2
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"

第一个组件首先排序,然后是第二个,然后是第三个。

4

2 回答 2

4

HashMaps 没有固有的顺序。

此类不保证地图的顺序;特别是,它不保证订单会随着时间的推移保持不变。

在迭代之前使用不同的数据结构,或者自己对键进行外部排序。无论哪种方式,您都需要编写一个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
}

注意 ,在任何类型的映射中使用可变键通常是一个坏主意。就个人而言,我从来没有需要——至少使用一个不可变的整数列表来代替。

于 2012-12-09T05:50:23.283 回答
0

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);

鲍勃是你的叔叔。

于 2012-12-09T05:56:49.313 回答