HashMap<ArrayList<Integer>, String>
迭代这个结构,我得到:
[1 1 0], "gh"
[0 4 2], "gh"
[0 5 2], "qh"
但是,我想对键进行排序(按递增顺序),以获得
[0 4 2], "gh"
[0 5 2], "qh"
[1 1 0], "gh"
第一个组件首先排序,然后是第二个,然后是第三个。
HashMap<ArrayList<Integer>, String>
迭代这个结构,我得到:
[1 1 0], "gh"
[0 4 2], "gh"
[0 5 2], "qh"
但是,我想对键进行排序(按递增顺序),以获得
[0 4 2], "gh"
[0 5 2], "qh"
[1 1 0], "gh"
第一个组件首先排序,然后是第二个,然后是第三个。
此类不保证地图的顺序;特别是,它不保证订单会随着时间的推移保持不变。
在迭代之前使用不同的数据结构,或者自己对键进行外部排序。无论哪种方式,您都需要编写一个Comparator<List<Integer>>
因为List<E>
不扩展Comparable<List<E>>
List<List<Integer>> keys = new ArrayList<>(map.keySet());
Collections.sort(keys, new Comparator<List<Integer>>() {
@Override public int compare(List<Integer> a, List<Integer> b) {
// TODO handle edge cases, like lists of differing size
for (int i=0; i<Math.min(a.size(), b.size()); i++) {
int result = Integer.compare(a.get(i), b.get(i));
if (result != 0) {
return result;
}
}
return 0;
}
});
for (List<Integer> key : keys) {
String value = map.get(key);
// do something interesting with the value
}
注意 ,在任何类型的映射中使用可变键通常是一个坏主意。就个人而言,我从来没有需要——至少使用一个不可变的整数列表来代替。
TreeMap 可能对您有用。有几种方法可以处理这个问题。我个人不会使用 ArrayList 作为 Map 的索引。相反,我会从 ArrayList 中制作一个键,并将实际的 ArrayList 包含在值中。
在上述情况下, Map 的值将是这种类型:
class SomeClass() {
ArrayList<Integer> aList;
String aString; // gh and qh in your example.
public Integer getKey() {
// Do something here to create a suitable key from aList and return it.
}
}
(从结构上讲,这种类可能更多地是您想要的 - 如果 List 和 String 相关,您不希望它们分开,它们显然似乎是。)
现在您将创建 TreeMap 而不是 HashMap 并添加 SomeClass 实例:
TreeMap treeMap = new TreeMap();
SomeClass someClass = new SomeClass(...); // construct it somehow
treeMap.add(someClass.getKey(), someClass);
鲍勃是你的叔叔。