我有HashMap
看起来像:
HashMap<Player, Integer> playerHashMap = new HashMap<>();
玩家是包含姓名,号码,年龄等的对象。
现在我已经对它进行了分类,它就像这样:
key , value
-----------------
Player1, 1
Player2, 2
Player3, 4
Player4, 6
但是我希望按值反转这个地图,如下所示:
key , value
-----------------
Player4, 6
Player3, 4
Player2, 2
Player1, 1
有什么想法吗?
排序方法(按值排序)如下所示:
private static HashMap<Player, Integer> sortByValues(HashMap<Player, Integer> map) {
List list = new LinkedList(map.entrySet());
Collections.sort(list, new Comparator<Object>() {
public int compare(Object o1, Object o2) {
return ((Comparable) ((Map.Entry) (o1)).getValue())
.compareTo(((Map.Entry) (o2)).getValue());
}
});
HashMap<Player, Integer> sortedHashMap = new LinkedHashMap<Player, Integer>();
for (Iterator<?> it = list.iterator(); it.hasNext();) {
Map.Entry<Player, Integer> entry = (Map.Entry<Player, Integer>) it.next();
sortedHashMap.put(entry.getKey(), entry.getValue());
}
return sortedHashMap;
}
答案 0 :(得分:2)
您可以使用java.util.TreeMap并传递比较器,以您想要的方式对它们进行排序。
但是我仍然想知道为什么你有玩家作为钥匙和整数作为价值? 如果仅使用Integer进行排序,则可能需要交换Key和值以获得更好的标准使用Maps的方法。 此外,如果您不需要使用散列技术访问对象(即如果您的集合在散列会提高性能的情况下不会很大),请考虑使用简单的List。
答案 1 :(得分:1)
事实是HashMap并没有保证任何特定的迭代顺序。所以你只是幸运了#39;您的列表以任何方式排序。要解决您的问题,您必须将表行排序为一个实体,以便value
链接到相应的player
。为此,您可以直接使用Map.Entry,并将它们放到集合中,但您需要一个自定义比较器。在您的示例中,最好使用通常的ArrayList
作为任务,并使用Collections.sort()
对其进行排序。要颠倒顺序,否定从比较器返回的结果:
class Player {}
public static void main(String[] args) {
HashMap<Player, Integer> all = new HashMap<>();
List<Map.Entry<Player, Integer>> sorted = sortByValues(all);
for (Map.Entry<Player, Integer> e : sorted) {
System.out.println("Player: " + e.getKey());
System.out.println("Value: " + e.getValue());
}
}
private static List<Map.Entry<Player, Integer>> sortByValues(HashMap<Player, Integer> map) {
List<Map.Entry<Player, Integer>> list = new ArrayList<>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Player, Integer>>() {
public int compare(Map.Entry<Player, Integer> e1, Map.Entry<Player, Integer> e2) {
//use minus to reverse the order
return -e1.getValue().compareTo(e2.getValue());
}
});
return list;
}
答案 2 :(得分:1)
你是怎么排序的? (基本)HashMap不定义元素之间的顺序。 我用这个:
public static <K extends Comparable<K>,V> List<Entry<K,V>> sortByKeys(Map<K,V> map, final Comparator<K> cmp)
{
List<Entry<K, V>> ret = new ArrayList<>();
for(Entry<K,V> kv : map.entrySet())
ret.add(kv);
Collections.sort(ret,((Comparator) new Comparator<Entry<K,?>>()
{
@Override
public int compare(Entry<K, ?> o1, Entry<K, ?> o2)
{
return cmp.compare(o1.getKey(), o2.getKey());
}
}));
return ret;
}
您可以指定比较器来订购退回的入库清单。
=====
编辑: 使用关注顺序的Map实现是个好主意。 您可以简单地修改代码以指定排序,只需修改标题和这一行:
-private static HashMap<Player, Integer> sortByValues(HashMap<Player, Integer> map) {
+private static HashMap<Player, Integer> sortByValues(HashMap<Player, Integer> map, final boolean reverse) {
并在街区:
-return ((Comparable) ((Map.Entry) (o1)).getValue())
+return (reverse?-1:1)*((Comparable) ((Map.Entry) (o1)).getValue())
答案 3 :(得分:1)
我不确定您为什么要返回单独的地图。您已经拥有了List,您只需按存储条目的值进行排序即可 也不要限制自己使用特定类型的地图,如HashMap。你可能只获得了一些东西,但是你很难将你的实现改为其他类型的Map。
所以你的代码看起来像:
private static List<Map.Entry<Player, Integer>> entriesSoltedByValue(
Map<Player, Integer> map) {
List<Map.Entry<Player, Integer>> list = new ArrayList<>(map.entrySet());
list.sort(Comparator.comparing(Map.Entry<Player, Integer>::getValue).reversed());
return list;
}
或使用流:
private static List<Map.Entry<Player, Integer>> entriesSoltedByValue(
Map<Player, Integer> map) {
return map.entrySet()
.stream()
.sorted(Comparator
.comparing(Map.Entry<Player, Integer>::getValue)
.reversed())
.collect(Collectors.toList());
}
答案 4 :(得分:1)
简而言之,您无法将订单设置为HashMap
。如果您希望使用与HashMap
相同的功能,但需要使用TreeMap。
Map<String, Integer> orderedMap = new TreeMap(Collections.reverseOrder());
orderedMap.putAll(playerHashMap);
HashMap
在TreeMap
中为O(log(n))提供O(1)插入和搜索,因为它在内部用红黑树实现。