问题描述:
我希望能够使用从另一个类传入的函数的ArrayList(其中该函数已在该另一个类中定义)。如果在一个类中定义了可能具有不同输入和返回类型的函数列表,我希望能够将其中一些函数的ArrayList以及可能的重复项作为参数传递给其他类的构造函数或方法,并且使用它们执行操作。
代码说明:
下面的代码是一个大大简化的示例,从设计的角度来看并没有多大意义。问题的焦点是该方法getResult()
中SomeClass
,一般如何,一旦你有他们使用功能的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<Integer, Integer> increment = (Integer input) -> {
return input + 1;
};
Function<Integer, Integer> decrement = (Integer input) -> {
return input - 1;
};
Function<Double, Double> timesPi = (Double input) -> {
return input * 3.14;
};
// list of Functions
List<Function> availableMathOperations = new ArrayList<>();
List<Function> 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<Function> operations;
double initialValue;
public SomeClass(List<Function> 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;
}
}
的method
一个的java.util.function.Function
目的是apply
。您需要这样称呼它:
operations.get(i).apply(initialValue)
但是,您使用raw
Function
,因此结果可能是,Object
并且您需要将其转换为适当的类型。同样,您不能将+
(或+=
)运算符与之配合使用。我建议通过以下方式限制参数类型Number
:
List<Function<Number, ? extends Number>> 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;
}
问题内容: 我想使用Java 8的新引入的函数对象将一些参数部分地应用于传统方法。 这是有问题的方法: 问题答案: 这实现了我想做的事情: 有关Java函数对象的所有预定义变体的列表,请在此处查看。 编辑: 如果您的方法带有很多参数,则可以编写自己的函数: 方法接受很多参数;您想提供其中一些: 这是使用自定义函数对象的方式:
问题内容: 我有一个重载的方法,该方法分别接受一个Consumer和一个Function对象,并返回与相应的Consumer / Function匹配的泛型类型。我以为这会很好,但是当我尝试使用lambda表达式调用任一方法时,我收到一条错误消息,指示对该方法的引用不明确。 基于我对JLS§15.12.2.1的阅读。确定潜在的适用方法:似乎编译器应该知道我的带空块的lambda与Consumer方
问题内容: 在什么情况下Java 8流中会调用“ reduce”的第三个参数? 下面的代码尝试遍历字符串列表,并将每个字符串的第一个字符的代码点值相加。最终的lambda返回的值似乎从未使用过,并且,如果您插入println,则似乎永远不会调用它。该文档将其描述为“组合器”,但我找不到更多详细信息… 问题答案: 您在说这个功能吗? 使用提供的标识,累积和组合功能,对此流的元素进行简化。这等效于:
我对 方法。 方法签名包括双消费者类型的参数。双消费者功能接口定义了一个函数方法accept(Object,Object)。据我所知,我现在可以使用任何与此函数接口一致的lambda表达式。 但是流中提到的示例。收集JavaDoc例如。 我不明白为什么ArrayList。add(E E)(单参数)与双消费者一致。accept(T T,U U)方法(两个参数),可以用作collect方法中的累加器函
我有一个重载方法,它分别接受一个使用者和一个函数对象,并返回一个与相应的使用者/函数匹配的泛型类型。我认为这很好,但是当我尝试用lambda表达式调用任何一个方法时,我得到一个错误,表明对该方法的引用是不明确的。 根据我对JLS§15.12的阅读。2.1. 确定可能适用的方法:编译器似乎应该知道,带有void块的lambda与Consumer方法匹配,带有返回类型的lambda与Function方
问题内容: 我知道如何创建对具有参数的方法的引用,并返回,它是: 但是,如果该函数引发异常,例如定义为: 如何定义此参考? 问题答案: 你需要执行以下操作之一。 如果是你的代码,请定义自己的函数接口,该接口声明已检查的异常: 并使用它: 否则,包装一个不声明检查异常的方法: 接着: 要么: