3

I've a SortedMap which have items like:

  • 1=abc
  • 2=xyz
  • 3=abc

Values can be duplicate.

I want to display the value-set on screen in the sorted manner. i.e.

myListMap

  • abc
  • abc
  • xyz

To sort the Map, I'm using comparator:

public class SortMapByValueComparator implements Comparator<String> {

    Map<String, String> mInputMap;

    /**
     * Constructor.
     * 
     * @param inputMap
     */
    public SortMapByValueComparator(Map<String, String> inputMap) {
        mInputMap = inputMap;
    }

    @Override
    public int compare(String lhs, String rhs) {
        String string1 = mInputMap.get(lhs);
        String string2 = mInputMap.get(rhs);
        return string1.compareToIgnoreCase(string2);
    }

}

And then passing the Map to this comparator like:

SortMapByValueComparator sortMapByValueComparator = new SortMapByValueComparator(myListMap);
SortedMap<String, String> sortedMapByValue = new TreeMap<String, String>(sortMapByValueComparator);
sortedMapByValue.putAll(myListMap);

Now, issue is when I call SortMapByValueComparator, it removes duplicate values. How can I avoid it?

PS - I want to use Map only.

reiley
  • 3,759
  • 12
  • 58
  • 114
  • "Values can be duplicate." and "I want to display the value-set on screen in the sorted manner" are contradictory statements. – TheLostMind Jun 13 '14 at 10:33
  • @TheLostMind for same values, I'm not concerned which abc is coming first, as long as both are displayed – reiley Jun 13 '14 at 10:37

2 Answers2

4

The problem is that compareToIgnoreCase() is returning 0 when two strings are equal, and returning zero is merging the keys as it is explained here. Implement your compare in a way that zero is not returned, it should work fine.

if(string1.compareToIgnoreCase(string2) >= 0)
    return 1;
else 
    return -1;
Community
  • 1
  • 1
anvarik
  • 6,417
  • 5
  • 39
  • 53
1

I would change the whole approach and go with something simpler:

// initializing your Map
// not sure if key set is Integer or String but it doesn't really matter here
Map<Integer, String> tm = new TreeMap<Integer, String>();
tm.put(1, "abc");
tm.put(2, "xyz");
tm.put(3, "abc");
// getting the values as List (not Set, so duplicates allowed)
List<String>values = new ArrayList<String>(tm.values());
System.out.printf("Unsorted values: %s%n", values);
// sorting the values with natural (lexicographic) order...
Collections.sort(values);
System.out.printf("Sorted values: %s%n", values);

Output

Unsorted values: [abc, xyz, abc]
Sorted values: [abc, abc, xyz]
Mena
  • 47,782
  • 11
  • 87
  • 106
  • Umm..you are right, but, I also want to retain the ids(keys) with respective values – reiley Jun 13 '14 at 10:36
  • 1
    @reiley so you want to [sort your Map by values](http://stackoverflow.com/questions/109383/how-to-sort-a-mapkey-value-on-the-values-in-java)? – Mena Jun 13 '14 at 10:38
  • In order to retain the key-value relationship, you can simply sort the `entrySet` of the map by the values of the `Entry`, as shown in this answer: http://stackoverflow.com/a/2581754 – Marco13 Jun 13 '14 at 10:48
  • thanks, but both my key & value are string, so how I'm gonna compare String's. Because, I've already tried compareTo above. – reiley Jun 13 '14 at 10:51