我目前有3个带有数据的文本文件
Textfile1
你好世界
再见世界Textfile2
你好世界
你好第二个
如何获得
的结果Hello {Textfile1 = 1,Textfile2 = 2}
World {Textfile1 = 2,Textfile2 = 1}
目前我已设法将我的Map中的单词传递到我的Reduce java页面。这就是我现在被困住的地方。
public class Reduce extends Reducer<Text, Text, Text, Text> {
HashMap<Text, Integer>input = new HashMap<Text, Integer>();
public void reduce(Text key, Iterable<Text> values , Context context)
throws IOException, InterruptedException {
int sum = 0;
for(Text val: values){
String word = key.toString();
Text filename;
input.put(val,sum );
if(//not sure what to write here){
}
}
context.write(new Text(key), input);
}
我的映射器代码
public class Map extends Mapper<LongWritable, Text, Text, Text> {
private Text file = new Text();
private Text word = new Text();
private String pattern= "^[a-z][a-z0-9]*$";//any lower case letter or number
public void map(LongWritable key, Text value,Context context) throws IOException, InterruptedException {
InputSplit inputSplit = context.getInputSplit();
String fileName = ((FileSplit)inputSplit).getPath().getName();
file.set(fileName);
String line = value.toString();
StringTokenizer tokenizer = new StringTokenizer(line);
while (tokenizer.hasMoreTokens()) {
word.set(tokenizer.nextToken());
String stringWord = word.toString().toLowerCase();
if (stringWord.matches(pattern)){
context.write(new Text(stringWord), new Text(fileName));
}
}
}
}
希望我能得到一些帮助
答案 0 :(得分:1)
在mapper的输出中,我们可以将文本文件名设置为键,将文件中的每一行设置为值。
可以使用Mapper类中的以下代码片段检索文件名。
FileSplit fileSplit = (FileSplit)context.getInputSplit();
String filename = fileSplit.getPath().getName();
然后在减速器中
public class Reduce extends Reducer<Text, Text, Text, Text> {
HashMap<Text, Integer>input = new HashMap<Text, Integer>();
public void reduce(Text key, Iterable<Text> values , Context context)
throws IOException, InterruptedException {
int sum = 0;
for(Text val: values){
String word = val.toString(); -- processing each row
String[] wordarray = word.split(' ');
for(int i=0 ; i<wordarray.length; i++)
{
if(input.get(wordarray[i]) == null){
input.put(wordarray[i],1);}
else{
int value =input.get(wordarray[i]) +1 ;
input.put(wordarray[i],value);
}
}
context.write(new Text(key), new Text(input.toString()));
}
答案 1 :(得分:0)
您可以为地图密钥编写自定义可写类。类似textpair的文件名,文字和值将为1。
地图输出
<K,V> ==> <MytextpairWritable,new IntWritable(1)>
只需总结reducer端的值并发出值即可。这样的事情。
public class Reduce extends Reducer<mytextpairWritable, IntWritable,mytextpairWritable, IntWritable> {
public void reduce(mytextpairWritable key, Iterable<IntWritable> values , Context context)
throws IOException, InterruptedException {
int sum = 0;
for(IntWritable val: values){
sum+=val.get();
}
context.write(key, new IntWritable(sum));
}
这会给你类似的东西
File1,hello,2
File2,hello,3
File3,hello,1