排序
大约 4 分钟languagejava
实体类实现 compareTo
@Data
public class UserDTO implements Comparable<UserDTO> {
private String name;
private Integer age;
public UserDTO(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(UserDTO userDTO) {
//重写compareTo方法,按照年龄升序排序。若要降序只需要修改相减的顺序即可
//升序
//return this.age - userDTO.getAge();
//降序
return userDTO.getAge() - this.age;
}
}
//测试方法
public static void main(String[] args) {
List<UserDTO> list = new ArrayList<>();
list.add(new UserDTO("西施",18));
list.add(new UserDTO("王昭君",16));
list.add(new UserDTO("杨昭君",20));
list.add(new UserDTO("貂蝉",24));
list.add(new UserDTO("猪八戒",5));
Collections.sort(list);
System.err.println(list);
}
//升序打印结果为:
[UserDTO(name=猪八戒, age=5), UserDTO(name=王昭君, age=16), UserDTO(name=西施, age=18), UserDTO(name=杨昭君, age=20), UserDTO(name=貂蝉, age=24)]
//降序序打印结果为:
[UserDTO(name=貂蝉, age=24), UserDTO(name=杨昭君, age=20), UserDTO(name=西施, age=18), UserDTO(name=王昭君, age=16), UserDTO(name=猪八戒, age=5)]
Lambda 表达式排序
public static void main(String[] args) {
List<UserDTO> list = new ArrayList<>();
list.add(new UserDTO("西施", 18));
list.add(new UserDTO("王昭君", 16));
list.add(new UserDTO("杨昭君", 20));
list.add(new UserDTO("貂蝉", 24));
list.add(new UserDTO("猪八戒", 5));
Collections.sort(list, new Comparator<UserDTO>() {
@Override
public int compare(UserDTO o1, UserDTO o2) {
//第一个参数属性 - 第二个参数属性 = 升序排序
//第二个参数属性 - 第一个参数属性 = 降序排序
int num = o2.getAge() - o1.getAge();
if (num > 0) {
return 1;
} else if (num < 0) {
return -1;
}
return 0;
}
});
System.err.println(list);
}
//打印结果-降序
[UserDTO(name=貂蝉, age=24), UserDTO(name=杨昭君, age=20), UserDTO(name=西施, age=18), UserDTO(name=王昭君, age=16), UserDTO(name=猪八戒, age=5)]
// 也可以直接使用 List 对象的 sort 方法
list.sort(new Comparator<UserDTO>(){
@Override
public int compare(UserDTO o1,UserDTO o2){
//TODO:xxxxx
return 0;
}
})
// 如果 JDK在8以及以上可以使用 lambda 表达式简化写法
// 使用 Lambda 表达式按照 level 升序排序
Collections.sort(mapList, (o1, o2) -> o1.get("level").compareTo(o2.get("level")));
// 或者使用更简洁的方式
mapList.sort(Comparator.comparing(m -> m.get("level")));
多属性排序
多属性排序中不可将多个属性对比的结果相加后排序,而应该是层层递进对比多属性后排序。
实体类
private class Person {
private String name;
private int gender;
private int age;
private int height;
public Person(String name, int gender, int age, int height) {
this.name = name;
this.gender = gender;
this.age = age;
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", gender=" + gender +
", age=" + age +
", height=" + height +
'}';
}
}
测试用数据
List<Person> ps = new ArrayList<>();
ps.add(new Person("Alice",0,11,165));
ps.add(new Person("Tom",1,99,178));
ps.add(new Person("Jerry",1,22,199));
ps.add(new Person("Alex",1,22,165));
ps.add(new Person("Luci",0,9,112));
ps.add(new Person("Anni",0,9,101));
反例
分别对比每个属性,将多个对比结果相加进行排序
public void test02(){
List<Person> ps = new ArrayList<>();
ps.add(new Person("Alice",0,11,165));
ps.add(new Person("Tom",1,99,178));
ps.add(new Person("Jerry",1,22,199));
ps.add(new Person("Alex",1,22,165));
ps.add(new Person("Luci",0,9,112));
ps.add(new Person("Anni",0,9,101));
// 多属性排序:性别(0在前)、年龄(升序)、身高(升序)
ps.sort(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int ret = o1.getGender()-o2.getGender();
int order1 = 0;// gender比较结果
int order2 = 0;// age比较结果
int order3 = 0;// height比较结果
if(ret > 0) order1 = 1;
else if(ret < 0) order1 = -1;
else order1 = 0;
ret = o1.getAge() - o2.getAge();
if(ret > 0) order2 = 1;
else if(ret < 0) order2 = -1;
else order2 = 0;
ret = o1.getHeight() - o2.getHeight();
if(ret > 0) order3 = 1;
else if(ret < 0) order3 = -1;
else order3 = 0;
return order1 + order2 + order3;
}
});
}
多属性渐进排序
多个属性要递进对比后排序
List<Person> ps = new ArrayList<>();
ps.add(new Person("Alice",0,11,165));
ps.add(new Person("Tom",1,99,178));
ps.add(new Person("Jerry",1,22,199));
ps.add(new Person("Alex",1,22,165));
ps.add(new Person("Luci",0,9,112));
ps.add(new Person("Anni",0,9,101));
ps.sort(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int ret1 = o1.getGender()-o2.getGender();
int ret2 = o1.getAge()-o2.getAge();
int ret3 = o1.getHeight()-o2.getHeight();
if(ret1 == 0)// 性别相同,按照年龄排序
if(ret2 == 0)// 性别、年龄都相同则按照身高排序
if(ret3 == 0) return 0;
else return ret3 > 0 ? 1 : -1;
else return ret2 > 0 ? 1 : -1;
else return ret1 > 0 ? 1 : -1;
}
});
Lambda 链式排序
private void compare03(List<Person> list){
list = list.stream().sorted(Comparator.comparing(Person::getGender,(int1,int2) -> {
int ret = int1 - int2;
if(ret == 0) return 0;
else return ret > 0 ? 1 : -1;
}).thenComparing(Person::getAge,(a1,a2) -> {
int ret = a1 - a2;
if(ret == 0) return 0;
else return ret > 0 ? 1 : -1;
}).thenComparing(Person::getHeight,(a1,a2) -> {
int ret = a1 - a2;
if(ret == 0) return 0;
else return ret > 0 ? 1 : -1;
})
).collect(Collectors.toList());
System.out.println(list);
}
