你能说出几种集合的排序方式?

面试回答

Java.util 包中的 List 接口继承了 Collection 接口,用来存放对象集合,所以对这些对象进行排序的时候,要么让对象类自己实现同类对象的比较,要么借助比较器进行比较排序。

举例:学生实体类,包含姓名和年龄属性,比较时先按姓名升序排序,如果姓名相同则按年龄升序排序。

实现 Comparable

第一种:实体类自己实现 Comparable 接口比较。

@Data
@Builder
@ToString
public class Student implements Comparable<Student> {

    private String name;
    private int age;


    @Override
    public int compareTo(Student o) {
        int flag=this.name.compareTo(o.name);
        if (flag==0){
            flag=this.age-o.age;
        }
        return flag;
    }

    public static void main(String[] args) {
        Student stu1=Student.builder().name("bb").age(19).build();
        Student stu2=Student.builder().name("aa").age(19).build();
        Student stu3=Student.builder().name("bb").age(17).build();
        List<Student> list= Arrays.asList(stu1,stu2,stu3);
        for (Student stu:list){
            System.out.println(stu);
        }
        System.out.println("--------------");
        Collections.sort(list);
        for (Student stu:list){
            System.out.println(stu);
        }
    }
    
}

输出如下:

Student(name=bb, age=19)
Student(name=aa, age=19)
Student(name=bb, age=17)
--------------
Student(name=aa, age=19)
Student(name=bb, age=17)
Student(name=bb, age=19)

借助 Comparator

第二种:借助比较器进行排序。

package com.chiyi.test;

import lombok.Builder;
import lombok.Data;
import lombok.ToString;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

@Data
@Builder
@ToString
public class Student  {

    private String name;
    private int age;

    public static void main(String[] args) {
        Student stu1=Student.builder().name("bb").age(19).build();
        Student stu2=Student.builder().name("aa").age(19).build();
        Student stu3=Student.builder().name("bb").age(17).build();
        List<Student> list= Arrays.asList(stu1,stu2,stu3);
        for (Student stu:list){
            System.out.println(stu);
        }
        System.out.println("--------------");
        list.sort(Comparator.comparing(Student::getName)
                .thenComparingInt(Student::getAge));
        for (Student stu:list){
            System.out.println(stu);
        }
    }

}

借助 Stream

第三种:借助 Stream 进行排序,借助 Stream 的 API,底层还是通过 Comparable 实现的。

@Data
@Builder
@ToString
public class Student {

    private String name;
    private int age;

    public static void main(String[] args) {
        Student stu1 = Student.builder().name("bb").age(19).build();
        Student stu2 = Student.builder().name("aa").age(19).build();
        Student stu3 = Student.builder().name("bb").age(17).build();
        List<Student> list = Arrays.asList(stu1, stu2, stu3);
        for (Student stu : list) {
            System.out.println(stu);
        }
        System.out.println("--------------");
        List<Student> list2 = list.stream().sorted((Comparator.comparing(Student::getName)
                .thenComparingInt(Student::getAge))).collect(Collectors.toList());
        for (Student stu : list2) {
            System.out.println(stu);
        }
    }
}

知识扩展

有了 Comparable 为什么还需要 Comparator?

Comparable 用于使某个类具备可排序能力。如之前的 Student 类,实现该接口后覆盖其 compareTo 方法,即可具备可排序的能力。

但是仍然存在一些二方库的类没有实现 Comparable,但是调用方法也需要比较的,此时就需要使用 Comparator 接口。

Comparator 是一个比较器接口,可以用来给不具备排序能力的对象进行排序。如上述代码中对不具备排序能力的 Student 进行排序。

compareTo 和 equals 的使用场景有何区别?

compareTo 常用于排序和 BigDecimal 等数值的比较。

equals 则是常用于业务语义中两个对象是否相同,如 String 常常通过 equals 来比较是否字面意义相同。

既然 Set 是无序的,还怎么排序?

这里说的是两个语境的不同,Set 的无序,指的是插入顺序是无序的。虽然 Set 的插入顺序是无序的,Set 也可以基于 SortedSet 要求对象实现 Comparable 来对 Set 中的元素进行排序。

Set 真的是插入无序的吗?

并不是,Set 有一个实现类是 LinkedHashSet,它引入了 LinkedHashMap,通过双向链表记录了每个 node 的插入顺序和查询顺序(可选),以此来达到 Set 的插入有序性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

协享科技

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值