java - 是否可以在方法定义中使用普通的 BiFunction

标签 java generics java-8 functional-interface

我遇到了以下问题:一个方法应该接受一个带有 2 个参数的双函数 - 一个是类型 Collection<T>另一个是T ;实际功能实际上可能是 Collection::removeCollection::add ,或更复杂的操作;实际函数用于十几个集合,函数中有多种类型的值和集合。

最初没有通用性 - 只有 Collection<String> s 和元素是 String所以将参数声明为 BiFunction<Collection<String>, String, Boolean>工作得很好:

List<String> idCodes;
void visitElement(Element e, 
                  BiFunction<Collection<String>, String, Boolean> elementOp) {
    elementOp.apply(idCodes, e.getIdCode());
}

但是后来我也添加了其他类型的集合,发现我再也找不到如何使用BiFunction了。一般而言:

List<String> idCodes;
List<Integer> weights;

void visitElement(Element e, 
                  BiFunction<...> elementOp) {
    elementOp.apply(idCodes, e.getIdCode());
    elementOp.apply(weights, e.getWeight());
}

但失败了——我可能只是在一个地方或另一个地方遇到编译错误,无论我使用什么类型参数都会失败。

我的一个尝试是

<T> void visitElement(Element e, 
                      BiFunction<Collection<T>, T, Boolean> elementOp) 

传入Collection::add时不会失败但实际将函数应用于 Collection<String> 时和 String ;或 Collection<Integer>int .

然后我又做了一个界面:

interface ElementOp {
    <T> boolean apply(Collection<T> collection, T item);
}

现在这完全符合我的要求,这并不奇怪。因此我的问题是:

我真的必须使用吗

interface ElementOp {
    <T> boolean apply(Collection<T> collection, T item);
}

void visitElement(Element e, 
                  ElementOp elementOp) {
    elementOp.apply(idCodes, e.getIdCode());
    elementOp.apply(weights, e.getWeight());
}

或者是否可以使用 BiFunction对于这种情况?

附言我正在使用 Eclipse 4.3 Mars Java 编译器,所以这可能只是因为那里有一些错误而无法工作。

最佳答案

您不能将 BiFunction 与处理这两种情况(TString)的 Integer 泛型一起使用。

这段代码无法编译:

<T> void visitElement(Element e,  
        BiFunction<Collection<T>, T, Boolean> elementOp) {  
   ...
   elementOp.apply(idCodes, e.getIdCode());
   elementOp.apply(weights, e.getWeight());
}

因为 BiFunction 是一个通用类,您使用 Collection<T>T 作为函数参数对其进行了参数化。
所以你在传递的时候只能传递 Collection<T>T 对象/变量 第一次调用中为 Collection<String>String,第二次调用中为 Collection<Integer>Integer

有了这个自定义界面,事情就不同了:

interface ElementOp {
    <T> boolean apply(Collection<T> collection, T item);
}

这个有效:

elementOp.apply(idCodes, e.getIdCode());
elementOp.apply(weights, e.getWeight());

BiFunction 相反,它可以接受用任何类声明的任何变量作为参数。
要保留的是 ElementOp 不是泛型类。
T 实际上只是一个方法范围泛型,它推断所传递参数的类型。


为了满足您的要求:多次调用相同的方法(Collection.add()Collection.remove())但使用不同类型的参数(StringInteger),您不想使用通用的 BiFunction<T,Collection<T>, Boolean>
您引入的自定义功能界面更适合。

关于java - 是否可以在方法定义中使用普通的 BiFunction,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46253132/

相关文章:

java - EAP 6.1 中的类加载问题 - JBoss 7.2/WAR 类看不到 EAR 类

java - 确定通用类型字段的类类型

java - 将元素从 Stream 添加到现有列表的更好方法是什么?

java - 如何将我给定的字符串转换为日期格式?

java - 有没有办法在 Java 8 中将 ZoneId 转换为 ZoneOffset?

java - 设置 sendBufferSize() 后 UDP 套接字的消息太长

java - hibernate 同表父/子关系

Java 8 流。除其他元素外的所有元素

generics - F# 泛型类型问题

java - Java 中的参数化良构和捕获转换