我在这里寻找一个更漂亮的解决方案.问题是组合泛型和Lambda表达式.

根据Java Language Specification,这不可能是我想要的方式.

所以我要问你的是:你有没有更优雅的方法来处理这个问题?有什么建议或惯例吗?

我的"List"类,我需要在很多函数中使用BiPredicate<T, T>:

package stackoverflow.genericlambdas;

import java.util.ArrayList;
import java.util.function.BiPredicate;

public class MyListImpl<T> {

    private final ArrayList<T> mItems = new ArrayList<>();


    public void addItem(final T pItem) {
        mItems.add(pItem);
    }

    // assume my library is full of such methods
    public int getFirstIndexOf(final BiPredicate<T, T> pIdentifier, final T pItem) {
        for (int i = 0; i < mItems.size(); i++) {
            final T t = mItems.get(i);
            if (pIdentifier.test(t, pItem)) return i;
        }
        return -1; // not found
    }

}

我的"Library"类,我想在其中存储模板BiPredicate<T, T>:

package stackoverflow.genericlambdas;

import java.util.Objects;
import java.util.function.BiPredicate;

public class Library {


    static public class CLUMSY_IDENTITY_CLASS<T> implements BiPredicate<T, T> {
        @Override public boolean test(final T p, final T q) {
            return p == q;
        }
    }
    static public class CLUMSY_EQUALITY_CLASS<T> implements BiPredicate<T, T> {
        @Override public boolean test(final T p, final T q) {
            return Objects.equals(p, q);
        }
    }


    static public final BiPredicate<T, T>   IDENTITY    = (p, q) -> p == q;                 // compilation error
    static public final BiPredicate<T, T>   EQUALITY    = (p, q) -> Objects.equals(p, q);   // compilation error


}

我的"Usage"类,我想在其中使用这些模板:

package stackoverflow.genericlambdas;

import java.util.Objects;

public class GenericLamdasUse {

    public static void main(final String[] args) {
        final MyListImpl<String> list = new MyListImpl<>();
        list.addItem("aa");
        list.addItem("bb");
        list.addItem("cc");

        final String testItem = "cc";
        final String testItem2 = "c" + (Math.random() < 2 /* always true */ ? "c" : ""); // this builds a new string that is not == the compile constant String "cc"

        final int whatIKnowWorks1 = list.getFirstIndexOf((p, q) -> Objects.equals(p, q), testItem);
        final int whatIKnowWorks2 = list.getFirstIndexOf((p, q) -> p == q, testItem);

        final int whatIKnowWorks3 = list.getFirstIndexOf(new Library.CLUMSY_IDENTITY_CLASS<>(), testItem); // dont't want the re-instantiation
        final int whatIKnowWorks4 = list.getFirstIndexOf(new Library.CLUMSY_EQUALITY_CLASS<>(), testItem); // for ever time i would need that

        final Library.CLUMSY_IDENTITY_CLASS<String> clumsy5 = new Library.CLUMSY_IDENTITY_CLASS<>(); // dont't want the re-instantiation
        final Library.CLUMSY_EQUALITY_CLASS<String> clumsy6 = new Library.CLUMSY_EQUALITY_CLASS<>();
        final int whatIKnowWorks5 = list.getFirstIndexOf(clumsy5, testItem); // for ever time i would need that
        final int whatIKnowWorks6 = list.getFirstIndexOf(clumsy6, testItem); // also, the types <String> have to match each time

        final int whatIWant1 = list.getFirstIndexOf(Library.EQUALITY, testItem); // I want this, but: compilation error
        final int whatIWant2 = list.getFirstIndexOf(Library.IDENTITY, testItem); // I want this, but: compilation error
    }

}

推荐答案

如果需要使用类型变量对BiPredicate进行参数化,则无法通过静态fields实现这一点,因为类型变量必须在作用域中定义.这类操作通常通过静态methods实现.

package stackoverflow.genericlambdas;

import java.util.Objects;
import java.util.function.BiPredicate;

public class Library {

    public static <T> BiPredicate<T, T> identity() {
        return (a, b) -> a == b;
    }

    public static <T> BiPredicate<T, T> equals()
        return Objects::equals;
    }
}

如果您不需要类型变量,请参见Sweeper's answer.

Java相关问答推荐

将偶数元素移动到数组的前面,同时保持相对顺序

替换com. sun. jndi. dns. DnsContextFactory Wildfly23 JDK 17

Spring Boot 3.2.2中的@Inject和@Resource Remove

当Volatile关键字真的是必要的时候?

如何对多个字段进行分组和排序?

Java SSLKeyManager出厂密码

是否为计划任务补偿系统睡眠?

如何在Spring Boot中创建可以将值传递给配置的&Enable&Quot;注释?

Regex以查找不包含捕获组的行

如何读取3个CSV文件并在控制台中按顺序显示?(Java)

如何配置空手道以使用FeignClient或RestTemplate代替ApacheHttpClient

当我在Java中有一个Synchronized块来递增int时,必须声明一个变量Volatile吗?

如何从命令行编译包中的所有类?

处理4.3问题:javax.xml.ind包不存在(&Q;).您可能在学习GitHub教程时遗漏了库.&Q

JavaFX,GridPane:在GridPane的列中生成元素将保持所有列的宽度

无法在IntStream上应用Collectors.groupingBy

字符串的Gzip压缩在java11和java17中给出了不同的结果

可以';不要在Intellij IDEA中使用最新的Java版本(JDK 21)

在JPanel上使用GridBagLayout并将JButton放在里面时出现问题

Java 8 中 ByteBuffer 和 BitSet 的奇怪行为