以字母数字方式对HashMap进行排序的最快方法是什么(在一个int的数组上)?

时间:2012-12-09 05:48:42

标签: java

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"

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

2 个答案:

答案 0 :(得分:4)

HashMaps have no inherent ordering.

  

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

在迭代之前使用a different data structure或自己对键进行外部排序。无论哪种方式,您都需要撰写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
}
任何类型的

N.B。 it is generally a Bad Idea to use mutable keys in a map。就个人而言,我从来没有必要 - 至少使用an immutable list of integers

答案 1 :(得分: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);

鲍勃是你的叔叔。