Java集合框架之Collections工具类

发布于:2025-03-05 ⋅ 阅读:(12) ⋅ 点赞:(0)

一、Collections工具类

Collections是一个提供对集合对象进行各种操作的静态方法的工具类,包括排序、搜索、线程安全化、同步控制等,Collections 工具类不能被实例化(构造函数私有化)。

Collections和Collection的区别:

  • Collection是接口,提供了对集合对象进行基本操作的通用接口方法,List、Set等多种具体的实现类

  • Collections是工具类,专门操作Collection接口实现类里面的元素

常见方法:

sort(List list):按自然排序的升序排序

sort(List list, Comparator c) :自定义排序规则,由Comparator控制排序逻辑,升序Comparator.naturalOrder()、降序Comparator.reverseOrder()

shuffle(List list):随机排序

reverse(List<?> list): 反转列表中元素的顺序。

max(Collection<? extends T> coll): 根据元素的自然顺序返回集合中的最大元素。

min(Collection<? extends T> coll): 根据元素的自然顺序返回集合中的最小元素。

二、Comparator排序接口

Collections工具类的获取最大元素 max(Collection coll)和获取最小元素 min(Collection coll)不适合对象比较,因为对象有多个属性,无法识别根据哪个属性来判断,需要自己自定义排序规则。

例如max方法:

Collections.max(list, new Comparator<T>() {
            @Override
            public int compare(T o1, T o2) {
                return o1.getXX() - o2.getXX();
            }
        });

假设有个学生类,该学生类有属性姓名、年龄、身高,我们想要比较出哪个学生的年龄最大,我们可以实现一下:

public static void test(){
        List<Student> list = new ArrayList<>();
        list.add(new Student("张三",23,160));
        list.add(new Student("李四",34,180));
        list.add(new Student("王五",28,190));
        list.add(new Student("小熊",16,170));
        System.out.println(Collections.max(list, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                //o1.getAge() 大于 o2.getAge(),那么返回值为正数,表示 o1 应该排在 o2 之后
                //o1.getAge() 小于 o2.getAge(),那么返回值为负数,表示 o1 应该排在 o2 之前
                return o1.getAge()-o2.getAge();
            }
        }));
    }

 运行结果:

Student{name='李四', age=34, height=180}

不止可以比较年龄,也可以实现比较身高的,其他的方法包括sort也可以自定义排序规则。

三、Comparable排序接口

Comparable是一个接口,定制排序规则,对实现它的每个类的对象进行整体排序,里面 compareTo 方法是实现排序的具体方法,String、Integer等类默认实现了这个接口,所以可以排序。

public interface Comparable<T> {
  public int compareTo(T o);
}

compareTo方法:用于比较当前对象和传进来对象的大小,o为要比较的对象

返回int类型:

  • 大于0, 表示this大于传进来的对象o ,则往后排,即升序

  • 等于0,表示this等于传进来的对象o

  • 小于0,表示this小于传进来的对象o

我们实战一下Comparable排序接口!

首先我们要先将Student类去实现一下Comparable接口,并实现Comparable接口的方法,我们比较的是身高属性:

 @Override
    public int compareTo(Student o) {
        return this.getHeight()-o.getHeight();
    }

接着在主函数方法中:

Set<Student> studentSet = new TreeSet<>();
        studentSet.add(new Student("张三", 23, 180));
        studentSet.add(new Student("李四", 34, 160));
        studentSet.add(new Student("王五", 28, 150));
        System.out.println(studentSet);

 打印出来的结果是按照身高的升序来的:

[Student{name='王五', age=28, height=150}, Student{name='李四', age=34, height=160}, Student{name='张三', age=23, height=180}]

那么我们总结一下,如果类的自然排序逻辑就是所需要的排序方式,并且不会改变,那么应该实现Comparable接口。而如果需要为类提供多种排序方式,那么应该使用Comparator。因为Comparator提供了更高的灵活性,它允许为同一个类定义多个不同的排序方式,并且可以用于比较任何对象。

四、JDK之重写HashCode和Equals

HashCode和Equals方法都于集合容器里面的对象比较,是 Object 类中的两个重要方法。

equals方法:默认情况下,Object 类中的 equals() 方法判断的是两个对象是否是同一个对象(即内存地址是否相同)。但在实际开发中,通常需要基于对象的属性值来判断对象是否相等,所以需要重写equals方法。

hashcode方法:

hashCode() 方法返回该对象的哈希码值。在哈希表结构中,hashCode() 用于确定对象的桶位置。

如果两个对象根据 equals(Object) 方法是相等的,调用这两个对象中任一对象的 hashCode 方法都必须产生相同的整数结果

如果两个对象根据 equals(Object) 方法是不相等的,那调用这两个对象中任一对象的 hashCode 方法不一定产生不同的整数(比如一个哈希函数是age%3,那么对于age是6跟9,它们的结果都是0)

 当向集合中插入对象时,如何判别在集合中是否已经存在该对象,比如Set确保存储对象的唯一,并判断是不是同个对象呢?

  • 依据hashCode和equals进行判断,所以Set存储的对象必须重写这两个方法

  • 判断两个对象是否一样,首先判断插入obj的hashcode值是否存在

  • hashcode值不存在则直接插入集合,值存在,比较完hashcode值,则还需判断equals方法判断对象是否相等


网站公告

今日签到

点亮在社区的每一天
去签到