我正在尝试创建一个将字符串值映射到函数的映射。这是我创建的界面(如在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与自身相当? (我现在可以处理解决方法,因为我会手动填写)
答案 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
提供的参数的子类。