public class MyMapper extends Mapper<LongWritable, Text, Text, Text> { @Override protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, Text>.Context context) throws IOException, InterruptedException { // 拿到传入进来的一行内容,把数据类型转换为String 空2:_________________________________ // 将字符串按照" "分隔符切割,并保存到字符串数组中 空3:_________________________________ if(words.length==3) context.write(new Text(words[1]), new Text(words[0]+" "+words[2]+"_file1")); else // 如果键值对来之于file2,则添加后缀"_file2",然后再发送到处理流水线 context.write(new Text(words[0]), new Text(words[1]+"_file2")); } }
时间: 2024-04-28 14:23:34 浏览: 16
这段代码是一个 Mapper 类,用于处理输入数据并输出键值对。在这个 Mapper 类中,map() 方法被重写,接收一个 LongWritable 类型的 key 和一个 Text 类型的 value,以及一个 Mapper.Context 对象,用于输出键值对。具体来说,该 Mapper 类的输入键值对类型是 LongWritable 和 Text,输出键值对类型是 Text 和 Text。
空2处应该填写以下代码:String line = value.toString(); 这行代码将 Text 类型的 value 转换为 String 类型的 line。
空3处应该填写以下代码:String[] words = line.split(" "); 这行代码将字符串 line 按照空格分隔符切割,并将结果保存到字符串数组 words 中。然后根据数组 words 的长度判断键值对来自哪个文件,如果长度为 3,则表示键值对来自 file1 文件,需要将第二个单词作为键,第一个单词和第三个单词用空格拼接作为值,并在值的末尾添加 "_file1" 后输出;否则表示键值对来自 file2 文件,需要将第一个单词作为键,第二个单词在末尾添加 "_file2" 后作为值输出。
相关问题
为什么这串代码无法实现文件的去重: public static void main(String[] args) throws Exception{ System.setProperty("username","hadoop234"); Configuration conf = new Configuration(); conf.set("fs.default.name", "hdfs://localhost:9000"); FileSystem fs = FileSystem.get(conf); int len = args.length; if(fs.exists(new Path(args[len-1]))) { fs.delete(new Path(args[len-1]),true); } Job job = Job.getInstance(conf,"Merge and duolicate removal"); job.setJarByClass(quchong.class); job.setMapperClass(MyMapper.class); job.setReducerClass(MyReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(Text.class); for(int i=0;i<len-1;++i) { FileInputFormat.addInputPath(job, new Path(args[i])); } FileOutputFormat.setOutputPath(job, new Path(args[len-1])); System.exit(job.waitForCompletion(true) ? 0 : 1); fs.close(); }
这段代码中并没有实现去重,因为在 MapReduce 任务中实现去重通常需要借助 Map 和 Reduce 的聚合功能。而这段代码只是设置了一个 Map 和 Reduce 的类,但并没有在类中实现去重逻辑。
如果想要实现文件的去重,需要在 MyMapper 和 MyReducer 类中添加代码来实现。具体来说,MyMapper 类中需要实现将输入文件中的每一行数据作为 key,value 为 null 的键值对输出。然后在 MyReducer 类中,可以利用 MapReduce 框架自动将相同 key 的数据聚合在一起的特性,只输出一个 key,将 value 设置为 null,这样就实现了去重。
这里提供一个简单的伪代码实现:
```java
public class MyMapper extends Mapper<LongWritable, Text, Text, NullWritable> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
// 将每一行数据作为 key,value 为 null 的键值对输出
context.write(value, NullWritable.get());
}
}
public class MyReducer extends Reducer<Text, NullWritable, Text, NullWritable> {
@Override
protected void reduce(Text key, Iterable<NullWritable> values, Context context) throws IOException, InterruptedException {
// 直接将 key 输出,value 设置为 null,实现去重
context.write(key, NullWritable.get());
}
}
```
根据手机流量数据,编写 MapReduce 程序来统计出每个手机号码的一年总流量。
Mapper阶段:
输入:每行数据包括手机号码、日期、上行流量、下行流量,以制表符分隔。
输出:键为手机号码,值为一年内的总流量,以制表符分隔。
```
public class MyMapper extends Mapper<LongWritable, Text, Text, LongWritable> {
private Text phoneNum = new Text();
private LongWritable totalFlow = new LongWritable();
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String[] words = value.toString().split("\t");
String phoneNumStr = words[0];
long upFlow = Long.parseLong(words[2]);
long downFlow = Long.parseLong(words[3]);
phoneNum.set(phoneNumStr);
totalFlow.set(upFlow + downFlow);
context.write(phoneNum, totalFlow);
}
}
```
Reducer阶段:
输入:每个手机号码的流量总和,以键值对的形式传递。
输出:每个手机号码的一年总流量,以制表符分隔。
```
public class MyReducer extends Reducer<Text, LongWritable, Text, LongWritable> {
private LongWritable totalFlow = new LongWritable();
@Override
protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
long sum = 0;
for (LongWritable value : values) {
sum += value.get();
}
totalFlow.set(sum);
context.write(key, totalFlow);
}
}
```