使用Java-8中的函数ArrayList

问题描述:我希望能够使用从另一个类传入的函数的ArrayList(其中函数已在其他类中定义)。 如果在一个类中定义了可能具有不同输入和返回类型的函数列表,我希望能够将其中一些函数的ArrayList(可能有重复项)作为参数传递给其他类的构造函数或方法,使用它们执行操作。

代码说明:下面的代码是一个非常简化的示例,从设计的角度来看并不是很有意义。 问题的焦点是SomeClass的方法getResult()以及一旦拥有它们,通常如何使用函数的ArrayList。

尝试解决问题: getResult()方法实现是使用函数列表的许多尝试之一的示例。 再次,请不要介意代码的设计。 这样做就是为了尽量缩短问题范例。

简单的测试类

 package com.Testing; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.function.Function; public class Tester { public static void main(String[] args) { // Some functions Function increment = (Integer input) -> { return input + 1; }; Function decrement = (Integer input) -> { return input - 1; }; Function timesPi = (Double input) -> { return input * 3.14; }; // list of Functions List availableMathOperations = new ArrayList(); List selectedMathOperations = new ArrayList(); // populate master list availableMathOperations.add(increment); availableMathOperations.add(decrement); availableMathOperations.add(timesPi); // Populate random selection list // // generate random binary number Random randomGenerator = new Random(); int randomNumber = randomGenerator.nextInt(availableMathOperations.size() * 2); boolean[] bits = new boolean[availableMathOperations.size()]; for (int j = 0; j < availableMathOperations.size(); j++) { bits[availableMathOperations.size() - 1 - j] = (1 << j & randomNumber) != 0; } // add math operations to selectedMathOperations based on binary number for (int j = 0; j < bits.length; j++) { if (bits[j]){ selectedMathOperations.add(availableMathOperations.get(j)); } } SomeClass someClass = new SomeClass(selectedMathOperations, 1.23); } } 

其他课程

 package com.Testing; import java.util.List; import java.util.function.Function; public class SomeClass { List operations; double initialValue; public SomeClass(List newOperations, double newInitialValue){ operations = newOperations; initialValue = newInitialValue; } public double getResult(){ double result = 0.0; // problem method // perform the random list of operations using the initial value initially for(int i = 0; i < operations.size(); i++){ if(i == 0) result = operations.get(i)(initialValue); else result += operations.get(i)(result); } return result; } } 

apply java.util.function.Function对象的method 。 你需要像这样调用它:

 operations.get(i).apply(initialValue) 

但是,您使用原始Function ,因此结果可能是Object ,您需要将其转换为适当的类型。 此外,您不能使用+ (或+= )运算符。 我建议使用Number限制参数类型:

 List> operations = Arrays.asList( num -> num.intValue() + 1, num -> num.intValue() - 1, num -> num.doubleValue() * 3.14 ); // just an example list here public double getResult() { double result = 0.0; for (int i = 0; i < operations.size(); i++) { if (i == 0) { result = operations.get(i).apply(initialValue).doubleValue(); } else { result += operations.get(i).apply(result).doubleValue(); } } return result; } 

我不相信我理解正确,但我认为您面临的问题是如何调用List的function? Function接口的JavaDoc声明它有一个非抽象方法,您调用的apply()使用Function,如下所示:

 public double getResult(){ double result = 0.0; for(int i = 0; i < operations.size(); i++){ if(i == 0) result = operations.get(i).apply(initialValue); else result += operations.get(i).apply(result); } return result; } 

顺便说一句,这种方法可以稍微整理一下,以使其更简单:

 public double getResult() { double result = initialValue; //Not sure if this if-statement is a requirement, but it is to replicate //the functionality in the question if (operations.isEmpty()) { return 0.0; } for (Operation operation : operations) { result = operation.apply(result); } return result; } 

正如其他人在评论中所说,你应该在传递List对象时使用generics(我想你必须使用像List