如何对 Java 中的 HashMap 进行排序?
How to sort a HashMap in Java?
我正在使用 HashMap<String,Integer>
作为一种定时投票系统。其中字符串是对象的名称,整数是对象拥有的票数。我想做的是对整数进行降序排序,如果他们是平局,我想选择之前没有赢得投票的那个(如果他们中的任何一个赢得了投票)
我尝试使用 TreeMap
,但它似乎无法满足我的要求,因为它根据键的值进行排序,而我需要对值进行排序。也不起作用,因为有时两个对象可能都具有相同的票数。
取自 here,下面是如何使用 JDK 8:
按值(降序)对 Map
进行排序
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
return map.entrySet().stream().sorted(Map.Entry.comparingByValue(Collections.reverseOrder())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
}
示例:
Map<String, Integer> votes = new HashMap<>();
votes.put("A", 5);
votes.put("B", 17);
votes.put("C", 1);
System.out.println(votes);
>> {A=5, B=17, C=1}
votes = sortByValue(votes);
System.out.println(votes);
>> {B=17, A=5, C=1}
为了能够确定平局的结果,您需要的不仅仅是一个整数。一种解决方案可能是创建一个自定义对象,该对象包含额外信息并实现可比性(类似于 Walter 所说)。
根据我从您的 post 中得知的情况,当出现平局投票时,您希望结果是与其他平局选项一样最近未被选中的选项。如果是这种情况,那么下面使用日期作为次要信息的解决方案应该可行。
import java.util.Date;
public class VoteOption implements Comparable<VoteOption>{
private String name;
private Integer votes;
private Date lastVote;
/** Constructor */
public VoteOption(String name){
this.name = name;
this.lastVote = new Date();
this.votes = 0;
}
/** gets the name of this option */
public String name(){
return this.name;
}
/** gets the number of votes this option currently has */
public int votes(){
return this.votes;
}
/** Call this method if the vote passed with this option.
* It will update the lastVote date so that this will become the
* last option to be picked if there is a tie in the next vote. */
public void votePassed(){
this.lastVote = new Date();
}
/** resets the vote count back to 0 */
public void resetVoteCount(){
this.votes = 0;
}
/** Adds 1 vote to the vote count */
public void vote(){
this.votes ++;
}
@Override
public int compareTo(VoteOption otherOption){
int compareVotes = this.votes.compareTo(otherOption.votes);
if(compareVotes!=0){
return compareVotes;
} else {
//handle vote ties
int compareDates = this.lastVote.compareTo(otherOption.lastVote);
return compareDates;
}
}
}
要对这些选项的列表进行排序,您应该调用
Collections.sort(list);
我正在使用 HashMap<String,Integer>
作为一种定时投票系统。其中字符串是对象的名称,整数是对象拥有的票数。我想做的是对整数进行降序排序,如果他们是平局,我想选择之前没有赢得投票的那个(如果他们中的任何一个赢得了投票)
我尝试使用 TreeMap
,但它似乎无法满足我的要求,因为它根据键的值进行排序,而我需要对值进行排序。也不起作用,因为有时两个对象可能都具有相同的票数。
取自 here,下面是如何使用 JDK 8:
按值(降序)对Map
进行排序
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
return map.entrySet().stream().sorted(Map.Entry.comparingByValue(Collections.reverseOrder())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
}
示例:
Map<String, Integer> votes = new HashMap<>();
votes.put("A", 5);
votes.put("B", 17);
votes.put("C", 1);
System.out.println(votes);
>> {A=5, B=17, C=1}
votes = sortByValue(votes);
System.out.println(votes);
>> {B=17, A=5, C=1}
为了能够确定平局的结果,您需要的不仅仅是一个整数。一种解决方案可能是创建一个自定义对象,该对象包含额外信息并实现可比性(类似于 Walter 所说)。
根据我从您的 post 中得知的情况,当出现平局投票时,您希望结果是与其他平局选项一样最近未被选中的选项。如果是这种情况,那么下面使用日期作为次要信息的解决方案应该可行。
import java.util.Date;
public class VoteOption implements Comparable<VoteOption>{
private String name;
private Integer votes;
private Date lastVote;
/** Constructor */
public VoteOption(String name){
this.name = name;
this.lastVote = new Date();
this.votes = 0;
}
/** gets the name of this option */
public String name(){
return this.name;
}
/** gets the number of votes this option currently has */
public int votes(){
return this.votes;
}
/** Call this method if the vote passed with this option.
* It will update the lastVote date so that this will become the
* last option to be picked if there is a tie in the next vote. */
public void votePassed(){
this.lastVote = new Date();
}
/** resets the vote count back to 0 */
public void resetVoteCount(){
this.votes = 0;
}
/** Adds 1 vote to the vote count */
public void vote(){
this.votes ++;
}
@Override
public int compareTo(VoteOption otherOption){
int compareVotes = this.votes.compareTo(otherOption.votes);
if(compareVotes!=0){
return compareVotes;
} else {
//handle vote ties
int compareDates = this.lastVote.compareTo(otherOption.lastVote);
return compareDates;
}
}
}
要对这些选项的列表进行排序,您应该调用
Collections.sort(list);