简体   繁体   English

如何通过Java的键对映射进行排序,但是如果键是(字符串+数字)的组合

[英]How to sort a Map in Java by its key but if the Key is combination of (String + numeric)

I have created a map called result. 我已经创建了一个名为result的地图。

In the sortByKeys method as my keys are String with Numeric values, I have converted them to Integer key type Map then sorted them. 在sortByKeys方法中,因为我的键是带有数字值的字符串,所以我将它们转换为Integer键类型Map,然后对其进行了排序。

Map<String, String> unsortMap = new TreeMap<String, String>();
unsortMap.put("room~1", "e");
unsortMap.put("room~2", "y");
unsortMap.put("room~10", "n");
unsortMap.put("room~4", "j");
unsortMap.put("room~5", "m");
unsortMap.put("room~3", "f");

Set set2 = unsortMap.entrySet();
Iterator iterator2 = set2.iterator();

while (iterator2.hasNext()) {
     /* Iterate */
    Map.Entry me2 = (Map.Entry) iterator2.next();
    String key = (String) me2.getKey();
    Object value = (Object) me2.getValue();
    System.out.println("Key ==>" + key + " Value ==>" + value);
}

# Current Output:#
/* current result */
Key ==>room~1 Value ==>e 
Key ==>room~10 Value ==>n
Key ==>room~2 Value ==>y
Key ==>room~3 Value ==>f
Key ==>room~4 Value ==>j
Key ==>room~5 Value ==>m

#Expected O/p:#
/* required result */
Key ==>room~1 Value ==>e
Key ==>room~2 Value ==>y
Key ==>room~3 Value ==>f
Key ==>room~4 Value ==>j
Key ==>room~5 Value ==>m
Key ==>room~10 Value ==>n 

Create a custom key object 创建一个自定义键对象

public class Key implements Comparable<Key>{
    String name;
    int id;

    public Key(String name, int id) {
        this.name = name;
        this.id = id;
    }

    @Override
    public int compareTo(Key o) {
        if(Objects.equals(name, o.name)){
            return Integer.compare(id, o.id);
        }else{
            return name.compareTo(o.name);
        }
    }

    @Override
    public String toString() {
        return name +"~"+ id;
    }

    @Override
    public boolean equals(Object o){
    ...
    @Override
    public int hashCode(){
    ...
}

and use it like this: 并像这样使用它:

    Map<Key, String> unsortMap = new TreeMap<>();
    unsortMap.put(new Key("room", 5), "e");

But if the String is always room you should use it in the key 但是,如果String始终是空格,则应在密钥中使用它

Without changing your code you can do like this.Need to write your own custom comparator.please always keep in mind that you can always create comparator login when you need sorting as per your own way 无需更改代码即可执行此操作。需要编写自己的自定义比较器。请始终牢记,当需要按自己的方式进行排序时,始终可以创建比较器登录名

Map<String, String> unsortMap = new TreeMap<String, String>(new Comparator<String>() {

            @Override
            public int compare(String o1, String o2) {
                // TODO Auto-generated method stub

                int j=Integer.parseInt(o1.substring(o1.indexOf("~")+1));
                int k=Integer.parseInt(o2.substring(o1.indexOf("~")+1));
                return j-k;
            }

        });

unsortMap.put("room~1", "e");
unsortMap.put("room~2", "y");
unsortMap.put("room~10", "n");
unsortMap.put("room~4", "j");
unsortMap.put("room~5", "m");
unsortMap.put("room~3", "f");

Set set2 = unsortMap.entrySet();
Iterator iterator2 = set2.iterator();

while (iterator2.hasNext()) {
     /* Iterate */
    Map.Entry me2 = (Map.Entry) iterator2.next();
    String key = (String) me2.getKey();
    Object value = (Object) me2.getValue();
    System.out.println("Key ==>" + key + " Value ==>" + value);
}

using stream and LinkedHashMap to maintain order 使用流和LinkedHashMap维护顺序

    Map<String, String> unsortMap = new TreeMap<String, String>();
    unsortMap.put("room~1", "e");
    unsortMap.put("room~2", "y");
    unsortMap.put("room~10", "n");
    unsortMap.put("room~4", "j");
    unsortMap.put("room~5", "m");
    unsortMap.put("room~3", "f");
    Comparator<String> c = (s1, s2) -> Integer.parseInt(s1.split("~")[1])   - Integer.parseInt(s2.split("~")[1]);
    Map<String, String> sortedMap = unsortMap.keySet()
            .stream()
            .sorted(c)
            .collect(Collectors.toMap(k -> k, k -> unsortMap.get(k), (k, v) -> v, LinkedHashMap::new));
    System.out.println(sortedMap);

Output 输出量

{room~1=e, room~2=y, room~3=f, room~4=j, room~5=m, room~10=n}

A more generic comparator for keys of type String that contains digits and letters: 包含数字和字母的String类型的键的比较通用的比较器:

Map<String, Double> result = new TreeMap<String, Double>(new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            String numericPart1 = o1.replaceAll("\\D+","");
            String numericPart2 = o2.replaceAll("\\D+","");
            String alphaPart1 = o1.replace(numericPart1, "");
            String alphaPart2 = o2.replace(numericPart2, "");

            if(alphaPart1.equals(alphaPart2)) {
                return Integer.compare(Integer.parseInt(numericPart1), Integer.parseInt(numericPart2));
            } else {
                return alphaPart1.compareTo(alphaPart2);
            }
        }
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM