创建具有泛型类型的地图

时间:2014-10-26 19:59:01

标签: java generics

我正在尝试创建一个将字符串值映射到函数的映射。这是我创建的界面(如在Java 8中,但我无法使用它):

interface Function<T, U> {
    U apply(T t);
}

现在,我创建了一个排序方法,根据一些属性对我的pojo进行排序:

public <U extends Comparable<U>> void sortPojoBy(Function<Pojo, U> f) {
        Collections.sort(list, new Comparator<Book> () {
            @Override
            public int compare(Pojo first, Pojo second) {
                return f.apply(first).compareTo(f.apply(second));
            }
        });
}

然后我可以调用它传递一个函数的匿名类来按我想要的属性排序,例如:

sortBooksBy(new Function<Pojo, Double>(){
                @Override
                public Double apply(Pojo p) {
                    return p.getPrice();
                }
            });

现在我制作地图时遇到了麻烦。理想情况下,我想要这样的事情:

Map<String, Function<Pojo, T extends Comparable<T>>> map = new HashMap<>();

我知道我不能做这样的事情,我目前的解决方法是创建一个带有原始函数的地图。

private Map<String, Function> map = new HashMap<>();
    {
        map.put("price", new Function<Pojo, Double>(){
            @Override
            public Double apply(Pojo t) {
                return t.getPrice();
            }           
        });
        map.put("name", new Function<Pojo, String>(){
            @Override
            public String apply(Pojo t) {
                return t.getTitle();
            }

        });
    }

我需要一张地图,因为我从JSON配置文件中获取了属性值(名称,价格等)。

所以我的问题是,有没有办法创建我的地图以确保函数的类型T与自身相当? (我现在可以处理解决方法,因为我会手动填写)

1 个答案:

答案 0 :(得分:4)

一种方法是更改​​它,以便所有函数首先确保返回可用的Comparable。换句话说,将Map中的参数移动到Function的参数。

interface Function<T, U extends Comparable<? super U>> {
    U apply(T t);
}

您的地图声明现在只是

Map<String, Function<Pojo, ?>> map = new HashMap<>();

您的通用方法sortPojoBy现在还执行U的通配符捕获。

public <U extends Comparable<? super U>> void sortPojoBy(Function<Pojo, U> f);

作为旁注,我略微改变了您的可比较声明。 T extends Comparable<? super T>是典型的形式。这是因为T是它为Comparable提供的参数的子类。