笔记--java sort() 方法排序
背景
最近在刷一道算法题 《字符串重新排序》时,发现自己有思路但是写代码的时候就无从下手了 而且看了答案之后还没看懂 关键就是基础不好 对于排序没有理解(虽然我学过常用的排序算法 但是都是理念 实践少)
目的
从实践和原理出发 重点是从实践出发 探讨如何使用 sort()方法 完成复杂的排序
能掌握到的知识
- 了解compaer(O1 ,O2) 中 返回1 -1 0 这三个什么意思 并且如何使用这三个值达到自己想要的排序
- 如何实现组合排序 即满足排序1情况下进行排序2
目录
- sort() 方法 简介
- sort() 方法使用
- 实战
sort()方法简介
sort()方法有很多种
- Arrays.sort()
public void sort(java.util.Comparator<? super E> c )
本次主要讨论的是第二种情况 并且是实现Comparator接口最简单的形式:
通过返回 1 0 -1 等三个数 比较列表中对象属性值的方法 实现的排序
如下所示
userList.sort((o1,o2) ->{if (o1.getAge() > o2.getAge()) {//降序return -1;} else if (o1.getAge() < o2.getAge()) {return 1;} else {return 0;}});
sort()方法的使用
那1 0 -1 分别代表什么呢 怎么比较能够实现升序降序呢
PS:这里并不一定是1 和-1 只要是负整数和正整数就行了 只不过我们习惯上用1和-1表示
放两个结论
- 三个数代表的意思
- 1:代表保持原样
- 0:代表保持原样
- -1:需要交换顺序
- 在排序前 o2 在o1前面
所以
- 升序:
- o1 > o2 时:前者比后者小 数越来越大 未排列前就是升序 不需要交换顺序 所以返回1或者0
- o1 < o2 时: 前者比后者大 数越来越小 未排列前就是降序 需要交换顺序 返回 - 1
降序你可以自己总结 下面我们实战演示一下
1. 单个属性的排序要求
给出测试数据
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {private int age;private int high;private String name;}
例子
public static void main(String[] args) {List<User> userList = new ArrayList<>();userList.add(new User(18, 165,"张三1"));userList.add(new User(16, 177, "张三11"));userList.add(new User(25, 189, "张三4"));userList.add(new User(25, 167,"张三3"));userList.add(new User(16, 155, "张三8"));userList.sort((o1,o2) ->{if (o1.getAge() > o2.getAge()) {//降序return -1;} else if (o1.getAge() < o2.getAge()) {// 降序return 0;} else {return 0;}});// userList.sort((o1,o2) ->{
// if (o1.getAge() < o2.getAge()) {
// //升序
// return -1;
// } else if (o1.getAge() > o2.getAge()) {
// return 0;
// } else {
// return 0;
// }
//
// });System.out.println("userList = " + userList);}
- 第一个if 中 判断条件表示 年龄 越来越大 但是要返回-1 即交换顺序 所以是降序
- 第二个if中 判断条件表示 年龄 越来越小 返回1 即顺序不变 所以是升序
2. 组合排序
很多时候我们可能并不是只按一个属性进行排序 比如以下要求
- 先按照年龄升序
- 再按照身高降序
public static void main(String[] args) {List<User> userList = new ArrayList<>();userList.add(new User(18, 165,"张三1"));userList.add(new User(16, 177, "张三11"));userList.add(new User(25, 189, "张三4"));userList.add(new User(25, 167,"张三3"));userList.add(new User(16, 155, "张三8"));userList.sort(((o1, o2) -> {//按照年龄升序if (o1.getAge() > o2.getAge()) {//后面的大于前面的数 数越来越大 即升序 所以不需要交换顺序return 1;} else if (o1.getAge() < o2.getAge()) {// 后面的小于前面的数 数越来越小 即降序 但是我们想要升序 所以需要交换顺序 返回-1return -1;} else {//相等时 按照身高降序if (o1.getHigh() > o2.getHigh()) {// 后面的大于前面 即数越来越大 升序 但是我们想要降序 所以返回-1return -1;} else if (o1.getHigh() < o2.getHigh()) {return 1;} else {return 0;}}}));System.out.println("userList = " + userList);}
实战
题目描述
有一串单词组成的英文字符串 需要下面要求进行排序
- 统计每个单词出现的次数,并按次数降序排列;
- 次数相同时,按单词长度升序排列;
3)次数和单词长度均相同时,按字典序升序排列
举例
示例1输入:This is an apple
输出:an is This apple示例2输入 Wisdom in the mind is better than money in the hand
输出in in the the is hand mind than money Wisdom better
代码
public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String originString = scanner.nextLine();//1. 获取全部List<String> list = new ArrayList<>(Arrays.asList(originString.split(" ")));//2. 统计每个单词出现的次数Map<String, Long> countMap = statistic(list);// 3. 排序List<Map.Entry<String, Long>> collect = countMap.entrySet().stream().sorted(((o1, o2) -> {if (o2.getValue() < o1.getValue()) {// 降序return -1;} else if (o1.getValue().equals(o2.getValue())) {if (o2.getKey().length() > o1.getKey().length()) {// 升序 o2是后面那个return -1;} else if (o1.getKey().length() == o2.getKey().length()) {return o1.getKey().compareTo(o2.getKey());}}return 1;})).collect(Collectors.toList());//4. 根据key 和value次数输出结果StringBuilder builder = new StringBuilder();for (Map.Entry<String, Long> entry : collect) {Long value = entry.getValue();String key = entry.getKey();for (int i = 0; i < value.intValue(); i++) {builder.append(key).append(" ");}}System.out.println(builder.substring(0, builder.length() - 1).toString());}private static Map<String, Long> statistic(List<String> list) {Map<String, Long> collect = list.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));return collect;}
我们主要关注第3点 排序那里的代码
参考:
CSDN博主「秃秃爱健身」的原创文章:https://blog.csdn.net/Saintmm/article/details/125218362