前几天在写代码时候遇见对Map中元素根据Value排序的情景,就想抽空花点时间认真学习巩固总结一下。
说道排序,我们无非还是得和比较说起,没有比较何有顺序!在Java中可以参与比较的两个接口莫非是:
可以比较的,实现该接口的类本身就具备了比较的特征。
public interface Comparable<T> {//Comparable是java.lang包中类
public int compareTo(T o);
}
另一个是比较器,本身不具备比较功能:
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);//默认所有类接口都是Object类的子类,所以本类我们可以不自己实现
}
接下来看看Comparable示例:
/**
*
* Comparable是可以比较的,也就是说实现Comparable接口自身就有比较的特征了
*
* @author Daxin
*
*/
class Cat implements Comparable<Cat> {
private int age;
private String name;
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public Cat(int age, String name) {
super();
this.age = age;
this.name = name;
}
@Override
public int compareTo(Cat o) {
return this.age - o.age;
}
}
Main函数:
public static void main(String[] args) {
Cat c1 = new Cat(5, "Tomcat");
Cat c2 = new Cat(3, "Tom");
System.out.println(c1.compareTo(c2)>0?c1.getName():c2.getName());
}
再看看Comparator示例:
class Dog {
private int age;
private String name;
@Override
public String toString() {
return "Dog [age=" + age + ", name=" + name + "]";
}
public Dog(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**
*
* 这是一个Dog的比较器,然而Dog本身不具备比较的特征,只能使用DogComparator进行比较
* 当然也可以使用Dog实现Comparator接口,但是这么设计是不合理的
*
* @author Daxin
*
*/
class DogComparator implements Comparator<Dog> { //Comparator是java.util包中的
@Override
public int compare(Dog o1, Dog o2) {
// TODO Auto-generated method stub
return o1.getAge() - o2.getAge();
}
}
Main方法如下:
public static void main(String[] args) {
Dog d1=new Dog(3, "Maomao");
Dog d2=new Dog(4, "Huanhuan");
//实例化比较器
DogComparator comparator = new DogComparator();
System.out.println(comparator.compare(d1, d2)>0?d1.getName():d2.getName());
}
接下来看看Map根据Entry的key或Value排序实现:
/**
*
* Bean
*
* @author Daxin
*
*/
class User {
private int age;
private int level;
public User(int age, int level) {
super();
this.age = age;
this.level = level;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
@Override
public String toString() {
return "User [age=" + age + ", level=" + level + "]";
}
}
Main方法,借助于Collections的sort工具方法进行排序:
/**
*
* 将HashMap中的实体根据Key排序
*
*
* @author Daxin
*
*/
public class Main1 {
public static void main(String[] args) {
Map<Integer, User> map = new HashMap<>();
Random rn = new Random();
for (int i = 0; i < 5; i++) {
map.put(rn.nextInt(20), new User(rn.nextInt(20), rn.nextInt(20)));
}
System.out.println(map);
// 将map中key-value实体转成序列。 由于Collections仅仅支持对List的子类进行排序,所以转成list,况且HashMap是无顺序的
ArrayList<Map.Entry<Integer, User>> list = new ArrayList<>(map.entrySet());
System.out.println(list);
// 由于Collections仅仅支持对List的子类进行排序,所以转成list,况且HashMap是无顺序的
Collections.sort(list, new Comparator<Map.Entry<Integer, User>>() {//传进去一个比较器
@Override
public int compare(Map.Entry<Integer, User> o1, Map.Entry<Integer, User> o2) {//比较器的比较规则函数
return o1.getKey() - o2.getKey();//指定规则,如果想根据Value比较的话直接使用getValue即可
}
});
System.out.println(list);
}
}
在使用Map时候要多多结合Map的内部类Entry使用,往往会事半功倍!