“Lambdas”与“Generics”问题的优雅解决方案?

问题描述 投票:0回答:1

我正在寻找一个更漂亮的解决方案。问题在于将泛型和 Lambda 表达式结合起来。

根据 Java 语言规范 这不可能是我想要的方式。

所以我问你:你知道一种更优雅的方法来处理这个问题吗?有什么建议或常见做法吗?

我的“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
    }

}

我的“库”类,我想在其中存储模板

BiPredicate<T, T>
s:

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


}

我的“使用”类,我想在其中使用这些模板:

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
    }

}
java generics lambda anonymous-function anonymous-methods
1个回答
0
投票

您无法通过静态 fields 来执行此操作,因为

T
必须在范围内定义。像这样的事情通常是通过静态方法实现的。

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;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.