我正在尝试在Hadoop中创建SetWritable。这是我的实现。我刚刚开始使用MapReduce,但我不知道该怎么做。我写了下面的代码,但是没有用。
自定义可写(需要设置):
public class TextPair implements Writable {
private Text first;
public HashSet<String> valueSet = new HashSet<String>();
public TextPair() {
}
@Override
public void write(DataOutput out) throws IOException {
out.writeInt(valueSet.size());
Iterator<String> it = valueSet.iterator();
while (it.hasNext()) {
this.first = new Text(it.next());
first.write(out);
}
}
@Override
public void readFields(DataInput in) throws IOException {
Iterator<String> it = valueSet.iterator();
while (it.hasNext()) {
this.first = new Text(it.next());
first.readFields(in);
}
}
}
映射器代码:
public class TokenizerMapper extends Mapper<Object, Text, Text, TextPair> {
ArrayList<String> al = new ArrayList<String>();
TextPair tp = new TextPair();
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
String [] val = value.toString().substring(2,value.toString().length()).split(" ");
for(String v: val) {
tp.valueSet.add(v);
}
String [] vals = value.toString().split(" ");
for(int i=0; i<vals.length-1; i++) {
setKey(vals[0],vals[i+1]);
System.out.println(getKey());
context.write(new Text(getKey()), tp);
}
}
public void setKey(String first,String second) {
al.clear();
al.add(first);
al.add(second);
java.util.Collections.sort(al);
}
public String getKey() {
String tp = al.get(0)+al.get(1);
return tp;
}
}
我基本上是想从Mapper发出SetWritable作为值。请提出我需要进行哪些更改。谢谢!
最佳答案
我会说您在阅读和写作方面遇到问题。您需要知道Set的大小,然后使用它读取正确数量的Text对象。
我将您的版本更改为“文本对象集”,因为它们可以轻松读写。
public class TextWritable implements Writable {
private Set<Text> values;
public TextPair() {
values = new HashSet<Text>();
}
@Override
public void write(DataOutput out) throws IOException {
// Write out the size of the Set
out.writeInt(valueSet.size());
// Write out each Text object
for(Text t : values) {
t.write(out);
}
}
@Override
public void readFields(DataInput in) throws IOException {
// Make sure we have a HashSet to fill up
values = new HashSet<Text>();
// Get the number of elements in the set
int size = in.readInt();
// Read the correct number of Text objects
for(int i=0; i<size; i++) {
Text t = new Text();
t.readFields(in);
values.add(t);
}
}
}
您应该为此添加一些帮助程序类,以便将元素添加到Set中。
我也看不到在
clear
方法中对Set进行map
的位置。如果您不清除它,则每次调用map方法时,它可能会越来越大。请参阅Hadoop ArrayWritable以获取参考。