Die Antwort, für die am meisten gestimmt wurde, funktioniert nicht, wenn Sie 2 gleichwertige Gegenstände haben. die TreeMap lässt gleiche Werte aus.
das Beispiel: unsortierte Karte
key/value: D/67.3
key/value: A/99.5
key/value: B/67.4
key/value: C/67.5
key/value: E/99.5
Ergebnisse
key/value: A/99.5
key/value: C/67.5
key/value: B/67.4
key/value: D/67.3
So lässt E!!
Bei mir hat es gut funktioniert, den Komparator so einzustellen, dass er bei Gleichheit nicht 0, sondern -1 zurückgibt.
in diesem Beispiel:
class ValueComparator implements Comparator {
Karte Basis; public ValueComparator(Map base) { this.base = base; }
public int compare(Object a, Object b) {
if((Double)base.get(a) < (Double)base.get(b)) {
return 1;
} else if((Double)base.get(a) == (Double)base.get(b)) {
return -1;
} else {
return -1;
}
} }
jetzt kehrt sie zurück:
unsortierte Karte:
key/value: D/67.3
key/value: A/99.5
key/value: B/67.4
key/value: C/67.5
key/value: E/99.5
Ergebnisse:
key/value: A/99.5
key/value: E/99.5
key/value: C/67.5
key/value: B/67.4
key/value: D/67.3
als Antwort auf Aliens (2011 nov. 22): Ich bin mit dieser Lösung für eine Karte von Integer Id's und Namen, aber die Idee ist die gleiche, so könnte der Code oben nicht korrekt ist (ich werde es in einem Test zu schreiben und geben Sie den richtigen Code), dies ist der Code für eine Karte Sortierung, basierend auf der Lösung oben:
package nl.iamit.util;
import java.util.Comparator;
import java.util.Map;
public class Comparators {
public static class MapIntegerStringComparator implements Comparator {
Map<Integer, String> base;
public MapIntegerStringComparator(Map<Integer, String> base) {
this.base = base;
}
public int compare(Object a, Object b) {
int compare = ((String) base.get(a))
.compareTo((String) base.get(b));
if (compare == 0) {
return -1;
}
return compare;
}
}
}
und dies ist die Testklasse (ich habe es gerade getestet, und dies funktioniert für die Integer, String Map:
package test.nl.iamit.util;
import java.util.HashMap;
import java.util.TreeMap;
import nl.iamit.util.Comparators;
import org.junit.Test;
import static org.junit.Assert.assertArrayEquals;
public class TestComparators {
@Test
public void testMapIntegerStringComparator(){
HashMap<Integer, String> unSoretedMap = new HashMap<Integer, String>();
Comparators.MapIntegerStringComparator bvc = new Comparators.MapIntegerStringComparator(
unSoretedMap);
TreeMap<Integer, String> sorted_map = new TreeMap<Integer, String>(bvc);
//the testdata:
unSoretedMap.put(new Integer(1), "E");
unSoretedMap.put(new Integer(2), "A");
unSoretedMap.put(new Integer(3), "E");
unSoretedMap.put(new Integer(4), "B");
unSoretedMap.put(new Integer(5), "F");
sorted_map.putAll(unSoretedMap);
Object[] targetKeys={new Integer(2),new Integer(4),new Integer(3),new Integer(1),new Integer(5) };
Object[] currecntKeys=sorted_map.keySet().toArray();
assertArrayEquals(targetKeys,currecntKeys);
}
}
Hier ist der Code für den Comparator einer Map:
public static class MapStringDoubleComparator implements Comparator {
Map<String, Double> base;
public MapStringDoubleComparator(Map<String, Double> base) {
this.base = base;
}
//note if you want decending in stead of ascending, turn around 1 and -1
public int compare(Object a, Object b) {
if ((Double) base.get(a) == (Double) base.get(b)) {
return 0;
} else if((Double) base.get(a) < (Double) base.get(b)) {
return -1;
}else{
return 1;
}
}
}
und dies ist der Testfall dafür:
@Test
public void testMapStringDoubleComparator(){
HashMap<String, Double> unSoretedMap = new HashMap<String, Double>();
Comparators.MapStringDoubleComparator bvc = new Comparators.MapStringDoubleComparator(
unSoretedMap);
TreeMap<String, Double> sorted_map = new TreeMap<String, Double>(bvc);
//the testdata:
unSoretedMap.put("D",new Double(67.3));
unSoretedMap.put("A",new Double(99.5));
unSoretedMap.put("B",new Double(67.4));
unSoretedMap.put("C",new Double(67.5));
unSoretedMap.put("E",new Double(99.5));
sorted_map.putAll(unSoretedMap);
Object[] targetKeys={"D","B","C","E","A"};
Object[] currecntKeys=sorted_map.keySet().toArray();
assertArrayEquals(targetKeys,currecntKeys);
}
Natürlich kann man das auch viel allgemeiner gestalten, aber ich brauchte es nur für einen Fall (die Karte)