3

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?

Vignesh Vino
  • 1,242
  • 4
  • 25
  • 50

2 Answers2

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

}
Roland Illig
  • 40,703
  • 10
  • 88
  • 121
0

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; }
JNL
  • 4,683
  • 18
  • 29