我希望Map
包含多个列表,每个列表由Comparable
个对象组成,但并不总是相同,因此可能会有List
个Doubles
和一个List
Strings
等等......
Map<String, List<Comparable<?>>>
不幸的是,上面定义的Map
没有用,因为无法比较每个List
中的元素。因此我不得不作弊并在课堂上引入一个类型参数:
class MyClass<T extends Comparable<? super T>> {
Map<String, List<T>> myMap;
}
这并不完全正确,因为并非所有列表都属于同一类型。但它有效,我唯一需要做的就是当我将T
添加到双打列表或Double
到字符串列表时,对String
进行类型转换。我确保每种类型只添加到正确类型的列表中。
有没有更好的方法来解决这个问题?
替代方法是为每种类型的Map
设置一个List
。但这只会使代码变得更加丑陋,而我对列表所做的唯一事情就是对它们进行排序并将它们作为String值插入到DB中,因此我只在可比较对象上调用toString
。
答案 0 :(得分:1)
您可以使用List<Object>
使其成为通用的此目的。
您可能希望对列表中的某些特定数据类型执行instance of
检查。
Map<String, List<Object>> map = new HashMap<>();
List<Object> list;
list = new ArrayList<>(Arrays.asList(new Object[] { 1, 2, 3.45, "dev", 'A', true, false }));
map.put("key1", list);
list = new ArrayList<>(Arrays.asList(new Object[] { false, 100, 5.1234f, "user", 'Z', true }));
map.put("key2", list);
for (Map.Entry<String, List<Object>> entry : map.entrySet()) {
System.out.println(entry.getKey() + " => " + entry.getValue());
}
输出:
key1 => [1, 2, 3.45, dev, A, true, false]
key2 => [false, 100, 5.1234, user, Z, true]
答案 1 :(得分:0)
来自docs of java generic wildcard它说:
在通用代码中,称为通配符的问号(?)表示未知类型。
还有:
通配符从不用作泛型方法调用,泛型类实例创建或超类型的类型参数。
因此,如果您有以下声明:
List<?> list = new ArrayList<>();
然后你不能向list
添加任何内容,因为你刚刚告诉编译器“我不知道将放入list
的对象类型”
所以你的代码List<Comparable<?>>
意味着“我希望列表包含可比较的对象,但我不知道它的类型”,这对于编译器来说是不行的,因为编译器确实需要知道类型信息为了它的工作。
要使用列表包含任何Comparable
个对象,您可以使用upper bounded wildcards之类的:
Map<String, List<? extends Comparable>> map = new HashMap<>();
然后您可以将任何comparable
列表作为此地图的值:
public static void main(String[] args) {
Map<String, List<? extends Comparable>> map = new HashMap<>();
List<Integer> as = new ArrayList<>();
as.add(1);
as.add(5);
as.add(3);
map.put("as", as);
List<String> bs = new ArrayList<>();
bs.add("hello");
bs.add("world");
bs.add("generics");
map.put("bs", bs);
}
最后我想你会对inheritance and subtypes in generics感兴趣,希望这对你有所帮助。
答案 2 :(得分:0)
这看起来有点像异构地图。除了比较它们之外,你实际上对你的可比对象列表做了什么?
但是,如果您希望列表具有不同的类型,则间接应该在List
附近。
public final class SortableList<T extends Comparable<? super T>> {
private final List<T> elements;
public SortableList(List<T> elements) {
this.elements = elements;
}
public List<T> elements() {
return elements;
}
}
...
Map<String,SortableList<?>> sortables;
...
Comparable<?> colaMax = Collections.max(sortables.get("shirley").elements());