如何对Map Collection的Hierarchical键进行排序?

时间:2016-04-29 17:37:46

标签: java sorting dictionary collections

我在排序关键值列表(Map)时遇到问题。考虑按预期排序键将解决我的问题。

预期产出

Key         Value
1           animal
1.1         dog
1.1.1       tommy
1.1.2       Lily
1.1.10      Sadie
1.2         cat
1.3         camel
1.3.2       camel2
1.3.11      camel11

我尝试过TreeMap,但它会对每个字符编号进行排序。如果需要在String中对整数进行排序,那么将使用什么。我希望在预期的输出中提到类似的东西。

TreeMap<String, String> data = new TreeMap<String, String>();       
data.put("1",   "animal");
data.put("1.1", "dog");
data.put("1.2", "cat");     
data.put("1.3", "camel");

data.put("1.3.2", "camel2");
data.put("1.3.11", "camel11");

data.put("1.1.1", "tommy");
data.put("1.1.2", "Lily");
data.put("1.1.10", "Sadie");


SortedSet<String> keys = new TreeSet<String>(data.keySet());

System.out.println("Key         Value");

for(String key: keys){
    System.out.println(key+"        "+data.get(key));

实际输出

 Key        Value
1       animal
1.1         dog
1.1.1       tommy
1.1.10      Sadie
1.1.2       Lily
1.2         cat
1.3         camel
1.3.11      camel11
1.3.2       camel2

3 个答案:

答案 0 :(得分:4)

您可以编写一个自定义matplotlib's colormaps,按周期细分关键字符串,并将每个元素视为int

public class VersionStringComparator implements Comparator<String> {
    @Override
    public int compare(String s1, String s2) {
        String[] s1parts = s1.split("\\.");
        String[] s2parts = s2.split("\\.");
        int commonLength = Math.min(s1parts.length, s2parts.length);

        // Loop and compare corresponding parts
        for (int i = 0; i < commonLength; ++i) {
            int partCompare = 
                Integer.compare(Integer.parseInt(s1parts[i]),
                                Integer.parseInt(s2parts[i]));
            if (partCompare != 0) {
                return partCompare;
            }
        }

        // Out of parts - the shorter array should come first
        return Integer.compare(s1parts.length, s2parts.length);
    }
}

然后可以在Comparator

中使用此TreeMap
TreeMap<String, String> data = new TreeMap<>(new VersionStringComparator()); 

TreeSet

TreeSet<String> keys = new TreeSet<>(new VersionStringComparator()); 

请注意,此VersionStringComparator实现假定它仅适用于看起来像一系列由句点分隔的整数的字符串。如果你打算在那里有其他字符串,你应该添加一些输入验证。

答案 1 :(得分:3)

您可以使用以下代码获得预期的结果

import java.util.Arrays;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

public class MapSort implements Comparator<String> {

    @Override
    public int compare(String v1, String v2) {
        String[] a1 = v1.split("\\.");
        String[] a2 = v2.split("\\.");
        int min = 0;
        int max = 0;
        if (a1.length <= a2.length) {
            min = a1.length;
            max = a2.length;
        } else {
            min = a2.length;
            max = a1.length;
        }
        int[] first = new int[max];
        int[] second = new int[max];
        for (int i = 0; i < a1.length; i++) {
            first[i] = Integer.parseInt(a1[i]);
        }
        for (int i = 0; i < a2.length; i++) {
            second[i] = Integer.parseInt(a2[i]);
        }

        for (int i = 0; i < min; i++) {
            if (first[i] != second[i]) {
                return first[i] > second[i] ? 1 : -1;
            }
        }
        return 1;
    }

    public static void main(String[] args) {

        TreeMap<String, String> data = new TreeMap<String, String>();
        data.put("1", "animal");
        data.put("1.1", "dog");
        data.put("1.2", "cat");
        data.put("1.3", "camel");

        data.put("1.3.2", "camel2");
        data.put("1.3.11", "camel11");

        data.put("1.1.1", "tommy");
        data.put("1.1.2", "Lily");
        data.put("1.1.10", "Sadie");

        Set<String> myset = new TreeSet<>(new MapSort());
        myset.addAll(data.keySet());

        for (String key : myset) {
            System.out.println(key + ":" + data.get(key));
        }
    }

}

答案 2 :(得分:1)

我认为您希望将Comparator传递给TreeMap构造函数。类似的东西:

class MyNumComp implements Comparator<String>{

    @Override
    public int compare(String s1, String s2) {

        // safely cast Strings to some int-type structure and compare
        // return -1 if s1 < s2; return 0 if equal; else 1

    }
}