如何先按值排序 Map 条目,然后按键排序并将排序的键放入列表中?
How to sort Map entries by values first, then by key and put the ordered keys in a List?
我有一个 HashMap :
private Map<String,Integer> matchesWonByTeam= new HashMap<String,Integer>();
- 我需要按赢得的比赛(值)和 return 包含球队名称的 ArrayList 对这些球队进行排序。
- 如果其中任何一支球队赢得的比赛数量相同,则需要按字母顺序排列。
使用集合和比较器最短、最简单的方法是什么?
Return条目集,创建一个列表,然后使用匿名比较器实现对条目进行排序。
List<Entry<String,Integer>> matchesWonList = new ArrayList<Entry<String,Integer>>(matchesWonByTeam.entrySet());
Collections.sort(matchesWonList , new Comparator<Entry<String,Integer>>(){
//implement your comparator here.
});
这个有效:
Map<String,Integer> map = new HashMap<String,Integer>();
/*...fill map...*/
SortedSet<Map.Entry<String, Integer>> sortedSet = new TreeSet<>(new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Entry<String, Integer> e1, Entry<String, Integer> e2) {
int res = e1.getValue().compareTo(e2.getValue());
if(res == 0)
return e1.getKey().compareTo(e2.getKey());
return res * -1;
}
});
sortedSet.addAll(map.entrySet());
List<String> list = new ArrayList<>();
for(Map.Entry<String, Integer> e: sortedSet)
list.add(e.getKey());
这是假设您希望顺序从最大 Integer
到最小 Integer
。如果不是,请在返回 res
时删除 * -1
。
这里有一些 Java 8 给你。
final Comparator<Map.Entry<String, Integer>> byMatchesWon =
Comparator.comparing(Map.Entry::getValue, Comparator.reverseOrder());
final Comparator<Map.Entry<String, Integer>> byTeamName =
Comparator.comparing(Map.Entry::getKey);
final List<String> hasToBeReturned = matchesWonByTeam
.entrySet().stream()
.sorted(byMatchesWon.thenComparing(byTeamName))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
注意 - 内联比较器在这里不起作用,编译器将无法推断出正确的实现。
您可以使用函数式编程来做到这一点:
final Map<String, Integer> map = new HashMap<>();
map.put("test", 1);
map.put("test1", 3);
map.put("test3", 4);
map.put("test2", 75);
map.put("a", 75);
map.put("test100", 100);
final List<String> test = map
.entrySet()
.stream()
.sorted((Entry<String, Integer> o1, Entry<String, Integer> o2) -> {
return o1.getValue().equals(o2.getValue()) ?
o1.getKey().compareTo(o2.getKey())
: o1.getValue().compareTo(o2.getValue());
})
.map(e -> e.getKey())
.collect(Collectors.toList());
for(String s : test)
System.out.println(s);
这个例子会输出
test test1 test3 a test2 test100
matchesWonByTeam 现在将是一个维护顺序的 linkedHashMap。
matchesWonByTeam = matchesWonByTeam.entrySet()
.stream()
.sorted(
new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
if(o1.getValue() < o2.getValue()) {
return -1;
}
if(o1.getValue() > o2.getValue()) {
return 1;
}
return o1.getKey().compareTo(o2.getKey());
}
}
)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1,e2) -> e1, LinkedHashMap::new));
我有一个 HashMap :
private Map<String,Integer> matchesWonByTeam= new HashMap<String,Integer>();
- 我需要按赢得的比赛(值)和 return 包含球队名称的 ArrayList 对这些球队进行排序。
- 如果其中任何一支球队赢得的比赛数量相同,则需要按字母顺序排列。
使用集合和比较器最短、最简单的方法是什么?
Return条目集,创建一个列表,然后使用匿名比较器实现对条目进行排序。
List<Entry<String,Integer>> matchesWonList = new ArrayList<Entry<String,Integer>>(matchesWonByTeam.entrySet());
Collections.sort(matchesWonList , new Comparator<Entry<String,Integer>>(){
//implement your comparator here.
});
这个有效:
Map<String,Integer> map = new HashMap<String,Integer>();
/*...fill map...*/
SortedSet<Map.Entry<String, Integer>> sortedSet = new TreeSet<>(new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Entry<String, Integer> e1, Entry<String, Integer> e2) {
int res = e1.getValue().compareTo(e2.getValue());
if(res == 0)
return e1.getKey().compareTo(e2.getKey());
return res * -1;
}
});
sortedSet.addAll(map.entrySet());
List<String> list = new ArrayList<>();
for(Map.Entry<String, Integer> e: sortedSet)
list.add(e.getKey());
这是假设您希望顺序从最大 Integer
到最小 Integer
。如果不是,请在返回 res
时删除 * -1
。
这里有一些 Java 8 给你。
final Comparator<Map.Entry<String, Integer>> byMatchesWon =
Comparator.comparing(Map.Entry::getValue, Comparator.reverseOrder());
final Comparator<Map.Entry<String, Integer>> byTeamName =
Comparator.comparing(Map.Entry::getKey);
final List<String> hasToBeReturned = matchesWonByTeam
.entrySet().stream()
.sorted(byMatchesWon.thenComparing(byTeamName))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
注意 - 内联比较器在这里不起作用,编译器将无法推断出正确的实现。
您可以使用函数式编程来做到这一点:
final Map<String, Integer> map = new HashMap<>();
map.put("test", 1);
map.put("test1", 3);
map.put("test3", 4);
map.put("test2", 75);
map.put("a", 75);
map.put("test100", 100);
final List<String> test = map
.entrySet()
.stream()
.sorted((Entry<String, Integer> o1, Entry<String, Integer> o2) -> {
return o1.getValue().equals(o2.getValue()) ?
o1.getKey().compareTo(o2.getKey())
: o1.getValue().compareTo(o2.getValue());
})
.map(e -> e.getKey())
.collect(Collectors.toList());
for(String s : test)
System.out.println(s);
这个例子会输出
test test1 test3 a test2 test100
matchesWonByTeam 现在将是一个维护顺序的 linkedHashMap。
matchesWonByTeam = matchesWonByTeam.entrySet()
.stream()
.sorted(
new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
if(o1.getValue() < o2.getValue()) {
return -1;
}
if(o1.getValue() > o2.getValue()) {
return 1;
}
return o1.getKey().compareTo(o2.getKey());
}
}
)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1,e2) -> e1, LinkedHashMap::new));