Java 之 Collections 工具类

一、Collections 概述

  java.utils.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> ):将集合中元素按照指定规则排序。

  Demo:

1 ArrayList<String> list = new ArrayList<>();
2 Collections.addAll(list,"a","b","c","d","e");   // 往集合中添加一些元素。
3 System.out.println(list);//[a, b, c, d, e]
4 Collections.shuffle(list);                             // 打乱集合顺序
5 System.out.println(list);//[b, d, c, a, e], [b, d, c, a, e]

三、sort 方法

  public static <T> void sort(List<T> list) 方法

    该方法将集合中元素按照默认规则排序,默认是升序。

    注意:被排序的集合里边存储的元素,必须实现Comparable,重写接口中的方法compareTo定义排序的规则。

四、Comparator 比较器

  上面使用了 sort() 方法进行的是默认排序,如果想要指定顺序那该怎么办呢?

public static <T> void sort(List<T> list,Comparator<? super T> ):将集合中元素按照指定规则排序。

  首先,先来研究下面的这个方法 

public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。

  Demo:

 1 public class CollectionsDemo2 {
 2     public static void main(String[] args) {
 3         ArrayList<String>  list = new ArrayList<String>();
 4         list.add("cba");
 5         list.add("aba");
 6         list.add("sba");
 7         list.add("nba");
 8         //排序方法
 9         Collections.sort(list);
10         System.out.println(list);
11     }
12 }
13 结果:[aba, cba, nba, sba]

  通过上面的Demo可以看出使用的默认规则完成字符串的排序,那么默认规则是如何定义出来的呢?

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

  上面我们存放的是一个 String 类,打开String类型如下:

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

  我们发现 String 类实现了这个接口,并完成了比较规则的定义,但是这样就把规则写死了,如果想按照第一个字符降序排列,这就需要修改 String 的源代码,但是这是不可能的,这时我们就可以使用 comparator 接口来实现。

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

  Comparator 这个接口,位于 java.util 包下面,排序是 comparator 能实现的功能之一,该接口代表一个比较器,比较器具有可比性。

  下面看一下这个比较的方法:

1  public int compare(String o1, String o2)`:比较其两个参数的顺序。
2 
3  两个对象比较的结果有三种:大于,等于,小于。
4 
5  如果要按照升序排序,
6  则o1 小于o2,返回(负数),相等返回0,01大于02返回(正数)
7  如果要按照降序排序
8  则o1 小于o2,返回(正数),相等返回0,01大于02返回(负数)

  Demo:按第一个单词降序

 1 public class CollectionsDemo3 {
 2     public static void main(String[] args) {
 3         ArrayList<String> list = new ArrayList<String>();
 4         list.add("cba");
 5         list.add("aba");
 6         list.add("sba");
 7         list.add("nba");
 8         //排序方法  按照第一个单词的降序
 9         Collections.sort(list, new Comparator<String>() {
10             @Override
11             public int compare(String o1, String o2) {
12                 return o2.charAt(0) - o1.charAt(0);
13             }
14         });
15         System.out.println(list);
16     }
17 }
18 结果:[sba, nba, cba, aba]

五、Comparable 和 Comparator 两个接口的区别

  Comparable:

    强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compaetTo 方法被称为她的自然比较方法。

    只能在类中实现 compareTo() 一次,不能经常修改类的代码实现自己想要的排序,实现此接口的对象列表(和数组)可以通过 Collection.sort (和 Arrays.sort)进行自动排序,对象可以用作有序映射中的键或有序集合中的元素,无序指定比较器。

  comparator:

    强行对某个对象进行整体排序。可以将 Comparator 传递给 sort 方法(如Collection.sort 或 Array.sort),从而允许在排序上实现精确控制。

    还可以使用 Comparator 来控制某些数据结构(如有序 set 或有序的映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。

  Demo:

 1 // 自定义 Student 类
 2 public class Student{
 3     private String name;
 4     private int age;
 5 
 6     public Student() {
 7     }
 8 
 9     public Student(String name, int age) {
10         this.name = name;
11         this.age = age;
12     }
13 
14     public String getName() {
15         return name;
16     }
17 
18     public void setName(String name) {
19         this.name = name;
20     }
21 
22     public int getAge() {
23         return age;
24     }
25 
26     public void setAge(int age) {
27         this.age = age;
28     }
29 
30     @Override
31     public String toString() {
32         return "Student{" +
33                "name='" + name + '\'' +
34                ", age=" + age +
35                '}';
36     }
37 }
View Code

  

  测试类

 1 public class Demo {
 2 
 3     public static void main(String[] args) {
 4         // 创建四个学生对象 存储到集合中
 5         ArrayList<Student> list = new ArrayList<Student>();
 6 
 7         list.add(new Student("rose",18));
 8         list.add(new Student("jack",16));
 9         list.add(new Student("abc",16));
10         list.add(new Student("ace",17));
11         list.add(new Student("mark",16));
12 
13 
14         /*
15           让学生 按照年龄排序 升序
16          */
17 //        Collections.sort(list);//要求 该list中元素类型  必须实现比较器Comparable接口
18 
19 
20         for (Student student : list) {
21             System.out.println(student);
22         }
23 
24 
25     }
26 }
View Code

  这个时候发现调用 Collections.sort()方法的时候 程序报错了。

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

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

  再补充上面的代码后,就 OK了。

  

  当然了,如果在使用的时候,想要独立的定义规则去使用 可以采用Collections.sort(List list,Comparetor<T> 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;
            }
        });

  

总结:

  对于自定义的类型来说,如果想要调用 Collections.sort() 或 Arrays.sort() 方法时,必须指定一个比较器。

  1、在当前类中 实现 Comparable 接口,重写其中的 compareTo() 方法,在方法里面指定比较方式。

  2、在调用 sort() 方法的时候,在第二个参数的位置,new Comparor 对象,然后重写 compare 方法

 

  

 

猜你喜欢

转载自www.cnblogs.com/niujifei/p/11440555.html