理解功能操作符:Lambda

时间:2014-08-14 10:37:24

标签: java string arraylist lambda

我有一个名为Semesters of Semester对象的arraylist

private ArrayList<Semester> Semesters

我编写了以下代码,使用列表中的对象(Semester)打印输出字符串(Semesters)

String report = year + "\n";
for (Semester s : Semesters) {
    report += s.toString() + "\n";
}

然后我在netbeans上得到了一个提示,其中上面的代码可以像这样写在一行:

String report = year + "\n";
report = Semesters.stream().map((s) -> s.toString() + "\n").reduce(report, String::concat);

我是一名中级java学生,我正在尝试理解这个功能,我觉得这个功能非常有用但不能完全了解它。

请帮助我理解这两段代码是如何相同的。

3 个答案:

答案 0 :(得分:2)

我还没有使用Java lambdas,但是通过函数式编程范例中的mapreduce\fold操作,这就是2个片段的等价方式:

  1. map基本上将特定函数应用于集合中的每个元素。在这种情况下,该函数/方法是s.toString() + "\n"。这与迭代集合并通过foreach循环将函数应用于每个元素相同。
  2. reduce是一个折叠操作,即它将地图操作返回的每个元素连接到原始字符串report
  3. 所以在原始代码中

    String report = year + "\n";
    for (Semester s : Semesters) {
        report += s.toString() + "\n";
    }
    

    您基本上对元素s进行操作,然后将该操作的结果连接到report。使用lambda,首先在map阶段对整个集合进行操作,然后遍历映射期间返回的集合,并将每个元素连接到report阶段的reduce

答案 1 :(得分:0)

  • semesters.stream()将为一次使用提供Stream<Semester>对象(有状态的迭代器)。
  • .map(...)被赋予一个函数接口:只有一个参数类型为Semester的方法的接口。
  • lambda exoression将生成一个生成接口的实例,其中包含一个带有Semester参数和String作为结果类型的方法。
  • 因此,地图会产生一个流
  • Map将稍后迭代Semester-s,应用方法并收集String。
  • Stream<String>.reduce(String startValue, stepFunction)将让操作(迭代)开始收集单个String,初始化为startValue,每一步:`result = result.concat(map method的返回值)。

我希望我能得到正确的解释。

System.out.println("Mapping Semester to String...");
Stream<String> sems = Semesters.stream().map((s) -> {
        System.out.println("map call " + s);
        return s + "\n";
    });
System.out.println("Reducing String stream to String...");
String report = sems.reduce(year + "\n", String::concat);

以上显示了渴望/懒惰的评价。也许看看Builder模式,了解幕后发生的事情。试试parallelfilter

String report = year + "\n"
    + semesters.stream()
        .filter(...)
        .sorted(...)
        .map(Semester::toString)
        .collect(Collectors.joining("\n"));

答案 2 :(得分:0)

以下是使用匿名类分解的等效功能:

Function<Semester, String> toStrFn = new Function<Semester, String>() {
  @Override
  public String apply(Semester semester) {
    return semester + "\n";
  }
};

BinaryOperator<String> reducer = new BinaryOperator<String>() {
  @Override
  public String apply(String lastResult, String currentValue) {
    return lastResult.concat(currentValue);
  }
};

String report = year + "\n";
Stream<Semester> semesterStream = Semesters.stream();
Stream<String> stringStream = semesterStream.map(toStrFn);
report = stringStream.reduce(report, reducer);