• 泛型1


    ArrayList中的元素可以重复,ArrayList没有排序方法,要借助Collections中的sort()方法排序。

    例如:

     1 import java.util.*;
     2 import java.io.*;
     3 
     4 public class Jukebox1{
     5     
     6     ArrayList<String> songList = new ArrayList<String>();
     7     
     8     public static void main(String[] args){
     9         new Jukebox1().go();
    10     }
    11     
    12     public void go(){
    13         getSongs();
    14         System.out.println(songList);
    15     }
    16     
    17     void getSongs(){
    18         try{
    19             File file = new File("SongList.txt");
    20             BufferedReader reader = new BufferedReader(new FileReader(file));
    21             String line = null;
    22             while((line = reader.readLine()) != null){
    23                 addSong(line);
    24             }
    25         }catch(Exception e){
    26             e.printStackTrace();
    27         }
    28     }
    29     
    30     void addSong(String lineToParse){
    31         String[] tokens = lineToParse.split("/");
    32         songList.add(tokens[0]);
    33     }
    34 }
    View Code

    上面代码可以将SongList.txt文件中的元素按照歌名排序,并输出。

    排序方法是:Collections.sort(songList);//借助Collections的sort()方法将songList排序

    输出:System.out.println(songList);//String类中toString()方法重写,所以可以输出歌名。

    将上述代码文件和SongList.txt文件放在同一个文件夹下,SongList.txt文件内容如下:

    Communication/The Cardigans

    Black Dog/Led Zeppelin

    Dreams/Van Halen

    Comfortably Numb/Pink Floyd

    Beth/Kiss

    倒退噜/黄克林

    上面文件内容,/前面是歌名,/后面是歌手名。

    ArrayList<Stirng> songList = new ArrayList<String>();//没有问题,可以借助Collections的sort()方法排序。

    如果使用我们自己创建的类类型会怎样?

    ArrayList<Song> songList = new ArrayList<Song>();

    Song类定义如下:

     1 class Song {
     2     String title;//歌名
     3     String artist;//作者
     4     String rating;
     5     String bpm;
     6     
     7     Song(String t, String a, String r, String b){
     8         title = t;
     9         artist = a;
    10         rating = r;
    11         bpm = b;
    12     }
    13     
    14     public String getTitle(){
    15         return title;
    16     }
    17     
    18     public String getArtist(){
    19         return artist;
    20     }
    21     
    22     public String getRating(){
    23         return rating;
    24     }
    25     
    26     public String getBpm(){
    27         return bpm;
    28     }
    29     
    30     public String toString(){
    31         return title;
    32     }
    33 }
    View Code

    对ArrayList<Song> songList进行排序的代码如下:

     1 import java.util.*;
     2 import java.io.*;
     3 
     4 public class Jukebox3{
     5     
     6     ArrayList<Song> songList = new ArrayList<Song>();
     7     
     8     public static void main(String[] args){
     9         new Jukebox3().go();
    10     }
    11     
    12     public void go(){
    13         getSongs();
    14         System.out.println(songList);
    15         Collections.sort(songList);
    16         System.out.println(songList);
    17     }
    18     
    19     void getSongs(){
    20         try{
    21             File file = new File("SongList1.txt");
    22             BufferedReader reader = new BufferedReader(new FileReader(file));
    23             String line = null;
    24             while((line = reader.readLine()) != null){
    25                 addSong(line);
    26             }
    27         }catch(Exception e){
    28             e.printStackTrace();
    29         }
    30     }
    31     
    32     void addSong(String lineToParse){
    33         String[] tokens = lineToParse.split("/");
    34         
    35         Song nextSong = new Song(tokens[0], tokens[1], tokens[2], tokens[3]);
    36         songList.add(nextSong);
    37     }
    38 }
    View Code

    SongList1.txt文件如下:

    Communication/The Cardigans/5/80
    Black Dog/Led Zeppelin/4/84
    Dreams/Van Halen/6/120
    Comfortably Numb/Pink Floyd/5/110
    Beth/Kiss/4/100
    倒退噜/黄克林/5/90

    编译之后会报错:

    ArrayList<String> 和 ArrayList<Song>有什么差异呢?

    从API说明文件找到java.util.Collections下的sort():

                                                                                                     图1

    看不懂了吧?别急,作为初学者,我也看不懂,慢慢来。 这里还有一个:

                                                                                                     图2

    我们定义一个ArrayList如下:

    ArrayList<String> songList = new ArrayList<String>();

    ArrayList前后尖括号中的内容要一样,这就相当于告诉编译器,SongList这个ArrayList中能存储String类类型。就是这么简单。

    图1:一步一步看

    <T extends Comparable<? super T>>

    T extends Comparable 表明T必须Comparable,这个字很重要。

    <? super T> 代表Comparable的类型参数必须是T或T的父类型。

    void sort(List<T> list)

    List<T>:仅能传入Comparable的参数化类型的list

                                                                               图3

    图3查看String说明,String并没有extends(继承)Comparable,只是implements(实现)Comparable。

    所以上面的字很重要,以泛型的观点来说,extend代表extend或implement。

    因此String类implement(实现)Comparable,就相当于泛型中extend(继承)Comparable。

    于是乎,我们就想到,我们的Song类没有extend也没有implement过Comparable。所以编译器翻脸不认人,ArrayList<Song> songList就不能使用Collections.sort()

    下面,我们想办法,怎么让Collections.sort()认可我们的Song类,查看Comparable:

                                                                                图4

    Comparable<T>原来是接口,再看它中的方法:

                                                                                 图5

    只有comareTo()一个方法,这就好办,让我们的Song类implement(实现)Comparable:

     1 class Song implements Comparable<Song>{
     2     String title;
     3     String artist;
     4     String rating;
     5     String bpm;
     6     
     7     //比较两个title大小
     8     public int compareTo(Song s){
     9         return title.compareTo(s.getTitle());
    10     }
    11     
    12     Song(String t, String a, String r, String b){
    13         title = t;
    14         artist = a;
    15         rating = r;
    16         bpm = b;
    17     }
    18     
    19     public String getTitle(){
    20         return title;
    21     }
    22     
    23     public String getArtist(){
    24         return artist;
    25     }
    26     
    27     public String getRating(){
    28         return rating;
    29     }
    30     
    31     public String getBpm(){
    32         return bpm;
    33     }
    34     
    35     public String toString(){
    36         return title;
    37     }
    38 }
    View Code

    运行结果:

    程序修改成功,我们再讲解一下运用泛型的方法:

    1.使用定义在类声明的类型参数,简单来说就是,把泛型定义在class上:

    public class ArrayList<E> extends AbstractList<E> ...{//这个是图2中的内容,可以查看API,里面有一个add()方法

        public bolean add(E o)

    }

    这表明,在ArrayList<String> songList = new ArrayList<String>();//这里已经把上面的E替换成了String类类型。

    songList.add(a);//这里的a必须是String类类型,即声明String a;,否则编译器会报错。

    2.使用为定义在类声明的类型参数,换句话说,除了上面定义在类上的泛型以外,其他的都是。比如:

    定义在方法上的泛型:

    public <T extends Animal> void takeThing(ArrayList<T> list)//如果类本身没有使用泛型参数,我们可以在返回类型之前指定泛型

    <T extends Animal>,我们的老朋友又和我们见面了,只要是extend或implement过的T都可以。

    如果Animal是类,Animal,和extend它的子类(Dog,Cat...),甚至如果Animal是接口,那么implement它的类都可以。

    在泛型中什么时候用E,什么时候用T?

    这个问题的回答是甲鱼的臀部-——龟腚(规定)。习惯的用法除了与集合有关的用E(表示element元素),其余都用T,就这么简单。

    说完了。

    有个问题,public <T extends Animal> void takeThing(ArrayList<T> list) 和 public void takeThing(ArrayList<Animal> list)有什么区别?

    第一个就不说了,第二个代表只有传入ArrayList<Animal>的变量是合法的,传入ArrayList<Dog>的变量是非法的。

    OVER!

  • 相关阅读:
    html5基础知识------全局属性
    css3盒模型 box-sizing
    AFO
    关于线段树的一个模板
    从头整理一下
    搜索?
    一些好的文章
    网络流初步学习之最大流
    NOIP2014 D1T3 [洛谷P1941] 飞扬的小鸟
    [洛谷P5259] 游戏中的学问
  • 原文地址:https://www.cnblogs.com/lanshanxiao/p/7170796.html
Copyright © 2020-2023  润新知