笔记--java sort() 方法排序

背景


最近在刷一道算法题 《字符串重新排序》时,发现自己有思路但是写代码的时候就无从下手了 而且看了答案之后还没看懂 关键就是基础不好 对于排序没有理解(虽然我学过常用的排序算法 但是都是理念 实践少)

目的


从实践和原理出发 重点是从实践出发 探讨如何使用 sort()方法 完成复杂的排序

能掌握到的知识

  1. 了解compaer(O1 ,O2) 中 返回1 -1 0 这三个什么意思 并且如何使用这三个值达到自己想要的排序
  2. 如何实现组合排序 即满足排序1情况下进行排序2

目录

  1. sort() 方法 简介
  2. sort() 方法使用
  3. 实战

sort()方法简介


sort()方法有很多种

  1. Arrays.sort()
    在这里插入图片描述
  2. 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. 三个数代表的意思
    • 1:代表保持原样
    • 0:代表保持原样
    • -1:需要交换顺序
  2. 在排序前 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);
    }
  1. 第一个if 中 判断条件表示 年龄 越来越大 但是要返回-1 即交换顺序 所以是降序
  2. 第二个if中 判断条件表示 年龄 越来越小 返回1 即顺序不变 所以是升序
2. 组合排序

很多时候我们可能并不是只按一个属性进行排序 比如以下要求

  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()) {
                // 后面的小于前面的数 数越来越小 即降序 但是我们想要升序 所以需要交换顺序 返回-1
                return -1;
            } else {
                //相等时 按照身高降序
                if (o1.getHigh() > o2.getHigh()) {
                    // 后面的大于前面 即数越来越大 升序 但是我们想要降序 所以返回-1
                    return -1;

                } else if (o1.getHigh() < o2.getHigh()) {
                    return 1;
                } else {
                    return 0;
                }
            }
        }));


        System.out.println("userList = " + userList);
    }

实战


题目描述
有一串单词组成的英文字符串 需要下面要求进行排序

  1. 统计每个单词出现的次数,并按次数降序排列;
  2. 次数相同时,按单词长度升序排列;
    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

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很好的问题!让我来解答。 首先,让我们来了解一下 `Comparable` 接口。这个接口是 Java 中的一个接口,它只有一个方法 `compareTo()`。这个方法的作用是定义类的自然排序顺序。 如果我们要对一个对象集合进行排序,只需要让这个类实现 `Comparable` 接口,并且重写 `compareTo()` 方法。这个方法返回一个整型值,表示该对象与另一个对象的大小关系。如果该对象小于另一个对象,则返回负整数;如果两个对象相等,则返回零;如果该对象大于另一个对象,则返回正整数。 下面是一个简单的例子,展示如何使用 `Comparable` 接口进行排序。 ```java public class Student implements Comparable<Student> { private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } // 重写 compareTo 方法 @Override public int compareTo(Student o) { // 按照年龄从小到大排序 return this.age - o.getAge(); } } ``` 在这个例子中,我们定义了一个 `Student` 类,并且让它实现了 `Comparable` 接口。我们重写了 `compareTo()` 方法,按照年龄从小到大排序。 现在,我们可以使用 `Collections.sort()` 方法对 `Student` 对象进行排序了: ```java List<Student> students = new ArrayList<>(); students.add(new Student("Tom", 20)); students.add(new Student("Jerry", 18)); students.add(new Student("Alice", 22)); Collections.sort(students); for (Student student : students) { System.out.println(student.getName() + " " + student.getAge()); } ``` 输出结果为: ``` Jerry 18 Tom 20 Alice 22 ``` 可以看到,我们成功地按照年龄从小到大对 `Student` 对象进行了排序。 希望这个例子能够帮助你理解如何使用 `Comparable` 接口进行排序。如果你还有其他问题,请随时提出!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值