欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaSE集合 - Collections与集合排序详解

程序员文章站 2022-05-23 15:14:05
...

【1】Collection与Collections

collection接口是list、set和queue接口的父接口。

JavaSE集合 - Collections与集合排序详解

JDK没有提供Collection接口的实现,而是提供了其子接口注入Set、List的实现。


Collection是一个 泛型接口,继承自Iterable<E>:

JavaSE集合 - Collections与集合排序详解


Collections 是一个纯静态类(静态成员变量,静态泛型方法与静态内部类),主要用来对集合进行操作。

JavaSE集合 - Collections与集合排序详解


【2】集合排序两个方法

集合的排序,常常用Collections两个方法:

Collections.sort(songList)

    @SuppressWarnings("unchecked")
    public static <T extends Comparable<? super T>> void sort(List<T> list) {
        list.sort(null);
    }

类型T必须继承Comparable<T>,其中Comparable<? super T>表示Comparable的类型参数必须为T或者T的父型。


② Collections.sort(songList,artistCompare)

    @SuppressWarnings({"unchecked", "rawtypes"})
    public static <T> void sort(List<T> list, Comparator<? super T> c) {
        list.sort(c);
    }

Comparator<? super T> c则表明不需要实现 Comparable<T>接口,但是需要实现Comparator<T>接口。


【3】Comparator<T>与Comparable<T>两个接口

3.1Comparable<T>接口

其只有一个方法compareTo,可以按照自定义规则去实现这个比较方法。

比较结果由 负整数,0,正整数分别表示小于,等于和大于。

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

Song类实现该接口:

public class Song implements Comparable<Song>{
    String title;
    String artist;
    String rating;
    String bpm;

    public int compareTo(Song s){
        return title.compareTo(s.getTile);
    }
    //...
}

Song比较实例:

//...
List<Song> songList = new ArrayList<Song>();
songList.add(song1);
songList.add(song2);
songList.add(song3);

Collections.sort(songList);

3.2Comparator<T>接口

实现该接口的int compare(T o1, T o2)方法:

@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2);
    //...
}

为Song添加内部类AritistCompare:

public class Song implements Comparable<Song>{
    String title;
    String artist;
    String rating;
    String bpm;

    public int compareTo(Song s){
        return title.compareTo(s.getTile);
    }
    class ArtistCompare implements Comparator<Song>{
        public int compare(Song one,Song Two){
            return one.getArtist().compareTo(two.getArtist());
        }
    }
    //...
}

测试方法如下:

ArtistCompare artistCompare = new ArtistCompare();

Collections.sort(songList,artistCompare);

如上所示,Song同时实现了两个接口,那么排序规则怎样的呢?

规则如下:

① 调用单一参数的sort(List<T> 0)方法代表由list元素上的compareTo()方法来决定顺序。因此元素必须实现Comparable接口。

② 调用sort<List<T> o,Comparator<T> c>方法代表不会调用list元素的compareTo()方法,而会使用Comparator的compare()方法。
这意味着list元素不需要实现Comparable接口(即使实现也不使用)。


Tips

此时再看sort<List<T> 0>方法:

    @SuppressWarnings("unchecked")
    public static <T extends Comparable<? super T>> void sort(List<T> list) {
        list.sort(null);
    }

源码示例,T继承自Comparable<? super T>,Comparable显然是个接口,T为具体类的类型(虽然现在不知道 哪种类型,但肯定不是接口)。那么,真是情况应该是实现该接口的具体类型。

这就与extends含义冲突了。。。

JAVA给了一种对参数化类型加上限制的方法,比如某种类型的子类。但也会有需要限制只允许有实现某特定接口的类。因此现在的状况需要对两种情形都能适用的语法—-继承和实现。即 extends和implements。

也就是说,对泛型来讲,extends代表“是一个……”不管是接口或是类都能适用!

即此时的T表明必须是实现Comparable接口的类型!!