首先整上完整代码
package text10;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
public class maps extends Mapper<LongWritable, Text, Text, NullWritable> {
Text k = new Text();
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String rawvalue = Processdata(value.toString());
String band = getname(rawvalue, "phone_brand");
String size = getsize(rawvalue);
String color = getcolor(rawvalue);
String[] data = {band, size, color};
if (CheckData(data)) {
String output = getoutput(band, size, color);
k.set(output);
context.write(k, NullWritable.get());
}
}
private String getoutput(String band, String size, String color) {
return String.format("%S|%S|%S", band, size, color);
}
private boolean CheckData(String[] data) {
for (int i = 0; i < data.length; i++) {
if ("".contains(data[i])) {
return false;
}
}
return true;
}
private String getcolor(String rawvalue) {
String comments = getname(rawvalue, "comments");
String color = getname(rawvalue, comments);
String[] array = {"红", "黑", "白", "金", "蓝", "黄", "紫", "绿", "粉", "银", "灰", "青"};
int i = 0;
for (; i < array.length; i++) {
if (color.contains(array[i])) {
color = array[i];
break;
}
}
if (array.length == i) {
color = "其他";
}
return color;
}
private String getsize(String rawjson) {
String parameter = getname(rawjson, "parameter");
JSONArray array = JSONArray.parseArray(parameter);
String keyname = "主屏幕尺寸(英寸)";
for (int i = 0; i < array.size(); i++) {
String rawvalue = getname(array.get(i).toString(), keyname);
if ("" == rawvalue.trim()) {
continue;
} else {
return rawvalue;
}
}
return "";
}
private String getname(String rawvalue, String keyname) {
JSONObject object = JSONObject.parseObject(rawvalue);
if (object.containsKey(keyname)) {
return object.getString(keyname).trim();
} else {
return "";
}
}
private String Processdata(String value) {
String rawvalue = value;
rawvalue = rawvalue.replace("/", "-");
rawvalue = rawvalue.replaceAll("/r/t", "");
return rawvalue;
}
}
**
分为6个方法**简单阐述六个方法的主要功能
第一个Processdata 主要功能 替换字符串和删除空格符
第二个getname主要功能从所有字符中获取目标字符
第三个第四个getsize,getcolor和第二个一样 因为目标字符的不同所以逻辑也不同所以分开写,不然一个方法就够了
第五个CheckData 需要过滤的数组,这个功能是 我想过滤他就false 没过滤就true 具体再说
第六个getoutput 存储输出的东西 把想要的东西 都放里面规定格式 输出来 这个一般的json格式都一样
分别阐述每一个封装方法的主要逻辑
第一 在继承map类里
// 数据预处理
String rawValue = PreProcessData(value.toString());
由此引入第一个方法 ,经过第一个方法处理过后的数据就成了 rawvalue;
private String PreProcessData(String value) {
String retValue = value;
// 将|替换为-
retValue = value.toString().replace('|', '-');
// 将换行符删除 就是把换行符换成"" 空的
retValue = retValue.toString().replaceAll("\\r\\t", "");
return retValue;
}
将value值赋给rawvalue,经过替换等操作返回他就ok了;简单过 。
第二
// 解析JSON格式数据,从数据中获取需要的字段
提取手机品牌名称
String phoneBrand = getStringName(rawvalue, “phone_brand”);
private String getStringName(String rawvalue, String keyword) {
JSONObject object = JSONObject.parseObject(rawvalue);
if (object.containsKey(keyword)) {
return object.getString(keyword).trim();
} else {
return "";
}
}
获取手机品牌引入第二个方法;主要逻辑:将原字符串,目标字符串传进去
经过JSon格式处理原字符串 得到object对象,在进行和keyword的比较,如果object包含keyword就返回object.getString(keyword).trim(); 就是目标字符串并且去掉两端的空格,否则就返回空值,这个返回的空值一会还得处理它,不要慌不要乱,理清思路。
第三
// 提取手机屏幕尺寸
String phoneSize = GetPhoneSize(rawValue);
private String getsize(String rawjson) {
String parameter = getname(rawjson, "parameter");
JSONArray array = JSONArray.parseArray(parameter);
String keyname = "主屏幕尺寸(英寸)";
for (int i = 0; i < array.size(); i++) {
String rawvalue = getname(array.get(i).toString(), keyname);
if ("" == rawvalue.trim()) {
continue;
} else {
return rawvalue;
}
}
return "";
}
把源数据传进来 提示一下为啥 传入的是rawvalue 接受的是rawjson? 一样的 就跟你在家叫小名你在学校叫大名一样,你还是你
继续,调用getname方法 获得 parameter 并把它存到json格式下的数组中
然后定义一个keyname 其实也可以传进来,都一样
下面是一个循环 里面再调用getname方法 参数的源数据 是刚才保存的json数组遍历他拿出来 在和目标数据经过getname方法的处理后 返回的值付给rawvalue;
在进行一个判断 如果空值等于rawvalue去掉空格时,就跳出本次循环返回空值,否则就返回rwvalue;
这一个方法逻辑性比较强,仔细揣摩推敲
第四
// 提取用户购买手机颜色
String buyColor = GetPhoneColor(rawValue);
private String getcolor(String rawvalue) {
String comments = getname(rawvalue, "comments");
String color = getname(comments, "buy_color");
String[] array = {
"红", "黑", "白", "金", "蓝", "黄", "紫", "绿", "粉", "银", "灰", "青"};
int i = 0;
for (; i < array.length; i++) {
if (color.contains(array[i])) {
color = array[i];
break;
}
}
if (array.length == i) {
color = "其他";
}
return color;
}
同样也是吧源数据传进来,调用getname方法 目标为comments 返回的数据给comments;
再把comments当做源数据 目标数据 buy_color 返回的数据付给 color;
在创建一个颜色数组 遍历该数组 用color颜色比较数组里的每一个颜色,如果包含就把这个数组的这个值赋给color 然后结束本次循环 并返回color 如果遍历一遍后没有包含的颜色就进入判断这时 i一定等于数组的长度 所以color值就是其他 最后就返回 color
这个方法 逻辑性也比较强 仔细阅读也很好理解
第五
String[] data = {band, size, color};
if (CheckData(data)) {
String output = getoutput(band, size, color);
k.set(output);
context.write(k, NullWritable.get());
}
创建一个数组 用来储存刚才几个方法返回的东西;
在if语句里包含两个方法
第一个checkdata
private boolean CheckData(String[] data) {
for (int i = 0; i < data.length; i++) {
if ("".contains(data[i])) {
return false;
}
}
return true;
}
就是遍历刚才的那个新建立的数组,之前的方法不是有返回的空值的吗,这个方法就是 如果有空值就过滤掉
第二个就是json都有的output方法 这个一般是统一的
private String getoutput(String band, String size, String color) {
return String.format("%S|%S|%S", band, size, color);
}
就是返回字符的格式,最后k.set(output);然后就没有然后了
总结一下 思路比你用的方法重要,千万别混,个人描述可能有些不妥,欢迎指正!
来源:oschina
链接:https://my.oschina.net/u/4348352/blog/4740475