有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java根据一些规则对地图进行排序

我有一张地图,我想根据一些规则对其内容进行排序:

  1. Sort the map Alphabetically (From A to Z) according to its Values and not its Keys.
  2. Ignore the Case Sensitivity of the Values while sorting them.
  3. Put duplicate words into consideration(Words having exact letters Spelling & Case).
  4. Sort the Alpha numeric words right(Cbc2ee should appear before Cbc100ee).
  5. Handle non English words(área should appear in the words starting with "a" letter but actually it appears after words starting with "z" letter, considering á another letter).

我想我想要的都是合乎逻辑的。我能够完成第1点、第2点和第3点;3通过此代码:

public <K, V extends Comparable<? super V>> LinkedHashMap<K, V> sortMapByValues( Map<K, V> map ) {
    SortedSet<Map.Entry<K, V>> sortedEntries = new TreeSet<Map.Entry<K, V>>(
        new Comparator<Map.Entry<K, V>>() {
            @Override 
            public int compare( Map.Entry<K, V> e1, Map.Entry<K, V> e2 ) {
                String a = (String)e1.getValue();
                String b = (String)e2.getValue();

                int diff = a.compareToIgnoreCase( b );

                if (diff == 0) 
                    diff = a.compareTo(b);  

                return diff != 0 ? diff : 1;  // Special fix to preserve words with similar spelling.
            }
        }
    );

    sortedEntries.addAll( map.entrySet() );

    LinkedHashMap<K, V> sortedMap = new LinkedHashMap<K, V>();

    for( Map.Entry<K, V> sortedEntry : sortedEntries )
        sortedMap.put( sortedEntry.getKey(), sortedEntry.getValue() );

    return sortedMap;
}

第(4)点:我找到了它的脚本,但无法将其与代码合并: http://www.davekoelle.com/alphanum.html

第(5)点,我也找到了它的脚本,但我无法将其与我的代码合并: http://www.javapractices.com/topic/TopicAction.do?Id=207

因为这些点会影响比较(…)方法 有人能帮我吗


共 (1) 个答案

  1. # 1 楼答案

    有几点

    方法签名应为:

    public static <K, V> Map<K, V> sortMapByValues(Map<K, V> map)
    

    注: -删除与Comparable的绑定,因为您正在比较映射值的toString(),而不是值本身 -根据良好的设计指南,指定抽象类型Map<...>,而不是具体类型LinkedHashMap -static因为它不改变状态-它只是“代码”

    现在,你的解决方案很好。它只需要多一点代码就可以实现这些额外的点

    下面是一些代码,它们可以实现您想要的功能:

    public static <K, V> Map<K, V> sortMapByValues(Map<K, V> map) {
        SortedSet<Map.Entry<K, V>> sortedEntries = new TreeSet<Map.Entry<K, V>>(new Comparator<Map.Entry<K, V>>() {
            public int compare(Map.Entry<K, V> e1, Map.Entry<K, V> e2) {
                String aRaw = e1.getValue().toString();
                String bRaw = e2.getValue().toString();
                String a = standardize(aRaw);
                String b = standardize(bRaw);
    
                // Check for hex
                try
                {
                    Integer ai = Integer.parseInt(a, 16);
                    Integer bi = Integer.parseInt(b, 16);
                    int diff = ai.compareTo(bi);
                    if (diff != 0)
                        return diff;
                }
                catch (NumberFormatException ignore)
                {
                }
    
                int diff = a.compareTo(b);
                if (diff != 0)
                    return diff;
                return aRaw.compareTo(bRaw);
            }
    
            /** This method removes all accent (diacritic) marks and changes to lower case */
            String standardize(String input) {
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < input.length(); i++) {
                    char c = input.charAt(i);
                    sb.append(Normalizer.normalize(c + "", Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", ""));
                }
                return sb.toString().toLowerCase();
            }
        });
    
        // The rest is your code left as it was, cos it's fine
        sortedEntries.addAll(map.entrySet());
    
        LinkedHashMap<K, V> sortedMap = new LinkedHashMap<K, V>();
    
        for (Map.Entry<K, V> sortedEntry : sortedEntries)
            sortedMap.put(sortedEntry.getKey(), sortedEntry.getValue());
    
        return sortedMap;
    }
    

    以下是测试代码:

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("a", "CC96");
        map.put("b", "CC97");
        map.put("c", "CC102");
        map.put("d", "CC103");
        map.put("e", "aabbcc");
        map.put("f", "aabbCC");
        map.put("g", "atabends");
        map.put("h", "aaBBcc");
        map.put("i", "AABBcc");
        map.put("j", "aabbcc");
        map.put("k", "Cc102");
        map.put("l", "baldmöglichst");
        map.put("m", "bar");
        map.put("n", "barfuss");
        map.put("o", "barfuß");
        map.put("p", "spätabends");
        map.put("q", "ätabends");
        map.put("r", "azebra");
    
        System.out.println(sortMapByValues(map).toString()
            .replaceAll(", ", "\r").replaceAll("(\\{|\\})", ""));
    }
    

    输出:

    a=CC96
    b=CC97
    c=CC102
    k=Cc102
    d=CC103
    i=AABBcc
    h=aaBBcc
    f=aabbCC
    e=aabbcc
    g=atabends
    q=ätabends
    r=azebra
    l=baldmöglichst
    m=bar
    n=barfuss
    o=barfuß
    p=spätabends