使用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
)