首页 文章

如何排序 Map

提问于
浏览
1

我有一个Map排序如下:

Map<String, String> map = new HashMap();

它包含以下字符串键:

String key = "key1.key2.key3.key4"

它包含以下String值:

String value = "value1.value2"

其中键和值可能因点数从 key1/value1key1.key2.key3.key4.key5/value1.value2.value3.value4.value5 非均匀而变化

我需要根据键中存在的点数或根据调用方法类型键/值的值来比较它们:

sortMap(Map map, int byKey);

要么

sortMap(Map map, int byValue);

这些方法当然会返回一个有序的 Map .

任何帮助,将不胜感激 .

4 回答

  • 1

    对于初学者,您需要使用 SortedMap 的实例 . 如果 Map 没有't implement that interface, then it has an undefined/arbitrary iteration order and you can' t控制它 . (通常情况就是这样,因为 Map 是一种将值与键相关联的方式;排序是一个辅助问题 . )

    所以我'll assume you'重新使用TreeMap,这是规范的有序 Map 实现 . 这会根据您可以在构造函数中提供的Comparator对其键进行排序 . 因此,如果您可以编写这样的比较器来确定哪个是两个任意键的"lower"(扰码警报:您可以),这将很容易实现 .

    但是,这仅在按键排序时有效 . 我不知道有任何直截了当的方法来做到这一点 . 我能想到的最好的是编写一个对值进行排序的 Comparator<Map.Entry> ,调用 Map.getEntrySet 并将所有条目推送到列表中,然后在列表中调用 Collections.sort . 这是你最关心的问题 .

    (另请注意,如果您的密钥不是不可变的,您将遇到很多麻烦,因为在外部更改时不会使用它们 .

  • 0

    没有办法在 HashMap 上施加任何类型的订单 .

    如果你想通过键上的某些比较来命令元素,那么在键上使用TreeMapComparator,或者只使用它们的默认Comparable顺序 .

    如果你想按值排序,唯一真正的选择是使用 LinkedHashMap ,它保留条目放入 Map 的顺序,然后在将条目插入 Map 之前对条目进行排序,或者可能是某些非JDK Map 实施 . 有一些肮脏的黑客使得一个关键的比较器实际上秘密地比较了这些值,但这些很危险并经常导致不可预测的行为 .

  • 1

    您应该使用TreeMap并实现ValueComparator或创建实现Comparable的键和值对象 .

    这里必须重复......

    编辑:重复(仅命名一个)Sort a Map<Key, Value> by values (Java)

  • 4

    我是通过以下方式做到的:

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static Map sortMap(Map unsortedMap) {
    
        List list = new LinkedList(unsortedMap.entrySet());
        // sort list based on comparator
        Collections.sort(list, new Comparator() {
            public int compare(Object o1, Object o2) {
                String value1 = (String)((Map.Entry) (o1)).getValue();
                String value2 = (String)((Map.Entry) (o2)).getValue();
                // declare the count
                int count1 = findOccurances(value1, '.');
                int count2 = findOccurances(value2, '.');
                // Go to thru the comparing
                if(count1 > count2){
                    return -1;
                }
                if(count1 < count2){
                    return 1;
                }
                return 0;
            }
        });
    
        // put the sorted list into map again
        Map sortedMap = new LinkedHashMap();
        for (Iterator it = list.iterator(); it.hasNext();) {
            Map.Entry entry = (Map.Entry) it.next();
            sortedMap.put(entry.getKey(), entry.getValue());
        }
        return sortedMap;
    }
    

    使用以下辅助方法:

    private static int findOccurances(String s, char chr) {
        final char[] chars = s.toCharArray();
        int count = 0;
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] == chr) {
                count++;
            }
        }
        return count;
    }
    

    在这里,我可以在比较部分放置一些 switch ,并在asc / desc之间进行额外的 int 参数更改 .

    我可以通过 switch 另一个 int 参数值在值和键之间进行更改以获得我的答案 .

相关问题