Ich muss den häufigsten Schlüssel finden, der von Mapper im Reducer ausgegeben wird. Mein Minderer arbeitet auf diese Weise fein:Den häufigsten Schlüssel in Reducer finden, Fehler: java.lang.ArrayIndexOutOfBoundsException: 1
public static class MyReducer extends Reducer<NullWritable, Text, NullWritable, Text> {
private Text result = new Text();
private TreeMap<Double, Text> k_closest_points= new TreeMap<Double, Text>();
public void reduce(NullWritable key, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
Configuration conf = context.getConfiguration();
int K = Integer.parseInt(conf.get("K"));
for (Text value : values) {
String v[] = value.toString().split("@"); //format of value from mapper: "[email protected]"
double distance = Double.parseDouble(v[1]);
k_closest_points.put(distance, new Text(value)); //finds the K smallest distances
if (k_closest_points.size() > K)
k_closest_points.remove(k_closest_points.lastKey());
}
for (Text t : k_closest_points.values()) //it perfectly emits the K smallest distances and keys
context.write(NullWritable.get(), t);
}
}
Es ist die K-Instanzen mit den kleinsten Abständen findet und schreibt in die Ausgabedatei. Aber ich muss den häufigsten Schlüssel in meiner TreeMap finden. Also versuche ich es wie folgt:
public static class MyReducer extends Reducer<NullWritable, Text, NullWritable, Text> {
private Text result = new Text();
private TreeMap<Double, Text> k_closest_points = new TreeMap<Double, Text>();
public void reduce(NullWritable key, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
Configuration conf = context.getConfiguration();
int K = Integer.parseInt(conf.get("K"));
for (Text value : values) {
String v[] = value.toString().split("@");
double distance = Double.parseDouble(v[1]);
k_closest_points.put(distance, new Text(value));
if (k_closest_points.size() > K)
k_closest_points.remove(k_closest_points.lastKey());
}
TreeMap<String, Integer> class_counts = new TreeMap<String, Integer>();
for (Text value : k_closest_points.values()) {
String[] tmp = value.toString().split("@");
if (class_counts.containsKey(tmp[0]))
class_counts.put(tmp[0], class_counts.get(tmp[0] + 1));
else
class_counts.put(tmp[0], 1);
}
context.write(NullWritable.get(), new Text(class_counts.lastKey()));
}
}
Dann bekomme ich diesen Fehler:
Error: java.lang.ArrayIndexOutOfBoundsException: 1
at KNN$MyReducer.reduce(KNN.java:108)
at KNN$MyReducer.reduce(KNN.java:98)
at org.apache.hadoop.mapreduce.Reducer.run(Reducer.java:171)
Können Sie mir bitte helfen dieses Problem beheben?
'Doppelabstand = Double.parseDouble (v [1]);' Dies ist, wo es passiert. Sind Sie sicher, dass im Wert ein "@" steht? – Tgsmith61591
Ja, ich bin mir ziemlich sicher. Die Ausgabe der ersten Version ist wie folgt: [email protected] Und auch der erste funktioniert ohne Probleme. –
Überprüfen Sie die Größe von 'v' und' tmp', um die Möglichkeiten einzuschränken. – Berger