Java基础 第三节 第十四课

常用功能

java.util.Collections是集合工具类, 用来对集合进行操作. 部分方法如下:

  • public static <T> boolean addAll(Collection<T> c, T... elements): 往集合中添加一些元素
  • public static void shuffle(List<?> list): 打乱顺集合顺序
  • public static <T> void sort(List<T> list): 将集合中元素按照默认规则排序
  • public static <T> void sort(List<T> list,Comparator<? super T> ): 将集合中元素按照指定规则排序

代码演示:

import java.util.ArrayList;
import java.util.Collections;

public class Test43 {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        // 原来的写法
        //list.add(12);
        //list.add(14);
        //list.add(15);
        //list.add(1000);

        // 采用工具类完成往集合中添加元素
        Collections.addAll(list,6,1,2,3,4,5);
        System.out.println(list);

        // 排序方法
        Collections.sort(list);
        System.out.println(list);
    }
}

输出结果:
[6, 1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 6]

代码演示之后, 发现我们的集合按照顺序进行了排列. 可是这样的顺序是采用默认的顺序, 如果想要指定顺序那该怎么办呢?

我们发现还有个方法没有讲, public static <T> void sort(List<T> list,Comparator<? super T> ): 将集合中元素按照指定规则排序.

Comparator 比较器

我们还是先研究这个方法:

public static <T> void sort(List<T> list,Comparator<? super T> )

不过这次存储的是字符串类型.

import java.util.ArrayList;
import java.util.Collections;

public class Test44 {
    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<>();
        Collections.addAll(arrayList,"cba","abc","sba","nba");
        
        // 排序方法
        Collections.sort(arrayList);
        System.out.println(arrayList);
    }
}

输出结果:
[6, 1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 6]

我们使用的是默认的规则完成字符串的排序, 那么默认规则是怎么定义出来的呢?

说到排序了, 简单的说就是两个对象之间比较大小. 那么在 Java 中提供了两种比较的实现方法, 一种是比较死板的采用java,lang.Comparable接口去实现, 一种是灵活的当我们需要做排序的时候在去选择的java.util.Comparator接口完成.

那么我们采用的public static <T> void sort(List<T> list)这个方法完成的排序, 实际上要求了被排序的类型需要实现 Comparable 接口完成比较的功能. 在 String 类型上如下:

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {

String 类实现了这个接口, 并完成了比较规则的定义, 但是这样就把这种规则写死了. 那比如我想要字符串按照第一个字符降序排列就要修改 String 源代码, 这是不可能的. 那么这个时候我们就可以使用public static <T> void sort(List<T> list,Comparator<? super T> )方法灵活完成. 这个里面就涉及到了 Comparator 这个接口, 位于java.util包下. 排序是 comparator 能实现的功能之一, 该接口代表一个比较器, 比较器具有可比性! 顾明思议就是做排序的, 通俗地讲需要比较两个对象谁排在前面谁排在后面. 那么比较方法就是:

public int compare(String o1, String o2) :

两个对象比较的结果有三种: 大于, 等于, 小于.

如果要按照升序排序, 则 o1 小于 o2, 返回 (负数), 相等返回 0, o1 大于 o2 返回 (正数). 如果按照降序排序, 则 o1 小于 o2, 返回 (正数), 相等返回 0, o1 大于 o2 返回 (负数).

操作如下:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Test {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("cba");
        list.add("aba");
        list.add("sba");
        list.add("nba");

        // 排序方法, 按照第一个单词的降序
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o2.charAt(0) - o1.charAt(0);
            }
        });
        System.out.println(list);
    }
}

调试输出:
[sba, nba, cba, aba]

简述 Compareable 和 Comparator 两个接口的区别

Comparable

Compara: 强行对实现它的每个类的对象进行整体排序. 这种排序被称为类的自然排序, 类的 compareTo 方法被称为它的自然比较方法. 只能在类中实现 compareTo() 一次, 不能经常修改类的代码实现自己想要的排序. 实现此接口的对象列表 (和数组) 可以通过 Collections.sort (和 Arrays.sort) 进行自动排序. 对象可以作有序映射中的键或有序集合中的元素, 无需指定比较器.

Comparator

Comparator: 强行对某个对象进行整体排序. 可以将 Comparator 传递给 sort 方法 ( 如 Collections.sort 或 Arrays.sort ), 从而允许在排序上实现精准控制. 还可以使用 Comparator 来控制某些数据结构 ( 如有序 set 或有序映射 ) 的顺序, 或者为那些没有自然顺序的对象 collection提供排序.

练习

创建一个学生类, 存储到 ArrayList 集合中完成指定排序操作.

Student 初始类

public class Student {
    private String name;
    private int age;
    
    public Student(){
        
    }
    
    public Student(String name, int age){
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

测试类

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Test2 {
    public static void main(String[] args) {
        // 创建四个学生对象
        ArrayList<Student> list = new ArrayList<>();
        list.add(new Student("小泽玛利亚", 19));
        list.add(new Student("武藤兰", 18));
        list.add(new Student("苍井空", 20));
        list.add(new Student("马保国", 69));

        // 按照年龄排序, 升序
        Collections.sort(list);               

        System.out.println(list.toString());
    }
}


当我们调用 Collection.sort() 方法的时候程序报错了.

原因: 如果想要集合中的元素完成排序, 那么必须要实现比较器 Comparable 接口.

于是我们完成了 Student 类的一个实现, 如下:

public class Student implements Comparable<Student>{
    ...
    @Override
    public int compareTo(Student o) {
        // 升序
        return this.age - o.age;
    }
}

再次测试, 代码就 OK 了, 效果如下:

Student{name='武藤兰', age=18}
Student{name='小泽玛利亚', age=19}
Student{name='苍井空', age=20}
Student{name='马保国', age=69}

扩展

如果在使用的时候, 想要独立的定义规则去使用可以采用 Collections.sort(List list, Comparetor c) 方式. 自定义规则:

Collections.sort(list, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o2.getAge() - o1.getAge();  // 以学生的年龄降序
            }
        });

如果想要规则更多一些, 可以参考下面代码:

Collections.sort(list, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                // 年龄降序
                int result = o2.getAge() - o1.getAge();//年龄降序
                if(result == 0){  // 第一个规则判断完了 下一个规则, 姓名的首字母升序
                    result = o1.getName().charAt(0) - o2.getName().charAt(0);
                }
                return result;
            }
        });
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 岁月 设计师:pinMode 返回首页