2014-11-23 2 views
0

Я изучаю Apache Spark. Учитывая такую ​​реализацию искры с использованием java ниже, я смущен некоторыми деталями об этом.Анонимный класс не имеет аргумента

public class JavaWordCount { 
    public static void main(String[] args) throws Exception { 
    if (args.length < 2) { 
     System.err.println("Usage: JavaWordCount <master> <file>"); 
     System.exit(1); 
    } 

    JavaSparkContext ctx = new JavaSparkContext(args[0], "JavaWordCount", 
     System.getenv("SPARK_HOME"), System.getenv("SPARK_EXAMPLES_JAR")); 
    JavaRDD<String> lines = ctx.textFile(args[1], 1); 

    JavaRDD<String> words = lines.flatMap(new FlatMapFunction<String, String>() { 
     public Iterable<String> call(String s) { 
     return Arrays.asList(s.split(" ")); 
     } 
    }); 

    JavaPairRDD<String, Integer> ones = words.map(new PairFunction<String, String, Integer>() { 
     public Tuple2<String, Integer> call(String s) { 
     return new Tuple2<String, Integer>(s, 1); 
     } 
    }); 

    JavaPairRDD<String, Integer> counts = ones.reduceByKey(new Function2<Integer, Integer, Integer>() { 
     public Integer call(Integer i1, Integer i2) { 
     return i1 + i2; 
     } 
    }); 

    List<Tuple2<String, Integer>> output = counts.collect(); 
    for (Tuple2 tuple : output) { 
     System.out.println(tuple._1 + ": " + tuple._2); 
    } 
    System.exit(0); 
    } 
} 

Согласно моему пониманию, начинается в строке 12, он прошел анонимный класс FlatMapFunction в lines.flatMap() в качестве аргумента. Тогда что означает String s? Похоже, что он не передает созданный String s в качестве аргумента, тогда как будет работать класс FlatMapFunction<String,String>(){}, поскольку не передаются какие-либо конкретные аргументы?

+1

'Строка s' является аргументом для' метода call' в том, что анонимный класс. –

ответ

3

Экземпляр анонимного класса, который вы передаете, переопределяет метод call(String s). Все, что получает этот экземпляр анонимного класса, - это то, что хочет использовать этот метод call() во время его выполнения: оно будет (каким-то образом) конструировать строки и передать их (прямо или косвенно) в метод call() того, что вы прошли.

Так что факт, что вы, не вызывая метод, который вы определили, не вызывает беспокойства: что-то еще делает.

Это обычный прецедент для анонимных внутренних классов. Метод m() ожидает, что будет передано что-то, что реализует интерфейс Blah, а интерфейс Blah имеет метод frobnicate(String s). Таким образом, мы называем его

m(new Blah() { 
    public void frobnicate(String s) { 
     //exciting code goes here to do something with s 
    } 
}); 

и метод m теперь будет в состоянии принять этот экземпляр, который реализует Blah и вызывать frobnicate() на него.

Возможно m выглядит следующим образом:

public void m(Blah b) { 
    b.frobnicate("whatever"); 
} 

Теперь метод frobnicate(), что мы писали в нашем внутреннем классе быть вызван, и как она работает, параметр s будет установлен в "whatever".

+0

Но в соответствии с кодами в моем вопросе я не видел ничего, что вызывает этот метод. Это странно, потому что это полный пример, реализующий функцию слова count. – byteBiter

+0

@ Liquid это потому, что внутри определения '.flatMap()' он будет ссылаться на этот метод. Это код внутри, который вы не показывали, и обычно не нужно беспокоиться. –

3

Все, что вы здесь делаете, передает FlatMapFunction как аргумент метода flatMap; Ваш прошел FlatMapFunction переопределяет вызов (строка ы):

JavaRDD<String> words = lines.flatMap(new FlatMapFunction<String, String>() 
{ 
    public Iterable<String> call(String s) 
    { 
    return Arrays.asList(s.split(" ")); 
    } 
}); 

код реализации lines.flatMap может выглядеть следующим образом, например:

public JavaRDD<String> flatMap(FlatMapFunction<String, String> map) 
{ 
    String str = "some string"; 
    Iterable<String> it = map.call(str); 
    // do stuff with 'it' 
    // return a JavaRDD<String> 
} 
+0

Вы имеете в виду, что 'String', возможно, уже задан в классе? – byteBiter

+0

Что вы подразумеваете под «предопределенным»? Если вы имеете в виду постоянный литерал, например, в моем примере, я не могу сказать точно. Фактическая реализация будет использовать «определенное» значение, которое оно решило использовать заранее - это может быть буквальный или значение, полученное из другой коллекции, базы данных и т. Д. Полученное значение потенциально может произойти из любого места. Я предлагаю вам изучить фактическую реализацию метода flatMap. Если у вас возникли проблемы с определением того, что делает этот код, просто задайте другой вопрос, прокомментируйте ссылку здесь, и я обязательно также проверю его :) – univise