我在这里有问题陈述
我需要在列表上进行迭代的操作找到第一个大于3的整数,甚至将其加倍并返回它。
这些是检查执行多少操作的一些方法
public static boolean isGreaterThan3(int number){
System.out.println("WhyFunctional.isGreaterThan3 " + number);
return number > 3;
}
public static boolean isEven(int number){
System.out.println("WhyFunctional.isEven " + number);
return number % 2 == 0;
}
public static int doubleIt(int number){
System.out.println("WhyFunctional.doubleIt " + number);
return number << 1;
}
与Java 8流我可以做到
List<Integer> integerList = Arrays.asList(1, 2, 3, 5, 4, 6, 7, 8, 9, 10);
integerList.stream()
.filter(WhyFunctional::isGreaterThan3)
.filter(WhyFunctional::isEven)
.map(WhyFunctional::doubleIt)
.findFirst();
输出是
WhyFunctional.isGreaterThan3 1
WhyFunctional.isGreaterThan3 2
WhyFunctional.isGreaterThan3 3
WhyFunctional.isGreaterThan3 5
WhyFunctional.isEven 5
WhyFunctional.isGreaterThan3 4
WhyFunctional.isEven 4
WhyFunctional.doubleIt 4
Optional[8]
因此总共进行了8次操作。
在命令式风格或java8之前,我可以像这样编码
for (Integer integer : integerList) {
if(isGreaterThan3(integer)){
if(isEven(integer)){
System.out.println(doubleIt(integer));
break;
}
}
}
输出是
WhyFunctional.isGreaterThan3 1
WhyFunctional.isGreaterThan3 2
WhyFunctional.isGreaterThan3 3
WhyFunctional.isGreaterThan3 5
WhyFunctional.isEven 5
WhyFunctional.isGreaterThan3 4
WhyFunctional.isEven 4
WhyFunctional.doubleIt 4
8
和操作是相同的。所以我的问题是,如果我使用的是传统的for循环流,那有什么区别?
最佳答案
Stream API引入了流的新概念,使您可以以新的方式解耦任务。例如,根据您的任务,您可能想做不同的事情,即双偶数大于3。在某些地方,您想找到第一个,在其他地方,您需要10个这样的数字,在第三位置,您想应用更多过滤。您可以封装查找此类数字的算法,如下所示:
static IntStream numbers() {
return IntStream.range(1, Integer.MAX_VALUE)
.filter(WhyFunctional::isGreaterThan3)
.filter(WhyFunctional::isEven)
.map(WhyFunctional::doubleIt);
}
这里是。您刚刚创建了一种算法来生成此类数字(而不生成它们),并且您不在乎如何使用它们。一个用户可能会致电:
int num = numbers().findFirst().get();
其他用户可能需要获取10个这样的数字:
int[] tenNumbers = numbers().limit(10).toArray();
第三个用户可能想找到第一个也可以被7整除的匹配数字:
int result = numbers().filter(n -> n % 7 == 0).findFirst().get();
以传统的命令式方式封装算法将更加困难。
通常,Stream API与性能无关(尽管并行流的运行速度可能比传统解决方案要快)。这与代码的表达能力有关。