用Java 8 Streams取代传统的newForLoop [英] Replacing traditional newForLoop with Java 8 Streams
问题描述
我有什么是
final List< Function< ;?超级双人,双人>> myList = generateList();
,但只适用于foreach,流需要final变量。我尝试了一下
final double myVal = calculate(10);
private double double(double val){
for(Function< ;? double Double,Double> function:this.myList){
val + = function.apply(val) ;
}
return val;
$ b现在,我明白我可以用<$ for()DoubleStream
得到一个sum()
,但我需要重新 - 将当前总和应用于每个Function
并将该总和添加到下一个函数,如上面的代码示例所示。
<编辑:所以在使用reduce()
区域进行测试之后,我对执行这种类型的计算所花费的时间进行了简单的测试,结果不利于流。以下是 https://gist.github.com/gabizou/33f616c08bde5ab97e56 的示例。包括从相当基本的测试的日志输出。
解决方案您可以使用流API来编写列表中的函数的功能。
static List< Function< ;?超级双人,双人>> myList
= Arrays.asList(d - > d + 4,d - > d * 2,d - > d - 3);
static函数< Double,Double> (函数< Double,Double>)d - > d + f.apply(d))
.reduce(Function :: andThen ).orElse(Function.identity());
static double calculate(double val){
return total.apply(val);
public static void main(String [] args){
System.out.println(calculate(10));
$ b产生组合函数的流操作没有关联性问题,在理论上甚至可以并行运行(尽管这里没有任何好处),而结果是一个单独的函数,它本身是连续的,永远不会分解成需要关联的部分。
So, finally making a relatively large jump from Java 6 to Java 8, I've read up a fair amount of Java 8 Streams API. Unfortunately, almost all the examples that have been asked are almost close to what I'm trying to figure out how to do, but not close enough.
What I have is
final List<Function<? super Double, Double>> myList = generateList(); final double myVal = calculate(10); private double calculate(double val) { for (Function<? super Double, Double> function : this.myList) { val += function.apply(val); } return val; }
Now, I've come to understand I could do something similar with
.stream().forEach()
, but that only applies the foreach and streams require final variables. I've tried to explore a bit withDoubleStream
to get asum()
, but I'd need to re-apply the current sum to eachFunction
and add that sum to the next function, as the code example above shows.Is this possible with pure Stream API?
Edit: So after testing with the
reduce()
area, I ran a simple test on the time it takes to perform this type of calculation and the results aren't in favor of streams. Here's an example https://gist.github.com/gabizou/33f616c08bde5ab97e56. Included are the log outputs from the fairly basic test.解决方案You can use the stream API to compose a function out of your list of functions.
static List<Function<? super Double, Double>> myList = Arrays.asList(d -> d + 4, d -> d * 2, d -> d - 3); static Function<Double, Double> total=myList.stream() .map(f -> (Function<Double, Double>) d -> d + f.apply(d)) .reduce(Function::andThen).orElse(Function.identity()); static double calculate(double val) { return total.apply(val); } public static void main(String[] args) { System.out.println(calculate(10)); }
The stream operation which produces the composed function does not have the associativity problem and could in theory even run in parallel (though there is no benefit here) while the result is a single function which is per se sequential and never dissolved into parts which would need to be associative.
这篇关于用Java 8 Streams取代传统的newForLoop的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!