匿名类没有参数

时间:2014-11-23 20:40:24

标签: java

我正在学习Apache Spark。鉴于使用下面的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行开始,它将一个匿名类FlatMapFunction作为参数传递给lines.flatMap()。那么String s意味着什么?它似乎没有传递创建的String s作为参数,那么FlatMapFunction<String,String>(){}类如何工作,因为没有传递特定的参数?

2 个答案:

答案 0 :(得分: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"

答案 1 :(得分:3)

你在这里所做的就是将FlatMapFunction作为参数传递给flatMap方法;你传递的FlatMapFunction会覆盖call(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>
}