排序LinkedHashMap

54

我如何按值对LinkedHashMap进行排序,考虑到LinkedHashMap包含字符串和整数。因此,我需要根据整数值对其进行排序。 非常感谢。


2
你必须使用LinkedHashMap吗?TreeMap可能会有所帮助。 - RNJ
2
这可能会有所帮助:https://dev59.com/YXRA5IYBdhLWcg3w6SbZ - RNJ
哦,我明白了。没注意读评论。^_^ - DankMemes
4个回答

81
List<Map.Entry<String, Integer>> entries =
  new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
Collections.sort(entries, new Comparator<Map.Entry<String, Integer>>() {
  public int compare(Map.Entry<String, Integer> a, Map.Entry<String, Integer> b){
    return a.getValue().compareTo(b.getValue());
  }
});
Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
for (Map.Entry<String, Integer> entry : entries) {
  sortedMap.put(entry.getKey(), entry.getValue());
}

4
好吧,我正在编写完全相同的代码! :) 除了最后一部分,我认为 OP 实际上不需要将它们放回映射中。 - Marko Topolnik
很好的答案。我需要按降序排序,所以在从比较器返回值时添加了一个负号。 - Michael Massey
更喜欢交换参数的顺序;如果原始的compareTo返回Integer.MIN_VALUE,则否定并不总是有效。 - Louis Wasserman
请写出 b.getValue().compareTo(a.getValue()) 的代码。 - Louis Wasserman
2
您不需要更改比较器。您可以使用Collections.reverseOrder(comparator),这样意思更明显。 - sprinter

48

Java 8 streams使这现在变得更加容易:您无需中间的map即可进行排序:

map.entrySet().stream()
    .sorted(Map.Entry.comparingByValue())
    .forEach(entry -> ... );

1
这三个点代表什么? - Barracuda
这三个点代表你想对排序后的值做任何操作。它可以是调用另一个方法,打印它们,将它们收集到不同的映射中 - 无论你的问题需要什么。 - sprinter
2
为什么这个答案被接受并且评价如此之高?它并没有回答如何对地图本身进行排序。它只是告诉我们如何按特定顺序处理地图的内容。 - Guardian667
1
@Guardian667 地图本身无法就地排序。虽然某些地图保证它们的顺序,但这在接口的文档中非常清楚。我怀疑 OP 和投票者意识到了这一点,并理解“根据其值对地图进行排序”是指按照其值的顺序使用条目。对于问题的任何其他解释都没有任何意义。 - sprinter
那是一个有效的建议。谢谢。 - Guardian667

4

LinkedHashMap 只保持插入顺序。如果您想根据值进行排序,则可能需要编写自己的 comparator


1
太棒了,是的,非常感谢,我确实编写了自己的比较器。 - Ramin
1
我认为你不需要编写自己的比较器。Map.Entry.comparingByValue()可以为你生成一个,并且它可以通过 Collections.reverseOrder(Map.Entry.comparingByValue()) 进行反转。 - sprinter
@sprinter:如果该值是任何自定义对象类型,怎么办? - kosa
@Nambari 要么让该类型实现 Comparable 接口,要么为 Map.Entry.comparingByValue 提供一个自定义的 Comparator - sprinter
@sprinter:没错,这就是这个答案的意思。 - kosa
1
你会如何使用那个比较器?你提供的解决方案与其他人不同吗? - Radu Simionescu

1
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.SortedMap;
import java.util.TreeMap;

public class HashMapTest {

public static void main(String[] args) {

    Map<String, Integer> map=new LinkedHashMap<String, Integer>();

    map.put("a", 11);
    map.put("B", 12);
    map.put("c", 3);
    map.put("d", 4);
    map.put("e", 5);
    map.put("f", 6);
    map.put("g", 7);
    map.put("h", 8);
    map.put("i", 9);
    map.put("j", 3);
    map.put("k", 2);
    map.put("l", 1);

    List<Map.Entry<String, Integer>> entries = new 
    ArrayList<Map.Entry<String, Integer>>(map.entrySet());
            Collections.sort(entries,new CustomizedHashMap());


            Map<String, Integer> sortedMap = new LinkedHashMap<String, 
   Integer>();
            for (Map.Entry<String, Integer> entry : entries) {
              sortedMap.put(entry.getKey(), entry.getValue());
              System.out.print( sortedMap.put(entry.getKey(), 
          entry.getValue())+"  ");
            }
     }
    }

 class CustomizedHashMap implements Comparator<Map.Entry<String, Integer>> {

  @Override
  public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
    // TODO Auto-generated method stub
    return -o1.getValue().compareTo(o2.getValue());
  }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接