需求:需要根据List集合中的对象属性去排序或者根据List集合中的每个Map的某个具体值去排序,
下面列举了几种排序方法
搭建场景:
@Data
@AllArgsConstructor
public class Phone {
//编号
Integer pId ;
//名称
String pName;
//价格
Integer price;
}
Phone phone1 = new Phone(1011,"华为",4999);
Phone phone2 = new Phone(1011,"小米",2999);
Phone phone3 = new Phone(1012,"苹果",6999);
Phone phone4 = new Phone(1013,"荣耀",3999);
List<Phone> phoneList = Arrays.asList(phone1, phone2, phone3, phone4);
list.sort()方法
这种方法会直接操作集合来进行排序
//根据pId升序
phoneList.sort(Comparator.comparing(Phone::getPId));
[Phone(pId=1011, pName=华为, price=4999),
Phone(pId=1011, pName=小米, price=2999),
Phone(pId=1012, pName=苹果, price=6999),
Phone(pId=1013, pName=荣耀, price=3999)]
//根据pId升序,如果pId相同,根据price升序
phoneList.sort(Comparator.comparing(Phone::getPId).thenComparing(Phone::getPrice));
[Phone(pId=1011, pName=小米, price=2999),
Phone(pId=1011, pName=华为, price=4999),
Phone(pId=1012, pName=苹果, price=6999),
Phone(pId=1013, pName=荣耀, price=3999)]
//根据pId降序
phoneList.sort(Comparator.comparing(Phone::getPId).reversed());
[Phone(pId=1013, pName=荣耀, price=3999),
Phone(pId=1012, pName=苹果, price=6999),
Phone(pId=1011, pName=华为, price=4999),
Phone(pId=1011, pName=小米, price=2999)]
//根据pid升序,pid相同的根据price降序
phoneList.sort(Comparator.comparing(Phone::getPId).
thenComparing(Phone::getPrice,Comparator.reverseOrder()));
[Phone(pId=1011, pName=华为, price=4999),
Phone(pId=1011, pName=小米, price=2999),
Phone(pId=1012, pName=苹果, price=6999),
Phone(pId=1013, pName=荣耀, price=3999)]
采用Stream流处理
这种方式不会改变原集合
//根据pId升序,如果pId相同,根据price升序
List<Phone> phoneStreamList = phoneList
.stream()
.sorted(Comparator.comparing(Phone::getPId).thenComparing(Phone::getPrice))
.collect(Collectors.toList());
[Phone(pId=1011, pName=小米, price=2999),
Phone(pId=1011, pName=华为, price=4999),
Phone(pId=1012, pName=苹果, price=6999),
Phone(pId=1013, pName=荣耀, price=3999)]
搭建场景:
Map<String, Object> alarmMap1 = new HashMap<>();
Map<String, Object> alarmMap2 = new HashMap<>();
Map<String, Object> alarmMap3 = new HashMap<>();
alarmMap1.put("雅迪",15);
alarmMap2.put("九号",2);
alarmMap3.put("小牛",88);
List<Map<String, Object>> alarmList = Arrays.asList(alarmMap1,alarmMap2,alarmMap3);
根据Map中的15,2,88排序
两种实现方式:
//根据value值进行降序排序
alarmList.sort((map1,map2) -> {
//提取map1 和 map2 中的值进行比较
int value1 = (int) map1.values().iterator().next();
int value2 = (int) map2.values().iterator().next();
//返回比较结果,实现降序排序
return Integer.compare(value2,value1);
});
Collections.sort(alarmList, new Comparator<Map<String, Object>>() {
@Override
public int compare(Map<String, Object> o1, Map<String, Object> o2) {
Integer value1 = (Integer) o1.values().toArray()[0];
Integer value2 = (Integer) o2.values().toArray()[0];
return value2.compareTo(value1); // 降序排序
}
});
[{小牛=88},
{雅迪=15},
{九号=2}]
另外一种Map类型的场景:
Map<String, Object> alarmMap1 = new HashMap<>();
Map<String, Object> alarmMap2 = new HashMap<>();
Map<String, Object> alarmMap3 = new HashMap<>();
alarmMap1.put("名称","戴尔");
alarmMap1.put("数量",1);
alarmMap2.put("名称","联想");
alarmMap2.put("数量",5);
alarmMap3.put("名称","华硕");
alarmMap3.put("数量",3);
List<Map<String, Object>> alarmList = Arrays.asList(alarmMap1,alarmMap2,alarmMap3);
根据"数量"进行排序
alarmList.sort((map1,map2) -> {
int value1 = (int) map1.get("数量");
int value2 = (int) map2.get("数量");
//返回比较结果,实现排序
return Integer.compare(value1,value2);
});
[{数量=1, 名称=戴尔},
{数量=3, 名称=华硕},
{数量=5, 名称=联想}]
compare方法默认是升序的,如过需要倒序,只需要修改两个参数的位置
alarmList.sort((map1,map2) -> {
int value1 = (int) map1.get("数量");
int value2 = (int) map2.get("数量");
//返回比较结果,实现降序排序
return Integer.compare(value2,value1);
});
[{数量=5, 名称=联想},
{数量=3, 名称=华硕},
{数量=1, 名称=戴尔}]
比较原理:
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;
}
假如现在开始比较,o1的值为1,o2的值为2,那么return的就是1-2=-1,返回-1,那么在比较器中认为1<2的,就会把1放到前面,但是假如把里面的返回逻辑改掉了,改成o2-o1,那么同样的o1=1,o2=2的情况下,返回的就是2-1=1,那么比较器就会认为1>2,比较器就会把2排序的更前面一点(因为它认为2是小于1的),这样就变成了降序排序。