Sorting Map using Comparator

旧时模样 提交于 2019-12-22 10:26:41

问题


I'm trying Comparator to implement a sort in TreeMap according to a sequence.

    final String sequence="People,Object,Environment,Message,Service";
Comparator<String> comparator = new Comparator<String>() {
             @Override
             public int compare(String key1, String key2) {
                 int returned = sequence.indexOf(key1) - sequence.indexOf(key2);

                 if (returned == 0 && !key1.contains(key2))
                     returned = -1;

                 return returned;

             }
         };
List<String> list=new ArrayList<String>();
          Map<String,String> lhm = new TreeMap<String,String>(comparator);
       // Put elements to the map
          lhm.put("Object", "biu");
          lhm.put("Message", "nuios");
          lhm.put("Service", "sdfe");
          lhm.put("People", "dfdfh");
          lhm.put("Environment", "qwe");
          lhm.put("Other", "names");
          lhm.put("Elements", "ioup");          
          lhm.put("Rand", "uiy");
for(Entry<String, String> entry : lhm.entrySet()) {
                System.out.println(entry.getKey());
            }

The Output which I'm getting here is

Rand
Elements
Other
People
Object
Environment
Message
Service

The Elements in treemap which equals the sequence are ordered correctly but other elements which are not following the sequence should come after the sequence.My expectation is like following

People
Object
Environment
Message
Service
Rand
Elements
Other

How to implement this?

Suppose If I add some more words to the elements of my TreeMap means my Comparator doesn't even order the elements.Like this

lhm.put("Object IOn", "biu");
          lhm.put("Message dfb", "nuios");
          lhm.put("Serviceabc", "sdfe");
          lhm.put("Peoplexxx", "dfdfh");
          lhm.put("Environmentxxx", "qwe");
          lhm.put("Other", "names");
          lhm.put("Elements", "ioup");          
          lhm.put("Rand", "uiy");

My Output become

Rand
Elements
Other
Environmentxxx
Peoplexxx
Serviceabc
Message dfb
Object IOn

Somebody help me to rewrite my Comparator to fix this problem?


回答1:


Here is some simple code that should to the task.

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;

public class FixedOrderComparator implements Comparator<String> {

  private final Map<String, Integer> index = new HashMap<>();

  public FixedOrderComparator(String elements) {
    String[] split = elements.split(",");
    for (int i = 0; i < split.length; i++) {
      index.put(split[i], i);
    }
  }

  @Override
  public int compare(String left, String right) {
    Integer rankLeft = index.get(left);
    Integer rankRight = index.get(right);
    if (rankLeft != null && rankRight != null) {
      return rankLeft.compareTo(rankRight);
    }
    if (rankLeft == null && rankRight == null) {
      return left.compareTo(right);
    }
    return Boolean.compare(rankLeft == null, rankRight == null);
  }

}



回答2:


You have to correct your logic used in the comparator.

  final String sequence="People,Object,Environment,Message,Service";
  System.out.println(sequence.indexOf("People"));  // 0
  System.out.println(sequence.indexOf("Object"));  // 7
  System.out.println(sequence.indexOf("Message"));  // 26
  System.out.println(sequence.indexOf("Environment")); // 14

.indexOf(key1) returns the index of the first character of the String and not the String.

 int returned = sequence.indexOf(key1) - sequence.indexOf(key2);
 if(returned < 0){ 
    // then it is sorted; 
    return 1;
 }
 else{ return -1; }


来源:https://stackoverflow.com/questions/18720800/sorting-map-using-comparator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!