2014-11-23 100 views
0

我正在学习Apache Spark。鉴于下面的java使用java实现spark,我对它的一些细节感到困惑。匿名类没有参数

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,它通过一个匿名类FlatMapFunctionlines.flatMap()作为参数。那么String s是什么意思?看起来它没有通过创建的String s作为参数,那么FlatMapFunction<String,String>(){}类将如何工作,因为没有特定的参数传入?

+1

'字符串s'是'在call'方法的参数匿名课程。 – 2014-11-23 20:42:53

回答

3

您传递的匿名类实例正在重写call(String s)方法。无论接收到这个匿名类实例是什么想要在其执行过程中使用该方法:它将(以某种方式)构造字符串并将它们(直接或间接)传递给你传入的任何方法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

但根据我的问题代码,我没有看到任何调用该方法。这很奇怪,因为它是实现“字数统计”功能的完整示例。 – byteBiter 2014-11-23 21:00:29

+0

@Liquid这是因为它在'.flatMap()'的定义内,它将调用该方法。它是你没有显示的代码,通常不需要担心。 – 2014-11-23 21:04:29

3

你在这里所做的就是传递一个FlatMapFunction作为flatMap方法的参数;您通过FlatMapFunction取代呼叫(String s)将:

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 2014-11-23 21:02:14

+0

“预定义”是什么意思?如果你的意思是不变的话,比如在我的例子中,我不能肯定地说。实际的实现将使用事先确定使用的'some'值 - 这可能是从另一个集合,数据库等检索的文字或值。检索到的值可能来自任何地方。我建议你看看flatMap方法的实际实现。如果你无法确定代码的作用,只需提出另一个问题,在这里注释链接,我一定会检查它:) – univise 2014-11-23 23:08:06