带有泛型的Java F-Bound类型

时间:2014-08-22 05:57:51

标签: java generics functor bounded-wildcard

有没有办法在java中表达f-bound类型,在调用站点返回一般响应?

interface Functor<T extends Functor<T>>
  public <B> T<B> map(Function<A, B> fn); // won't compile because types don't match

如果类型永远不会改变,我可以使用f-bound类型,但在map的情况下,我需要一个新类型。有没有办法在java中表达这个?

即使我知道javac不支持更高级别的类型,我真正想要的是能够得到更高级别的东西。

假设我们有一个List<A>,并希望此界面返回List<B>。但是,不希望此界面知道有关List的任何信息。

1 个答案:

答案 0 :(得分:0)

阅读维基百科对仿函数的定义,听起来你想要定义一个能够从一个类别(Java类型)映射到另一个类别的泛型类型。在上面的示例中,要从List<A>映射到List<B>,其中AB类型是通用的。

如果这是您的目标,那么请考虑以下界面来定义Functor类型:

public interface Functor<CategoryA, CategoryB> {
    public CategoryB map(CategoryA instance);
}

这声明Functor类型处理两种通用参数类型CategoryACategoryB,并且不对这些参数类型施加约束。它还声明必须实现一个方法map,该方法从类型为CategoryA的对象映射到类型为CategoryB的对象。

假设,根据您的示例,您现在想要创建Functor的具体实例,该实例从List<Integer>映射到List<String>。您可以创建以下类:

public class IntegerListToStringList implements Functor<List<Integer>, List<String>> {
    @Override
    public List<String> map(List<Integer> integerList) {
        List<String> stringList = new ArrayList<>(integerList.size());
        for(Integer intValue : integerList) {
            stringList.add(Integer.toString(intValue));
        }
        return stringList;
    }
}

然后你可以像这样调用这个具体的Functor实现:

Functor<List<Integer>, List<String>> functor = new IntegerListToStringList();
Integer[] intArray = new Integer[] {2, 3, 5, 7, 11, 13};
List<Integer> intList = Arrays.asList(intArray);
List<String> stringList = functor.map(intList);
System.out.println("String list: " + stringList);

现在任何期望类型为Functor<List<Integer>, List<String>>的参数的方法都可以接受IntegerListToStringList类型的实例。