WordMean
A feladathoz kapcsolódó kódok megtalálhatók a GitHub repoban.
Adjuk meg, hogy a bemeneti fájlban mekkora a szavak átlagos hossza!
A keressett adat meghatározásához két adatra van szükségünk, a karakterek számára és a szavak számárá.
A feladat bemenete egy fájl, a Mapper
alapértelmezett bemeneti típusaihoz nem kell hozzányúlnunk. Mivel a kimenetben
egyetlen aggregált értéket akarunk, ezért fontos, hogy minden kulcs-érték pár egy Reducer-hez kerüljön. Mivel az alap
hash alapú shuffle algoritmust használjuk, ezért csak azt kell elérnünk, hogy a Mapper
által kiadott párok kulcsai
ugyan azok legyenek.
Ehhez kulcsként, a NullWritable
osztályt fogjuk használni:
public class WordMeanMapper extends Mapper<LongWritable, Text, NullWritable, IntWritable> {
public void map(LongWritable ikey, Text ivalue, Context context) throws IOException, InterruptedException {
for (String word : ivalue.toString().replaceAll("[,.?!:]", " ").split(" ")) {
// NullWritable singleton, ezért az, hogy nem mentjük ki változóba, nem ront a teljesítményen
context.write(NullWritable.get(), new IntWritable(word.length()));
}
}
}
Ennek hatására a Reducer
pontosan szavak száma darab párt fog kapni, ahol az érték az adott szó hossza.
public class WordMeanReducer extends Reducer<NullWritable, IntWritable, NullWritable, DoubleWritable> {
// figyeljünk a reduce típusszignatúrájára, _key típusának meg kell egyeznie az osztály első típusapraméterével
// az iterable típusparaméterének pedig az osztály második típusparaméterével
public void reduce(NullWritable _key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int wordCount = 0;
int wordLengthSum = 0;
for (IntWritable entryValue : values) {
wordCount++;
wordLengthSum += entryValue.get();
}
context.write(NullWritable.get(), new DoubleWritable((double) wordLengthSum / wordCount));
}
}