Java通用高级用法

Java通用高级用法,java,generics,java-8,generic-programming,Java,Generics,Java 8,Generic Programming,问题是,如果泛型签名由多个签名组成,则以下代码无法编译?都是同一类型的 import java.util.Map; import java.util.HashMap; import java.util.function.Function; public class Test { private static <T> T findSelfReference(Map<T, T> map) { for (Map.Entry<T, T> e

问题是,如果泛型签名由多个签名组成,则以下代码无法编译?都是同一类型的

import java.util.Map;
import java.util.HashMap;
import java.util.function.Function;

public class Test {

    private static <T> T findSelfReference(Map<T, T> map) {
        for (Map.Entry<T, T> entry : map.entrySet()) {
            if (entry.getKey() == entry.getValue()) {
                return entry.getKey();
            }
        }
        return null;
    }

    private static <T> T findSelfReference2(Map<T, T> map) {
        for (T key : map.keySet()) {
            if (map.get(key) == key) {
                return key;
            }
        }
        return null;
    }

    // Question: How to write the method signature that can ensure compile-time type safety? Both the signatures fail to compile.

    // private static <T> String fun(Function<Map<T, T>, T> finder) {
    private static String fun(Function<Map<?, ?>, ?> finder) {
        Map<Integer, Integer> map1 = new HashMap<>();
        // some processing to map1
        Integer n = finder.apply(map1);  // usage here, compile-time type checking wanted

        Map<String, String> map2 = new HashMap<>();
        // other processing to map2 depending on n
        return finder.apply(finder, map2);  // another usage
    }

    public static void main(String[] args) {
        // Please don't change into helper class...
        System.out.println(fun(Test::findSelfReference));
        System.out.println(fun(Test::findSelfReference2));
    }
}
有趣的是,在每次调用finder.apply时,类型T是固定的。但在不同的通话中,他们使用不同的类型。我尝试了通配符捕获ref:但是没有运气

我不想将结果强制转换到必须在运行时进行检查的对象中。所有类型检查都应该在编译时完成


如果不在helper类上创建n是内联函数数的函数,是否可能?

您的方法到底想实现什么

您可以使用通配符或类型参数T向其传递函数,然后希望将其应用于两种不同的具体类型Integer和String

这是行不通的:

Map<Integer, Integer> map1 = new HashMap<>();
// ...
Integer n = finder.apply(map1);

你到底想用你的方法实现什么

您可以使用通配符或类型参数T向其传递函数,然后希望将其应用于两种不同的具体类型Integer和String

这是行不通的:

Map<Integer, Integer> map1 = new HashMap<>();
// ...
Integer n = finder.apply(map1);

你可以这样做:

private static <T> T fun(Function<Map<T, T>, T> finder, Map<T, T> map) {
    return finder.apply(map);
}

private static Map<String, String> getStringMap(Integer n) {
    String a = String.valueOf(n + 1);
    Map<String, String> map2 = new HashMap<>();
    map2.put("1", "2");
    map2.put("3", "4");
    map2.put("5", "7");
    map2.put("3", a);
    return map2;
}

private static Map<Integer, Integer> getIntMap() {
    Map<Integer, Integer> map1 = new HashMap<>();
    map1.put(1, 2);
    map1.put(3, 4);
    map1.put(5, 7);
    map1.put(2, 2);
    map1.put(8, 8);
    return map1;
}

public static void main(String[] args) {
    fun(Test::findSelfReference, getIntMap());
    fun(Test::findSelfReference, getStringMap(1));
}

你可以这样做:

private static <T> T fun(Function<Map<T, T>, T> finder, Map<T, T> map) {
    return finder.apply(map);
}

private static Map<String, String> getStringMap(Integer n) {
    String a = String.valueOf(n + 1);
    Map<String, String> map2 = new HashMap<>();
    map2.put("1", "2");
    map2.put("3", "4");
    map2.put("5", "7");
    map2.put("3", a);
    return map2;
}

private static Map<Integer, Integer> getIntMap() {
    Map<Integer, Integer> map1 = new HashMap<>();
    map1.put(1, 2);
    map1.put(3, 4);
    map1.put(5, 7);
    map1.put(2, 2);
    map1.put(8, 8);
    return map1;
}

public static void main(String[] args) {
    fun(Test::findSelfReference, getIntMap());
    fun(Test::findSelfReference, getStringMap(1));
}

问题是您希望查找器的apply方法是泛型的

解决方案是使用通用方法定义自己的功能接口

@FunctionalInterface
interface Finder {
    <T> T apply(Map<T, T> map);
}

private static String fun(Finder finder) {
    // same body
}

如果这算是一个助手类,那么我不知道该告诉你什么。你想把一个方形的钉子敲入一个圆孔。Functionapply不是泛型方法,因此无法使用Function实现这一点。

问题在于您希望查找器的apply方法是泛型的

解决方案是使用通用方法定义自己的功能接口

@FunctionalInterface
interface Finder {
    <T> T apply(Map<T, T> map);
}

private static String fun(Finder finder) {
    // same body
}
如果这算是一个助手类,那么我不知道该告诉你什么。你想把一个方形的钉子敲入一个圆孔。Functionapply不是泛型方法,所以不能使用Function来实现这一点