1

I have created a map called 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.

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 
  • As of now I have not used any sort logic I checked few examples, it is said the key much be an Integer to sort ...is thr a way to do it ? –  Sep 01 '16 at 11:55
  • @kalpna try to use my below solution it might help you without changing the code – Jekin Kalariya Sep 01 '16 at 12:06
  • Possible duplicate of [how to sort Map values by key in Java](http://stackoverflow.com/questions/922528/how-to-sort-map-values-by-key-in-java) – Markus Mitterauer Sep 01 '16 at 12:38
  • Possible duplicate of [Using comparator for several characteristics in java](http://stackoverflow.com/questions/39096150/using-comparator-for-several-characteristics-in-java). That question and its answer are about sorting strings that may or not contain numbers, and sorting them numerically if they do. – Ole V.V. Sep 03 '16 at 08:25

4 Answers4

4

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

Liviu Stirb
  • 5,876
  • 3
  • 35
  • 40
4

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);
}
Jekin Kalariya
  • 3,475
  • 2
  • 20
  • 32
  • The constructor TreeMap(new Comparator(){}) is undefined – Poornima Sep 01 '16 at 12:06
  • @poori No java has constructor for tree map to pass your custom comparator also, if you are not clear try to past my code in your editor and check – Jekin Kalariya Sep 01 '16 at 12:08
  • From there only i pasted this error..Can you check again – Poornima Sep 01 '16 at 12:10
  • I think you are not implement overloaded method compare try to past exact code it will 100% work, dont modified yourself – Jekin Kalariya Sep 01 '16 at 12:14
  • 1
    Even though in this case there can’t be duplicates, I still think you should take into account the case where `j == k`. You can even simplify and just do `return j - k;` or return `Integer.compare(j, k);`. – Ole V.V. Sep 01 '16 at 12:17
  • Thanks Ole for suggestion , I forgot that simple way :) – Jekin Kalariya Sep 01 '16 at 12:19
  • thanks for the suggestions but if my map has combinaions of some thing link this ? unsortMap.put("roomss", "e"); 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("room3", "f") –  Sep 01 '16 at 12:55
  • @Kalpana Ramanan You need to define types of keys [ I can see 3 types roomss, room~1, room3 ] in the compare method of the Comparator you need to check what is the type of String o1 and String o2. then extract the number as per the type. this will result in two integers say intValue1 and intValue2 for which you can simply return Integer.compare(intValue1,intValue2). – nits.kk Sep 03 '16 at 06:36
0

using stream and LinkedHashMap to maintain order

    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}
Saravana
  • 12,647
  • 2
  • 39
  • 57
  • Thanks saravana!!! but still it is Throwing error such as Lamda expressions are not allowed, use source above 8 or higher ? what should I do ? –  Sep 02 '16 at 04:40
  • you can use lambda if you're using java 1.8+ – Saravana Sep 02 '16 at 04:58
0

A more generic comparator for keys of type String that contains digits and letters:

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);
            }
        }
    });