Ответ, за который проголосовали большинство, не работает, если у вас есть 2 равных элемента.
TreeMap оставляет равные значения.
пример:
несортированная карта
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
Результаты
key/value: A/99.5
key/value: C/67.5
key/value: B/67.4
key/value: D/67.3
Так что упусти E !!
Для меня это работало нормально, чтобы настроить компаратор, если он равен не вернуть 0, а -1.
в примере:
класс ValueComparator реализует Comparator {
Карта базы;
public ValueComparator (База карт) {
this.base = base;
}
public int Сравнение (Объект a, Объект 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;
}
}
}
теперь возвращается:
несортированная карта:
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
Результаты:
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
как ответ иностранцам (2011 ноябрь 22):
Я использую это решение для карты целочисленных идентификаторов и имен, но идея та же самая, поэтому, возможно, приведенный выше код неверен (я напишу его в тесте и дам правильный код), это код для сортировки карт, основанной на решении выше:
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;
}
}
}
и это тестовый класс (я только что проверил его, и это работает для 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);
}
}
вот код для компаратора карты:
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;
}
}
}
и вот тест для этого:
@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);
}
конечно, вы можете сделать это более общим, но мне просто нужно было это для 1 случая (Карта)