Java中HashMap不同于Array、ArrayList和LinkedLists,它不会维持插入元素的顺序。因此对HashMap排序的掌握很重要。HashMap排序有两个步骤:
- 1、通过map.entrySet()方法获取键值对;并将键值对传递给链表list;
- 2、自定义比较器来使用Collections.sort()方法排序链表。
关于map的遍历方法可参考java中Map的七种遍历方法
例如下面的按照value降序排列:
Collections.sort(list, new Comparator<Entry<String,Integer>>() {
public int compare(Entry<String, Integer> ele1, Entry<String, Integer> ele2) {
return ele1.getValue().compareTo(ele2.getValue());
}
});
灵活使用Comparator接口可以实现HashMap的灵活排序:包括分别对键、值的升降序排序,优先按值、其次按键排序,或者优先按键、其次按值排序;以上实现只需重写compare方法。
1、对value降序排列
public int compare(Map.Entry<Integer,Integer>e1,Map.Entry<Integer,Integer>e2){
return e2.getValue().compareTo(e1.getValue());
}
2、对键KEY降序排列
public int compare(Map.Entry<Integer,Integer>e1,Map.Entry<Integer,Integer>e2){
return e2.getKey().compareTo(e1.getKey());
}
3、优先按值value降序、其次按键key升序排序
public int compare(Map.Entry<String,Integer>e1,Map.Entry<String,Integer>e2){
int re = e2.getValue().compareTo(e1.getValue());
if(re!=0){return re;}
else{return e1.getKey().compareTo(e2.getKey());}
}
4、优先按键key降序、其次按值value升序排序
public int compare(Map.Entry<String,Integer>e1,Map.Entry<String,Integer>e2){
int re = e2.getKey().compareTo(e1.getKey());
if(re!=0){return re;}
else{return e1.getValue().compareTo(e2.getValue());}
}
例题:
HJ102 字符统计
题意描述:输入一个只包含小写英文字母和数字的字符串,按照不同字符统计个数由多到少输出统计结果,如果统计的个数相同,则按照ASCII码由小到大排序输出。
本题含有多组样例输入
很简单的一个思路就是先对map的值排序,然后再按照键排序。
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner cin=new Scanner(System.in);
while(cin.hasNext()){
Map<Character,Integer> map = new HashMap<Character,Integer>();
String string=cin.next();
for(int i=0;i<string.length();i++){
char c=string.charAt(i);
if(map.get(c)==null) map.put(c,1);
else map.put(c,map.get(c)+1);
}
List<Map.Entry<Character,Integer>> list = new ArrayList<>();
list.addAll(map.entrySet());
Collections.sort(list,new Comparator<Map.Entry<Character,Integer>>(){
public int compare(Map.Entry<Character,Integer>e1,Map.Entry<Character,Integer>e2){
int re = e2.getValue().compareTo(e1.getValue());
if(re!=0){return re;}
else{return e1.getKey().compareTo(e2.getKey());}
}
});
for(Map.Entry<Character,Integer> map1:list){
System.out.print(map1.getKey());
}
System.out.println();
}
}
}
当然,我们也可以利用普通类实现Comparable接口来对数据进行自定义排序
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner cin=new Scanner(System.in);
while(cin.hasNext()){
Map<Character,Integer> map = new HashMap<Character,Integer>();
String string=cin.next();
for(int i=0;i<string.length();i++){
char c=string.charAt(i);
if(map.get(c)==null) map.put(c,1);
else map.put(c,map.get(c)+1);
}
List<User> list=new ArrayList<>();
for(Map.Entry<Character,Integer> entry:map.entrySet()){
User user=new User();
user.setKey(entry.getKey());
user.setValue(entry.getValue());
list.add(user);
user=null;//释放对象
}
Collections.sort(list);
for (User user:list){
System.out.print(user.getKey());
}
System.out.println();
}
}
static class User implements Comparable<User>{
private Character key;
private Integer value;
public User() {
}
@Override
public int compareTo(User user) {
if(user.value==this.value)
return this.key.compareTo(user.key); //value相同key升序
return user.value.compareTo(this.value); //value不同则value降序
}
public Character getKey() {
return key;
}
public void setKey(Character key) {
this.key = key;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
}
}