我有一个名为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学生,我正在尝试理解这个功能,我觉得这个功能非常有用但不能完全了解它。
请帮助我理解这两段代码是如何相同的。
答案 0 :(得分:2)
我还没有使用Java lambdas,但是通过函数式编程范例中的map
和reduce\fold
操作,这就是2个片段的等价方式:
map
基本上将特定函数应用于集合中的每个元素。在这种情况下,该函数/方法是s.toString() + "\n"
。这与迭代集合并通过foreach循环将函数应用于每个元素相同。reduce
是一个折叠操作,即它将地图操作返回的每个元素连接到原始字符串report
。所以在原始代码中
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的方法的接口。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模式,了解幕后发生的事情。试试parallel
和filter
。
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);