黑马程序员_集合总篇_基础之重点

------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

为什么出现集合类?

面向对象语言对事物的体现都是以对象的形式,所以为了方便对多 个对象的操作,就对对象进行存储,集合就是存储对象常用的一 种方式。

数组和集合类同是容器,有何不同?

数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。 数组中可以存储基本数据类型,集合只能存储对象。

集合类的特点

集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象

集合体系



Collection

Collection是集合框架中常用的接口,旗下有两个子接口:List(列表)和Set(集)

List:可存放重复元素,元素取出和存入的顺序是一致的

Set:不可以存放重复元素,元素的取出和存入的顺序不一定一致

一、Collection 接口中常用的方法

        1、添加

1、all(E e)          //E暂时可以看作是Object   可以添加任意类型

2、addAll(Collection collection)           将指定集合中的元素添加到该集合中

        2、删除

1、remove(E   e)        //删除指定元素

2、remove(Collection   collection)   //去交集   ,也就是该集合中会保留指定集合中没有的元素,如果指定集合中的元素与该集合中的元素完全相同,那么该集合将为NULL

3、clear()                 //删除集合中的所有元素

        3、判断

1、contains(E    e)      //判断指定元素是否存在

2、isEmpty();            //判断集合是否为NUll     其实就是在判断size()是否为0

        4、获取

1、size()            //获取集合的长度

2、iterator()      迭代器,用于获取集合中的每个元素  和for循环原理相同

二、迭代器

1、什么是迭代器?

        迭代器其实就是集合中取出元素的方式  如:DNF中的娃娃机

2、对于迭代器取出元素的动作:

       当不足以用一个函数来描述,需要多个功能来体现时,所以就将取出这个动作封装成了一个对象,用对象来进行描述,所以就把取出方式定义在集合内部,这样取出方式就可以直接访问集合中的元素,那么取出方式就被定义成了内部类。

       因为每个容器的数据结构不同,所以取出的动作和细节也不一样,但是都有共性的内容:判断和取出,那么可以将这些共性进行抽取,那么该类就就都符合一个规则,该规则就是Iterator接口,而想要获取集合中取出的对象,可以通过一个对外提供的方法iterator()来获取

3、迭代常用方法

        1、next()                       取出一个元素

        2、hasNext()                判断是否还有元素   返回一个boolean类型的结果

        3、remove()                 删除当前元素

       注意:想要将集合中的元素全部取出,必须使用循环每取一次(next()),判断一次(hasNext())  知道hasNext为false,结束循环

4、迭代用法:

[java]  view plain copy print ?
  1.         <span style="font-size:14px;">      ArrayList al1 = new ArrayList();  
  2. al1.add("java01");  
  3. al1.add("java02");  
  4. al1.add("java03");  
  5. al1.add("java04");  
  6. //第一种用法  
  7. Iterator it = all.iterator();  
  8. while(it.hasNext()){  
  9.     System.out.println(it.next());  
  10. }  
  11. //第二种用法  
  12. for(Iterator it = all.iterator();it.hasNext();){  
  13.     System.out.prinln(it.next());  
  14. }</span>  
注意:iterator是Collection接口中的方法,所以每一个子类集合对象多具备迭代器

5、使用迭代注意事项

1、  迭代器在Collection接口中是通用的,它替代了Vector类中中的枚举

2、迭代器的next方法是自动向下取元素,但是一个循环中不可以出现多个next,要避免出现NoSuchElementException异常

3、迭代器的next方法返回值类型是Object,所以应注意转换

问题:为什么迭代器的next方法的返回值类型是Object呢?

        原因:因为集合中可以存储的类型只能是对象(String、int都是对象),所以返回值一定是对象的祖先Object



List

Collection
    |--List:元素是有序的,元素可以重复。因为该集合体系有索引。
        |--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。   底层使用的都是可变数组,每次加长50%
        |--LinkedList:底层使用的链表数据结构。特点:增删速度很快,查询稍慢。线程不同步。
        |--Vector:底层是数组数据结构。线程同步。被ArrayList替代了。因为效率低。  底层使用的都是可变数组,每次加长100%

虽然Vector已经被ArrayList替代了,但是它里面有一些特殊的方法是ArrayList没有的,就是枚举,其实枚举和迭代的原理是一样的,但是后面学习IO时可能会用到枚举,所以还是说一下Vector把

Vector中特有的方法:

1、elements()       //相当于iterator()

2、hasMoreElements()       相当于hasNext(0

3、nextElement()     //相当于next()

[java]  view plain copy print ?
  1. <span style="font-size:14px;">import java.util.*;  
  2. class VectorDemo   
  3. {  
  4.     public static void main(String[] args)   
  5.     {  
  6.         Vector v = new Vector();  
  7.   
  8.         v.add("java01");  
  9.         v.add("java02");  
  10.         v.add("java03");  
  11.         v.add("java04");  
  12.   
  13.         Enumeration en = v.elements();    //elements返回值类型为Enumeration类  
  14.   
  15.         while(en.hasMoreElements())  
  16.         {  
  17.             System.out.println(en.nextElement());  
  18.         }  
  19.     }  
  20. }</span>  

一、List中特有的方法

只要是可以操作角标的方法都是List集合中特有的方法,因为List集合有索引

1、增

       add(int  index)

       add(int  index, Collection  collection)

2、删

       remove(int index)

3、改

       set(int  index)

4、查

       get(index)

       subList(头,  尾)

       indexOf(int  index)

       lastIndexOf(int index)

       listIterator()                        //注:有点特殊

二、listIterator方法

1、用法:listIterator方法的用法和iterator方法的用法相同,只不过listIterator的返回值类型为ListIterator,是 Iterator的一个子接口,而 iterator方法返回值类型为Iterator接口

2、listIterator和iterator的区别:

            因为iterator方法返回的结果是Iterator ,而Iterator接口中仅仅只有对元素的删除操作,所以当使用Iterator是不可以对元素进行出删除操作之外的操作的,有局限性,而ListIterator类中定义了很多对元素操作的方法,所以当需要多元素进行删除以外的操作时,建议使用Iterator的子接口ListIterator中的listIterator方法获取

3、ListIterator特有方法

        1、get()

        2、add()

        3、hasPrevious()          判断前面是否还有元素

        4、previous()                 向前获取元素

        5、set(Object obj);

LinkedList

一、LinkedList特有方法

1、增       

        addFirst();

        addLast();

2、删          注:使用该方法时,该方法不仅会删除元素,还会返回要删除的元素  如果集合为空  则会出现NoSuchElementException

        removeFrist()

        removeLast()

3、获取      注:使用该方法时,该方法只会获取元素,不会删除元素   如果集合为空  则会出现NoSuchElementException

        getFirst();

        getLst()

JDK1.6以后,出现了替代方法。

1、增

        offFirst();

        offLast();

2、获取

        //获取元素,但是不删除。如果集合中没有元素,会返回null

        peekFirst();

        peekLast();

3、删

        //获取元素,并删除元素。如果集合中没有元素,会返回null

        pollFirst();

        pollLast();

4、练习1:
[java]  view plain copy print ?
  1. <span style="font-size:14px;">/* 
  2. 需求:模拟一个堆栈和队列数据结构 
  3. 堆栈:先进后出   如同一个杯子 
  4. 队列:先进先出   如同一个管子 
  5. */  
  6. class DemoTest   
  7. {  
  8.   
  9.     private LinkedList link;  
  10.     //初始化一个LinkedList集合  
  11.     DemoTest(){  
  12.         this.link = new LinkedList();  
  13.     }  
  14.     //自己内部完成添加  
  15.     public void myAdd(Object obj){  
  16.         link.addFrist(obj);  
  17.     }  
  18.     //堆栈  
  19.     public void getDuiZhan(){  
  20.         while(!link.isEmpty()){  
  21.             System.out.println(link.removeFirst());  
  22.         }  
  23.     }  
  24.     //队列  
  25.     public void getDuiLie(){  
  26.         while(!link.isEmpty()){  
  27.             System.out.println(link.removeLast());  
  28.         }  
  29.     }  
  30. }  
  31.   
  32. public class Test {  
  33.     public static void main(String [] agrs){  
  34.         DemoTest de = new DemoTest();  
  35.         de.myAdd("lisi01");  
  36.         de.myAdd("lisi02");  
  37.         de.myAdd("lisi03");  
  38.         de.myAdd("lisi04");  
  39.         de.myAdd("lisi05");  
  40.         //输出队列  
  41.         de.getDuiLie();  
  42.         //输出堆栈  
  43.         de.getDuiZhan();  
  44.     }  
  45. }  
  46. </span>  
5、练习2:去除Arraylist中的重复元素
[java]  view plain copy print ?
  1. <span style="font-size:14px;">/* 
  2. 需求:去除List集合中的重复元素 
  3. */  
  4. class ListUtil  
  5. {  
  6.     //消除重复值后输出  
  7.     public static void get(List li){  
  8.         for(Iterator it = contains(li).iterator();it.hasNext();){  
  9.             System.out.println(it.next());  
  10.         }  
  11.     }  
  12.     //把重复元素清除后添加到一个新的List集合中  
  13.     private static List contains(List li){  
  14.         List list = new ArrayList();  
  15.         for(Iterator it = li.iterator();it.hasNext();){  
  16.             Object obj = it.next();  
  17.             if(!list.contains(obj))  
  18.                 list.add(obj);  
  19.         }  
  20.         return list;  
  21.     }  
  22. }  
  23.   
  24. public class DemoTest {  
  25.     public static void main(String [] args){  
  26.         LinkedList list = new LinkedList();  
  27.         list.add("li001");  
  28.         list.add("li001");  
  29.         list.add("li003");  
  30.         list.add("li002");  
  31.         list.add("li005");  
  32.         list.add("li002");  
  33.         ListUtil.get(list);  
  34.     }  
  35. }  
  36. </span>  

6、练习3、去除集合中的重复对象

[java]  view plain copy print ?
  1. <span style="font-size:14px;">import java.util.*;  
  2. class Person  
  3. {  
  4.     private String name;  
  5.     private int age;  
  6.     Person(String name,int age)  
  7.     {  
  8.         this.name = name;  
  9.         this.age = age;  
  10.     }     
  11.     /*这里必须复写equals方法*/  
  12.     public boolean equals(Object obj)  
  13.     {  
  14.         //用于判断equals方法是否执行  
  15.         System.out.println("??????????");  
  16.         if(!(obj instanceof Person))  
  17.             return false;  
  18.         Person p = (Person)obj;  
  19.                 //这里只要是名字和年龄相同就认为是同一个人  
  20.         return this.name.equals(p.name) && this.age == p.age;  
  21.     }  
  22.     public String getName()  
  23.     {  
  24.         return name;  
  25.     }  
  26.     public int getAge()  
  27.     {  
  28.         return age;  
  29.     }  
  30. }  
  31. class DemoTest3   
  32. {  
  33.     public static void sop(Object obj)  
  34.     {  
  35.         System.out.println(obj);  
  36.     }  
  37.     public static void main(String[] args)   
  38.     {  
  39.         ArrayList set = new ArrayList();  
  40.         //Set set = new HashSet();  
  41.         set.add(new Person("lisi01",30));//al.add(Object obj);//Object obj = new Person("lisi01",30);  
  42.         set.add(new Person("lisi02",32));  
  43.         set.add(new Person("lisi02",32));  
  44.         set.add(new Person("lisi04",35));  
  45.         set.add(new Person("lisi03",33));  
  46.         set.add(new Person("lisi04",35));         
  47.         /*发现在Person类中复写了equals方法之后,并没有去除重复对象,这是为什么呢? 
  48.         我们都知道对象比较的是equals方法,为什么我们复写了equals方法还是不行呢? 
  49.         因为如果我们在equals方法中打印输出一条语句的话,我们就会发现该语句根本就没有执行? 
  50.         这又是为什么呢?这就说明计算机底层并没有帮我们调用我们复写的equals方法 
  51.         而不执行equals方法肯定是去除不掉重复对象的,所以这时候我们最大的问题应该是调用equals 
  52.         方法,只要执行了equal方法那么肯定能去除重复对象,所以,这时候我们contain方法来解决 
  53.         因为contains方法底层用的都是equals方法,我们调用了contains不就等于调用了equals方法么? 
  54.         所以,我们可以先用contain判断一下,把不存在的值放入到一个新容器中,所以就有了singleElement方法*/  
  55.         set = singleElement(set);  
  56.         for(Iterator it = set.iterator();it.hasNext();){  
  57.             Person p = (Person) it.next();  
  58.             System.out.println(p.getName()+"...."+p.getAge());  
  59.         }  
  60.     }  
  61.   
  62.   
  63.     public static ArrayList singleElement(ArrayList al)  
  64.     {  
  65.         //定义一个临时容器。  
  66.         ArrayList newAl = new ArrayList();  
  67.   
  68.         Iterator it = al.iterator();  
  69.   
  70.         while(it.hasNext())  
  71.         {  
  72.             Object obj = it.next();  
  73.   
  74.             if(!newAl.contains(obj))  
  75.                 newAl.add(obj);  
  76.   
  77.         }  
  78.   
  79.         return newAl;  
  80.     }  
  81. }</span>  

Set

Set:无序,不可以重复元素。
    |--HashSet:数据结构是哈希表。线程是非同步的。
                保证元素唯一性的原理:判断元素的hashCode值是否相同。
                如果相同,还会继续判断元素的equals方法,是否为true。

    |--TreeSet:可以对Set集合中的元素进行排序。
                底层数据结构是二叉树。
                保证元素唯一性的依据:
                compareTo方法return 0.

                TreeSet排序的第一种方式:让元素自身具备比较性。
                元素需要实现Comparable接口,覆盖compareTo方法。
                也种方式也成为元素的自然顺序,或者叫做默认顺序。

                TreeSet的第二种排序方式。
                当元素自身不具备比较性时,或者具备的比较性不是所需要的。
                这时就需要让集合自身具备比较性。
                在集合初始化时,就有了比较方式。

注:Set接口中的方法和Collection接口中的方法是一样的,所以在使用Set子类时获取元素时,只能通过迭代的方式

HashSet

注:HashSet对于判断元素是否存在,以及删除等操作,依赖的方法都是元素的hashCode方法和equals方法

练习:去除HashSet中的重复对象

[java]  view plain copy print ?
  1. /*需求:消除HashSet中的重复对象*/  
  2. import java.util.*;  
  3. class Person  
  4. {  
  5.     private String name;  
  6.     private int age;  
  7.     public Person(String name,int age){  
  8.         this.name = name;  
  9.         this.age = age;  
  10.     }  
  11.     public String getName(){  
  12.         return name;  
  13.     }  
  14.     public int getAge(){  
  15.         return age;  
  16.     }  
  17.     //重写Object类中的hashCode方法  
  18.     public int hashCode(){  
  19.         //这样写能尽可能的保证哈希值唯一  
  20.         return this.name.hashCode()+age*24;  
  21.     }  
  22.     //重写Object类中的equals方法  
  23.     public boolean equals(Object obj){  
  24.         if(!(obj instanceof Person))  
  25.             throw new RuntimeException();  
  26.         Person p = (Person) obj;  
  27.         return this.name.equals(p.name);  
  28.     }  
  29. }  
  30. public class HashSetDemo   
  31. {  
  32.     public static void main(String[] args)   
  33.     {  
  34.         Set set = new HashSet();  
  35.         set.add(new Person("li01",21));  
  36.         set.add(new Person("li01",21));  
  37.         set.add(new Person("li02",21));  
  38.         set.add(new Person("li03",21));  
  39.         set.add(new Person("li05",21));  
  40.         set.add(new Person("li02",21));  
  41.         for(Iterator it = set.iterator(); it.hasNext();){  
  42.             Person p = (Person) it.next();  
  43.             System.out.println(p.getName()+":"+p.getAge());  
  44.         }  
  45.     }  
  46. }  

TreeSet

特点:

可对Set集合中的元素进行排序,是因为:TreeSet类实现了Comparable接口,该接口强制让增加到集合中的对象进行了比较,需要复写compareTo方法,才能让对象按指定需求(如人的年龄大小比较等)进行排序,并加入集合。

        java中的很多类都具备比较性,其实就是实现了Comparable接口。

注意:排序时,当主要条件相同时,按次要条件排序。  

二叉树示例图:

二叉树原理:通过compareTo方法的返回值,是正整数、负整数或零,则两个对象较大、较小或相同。根据返回值来存放,正数则放在右边,负数这放在左边,0则证明相等,不存入

2Tree排序的两种方式   当自然排序和比较器同时存在时,以比较器为主

        1)第一种排序方式:自然排序

        让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。这种方式也被称为元素的自然顺序,或者叫做默认顺序。

示例:

[java]  view plain copy print ?
  1. /* 
  2. TreeSet自然排序 
  3. */  
  4.   
  5. import java.util.*;  
  6. class Person implements Comparable  
  7. {  
  8.     private String name;  
  9.     private int age;  
  10.     public Person(String name,int age){  
  11.         this.name = name;  
  12.         this.age = age;  
  13.     }  
  14.     public String getName(){  
  15.         return name;  
  16.     }  
  17.     public int getAge(){  
  18.         return age;  
  19.     }  
  20.     //重写comepareTo()方法让对象具备比较性  
  21.     public int compareTo(Object obj){  
  22.         if(!(obj instanceof Person))  
  23.             throw new RuntimeException();  
  24.         Person p = (Person) obj;  
  25.         //让对象先按姓名排序后如果姓名相同再按年龄排序  
  26.         int num = this.name.compareTo(p.name);  
  27.         if(num==0)  
  28.             return this.age - p.age;  
  29.         //  return new Integer(this.age).compareTo(new Integer(p.age))  
  30.         return num;  
  31.     }  
  32. }  
  33. public class TreeSetDemo   
  34. {  
  35.     public static void main(String[] args)   
  36.     {  
  37.         Set set1 = new TreeSet();  
  38.         set1.add(new Person("li01dfds————",23));  
  39.         set1.add(new Person("li01dsfs————",21));  
  40.         set1.add(new Person("li02assa————",24));  
  41.         set1.add(new Person("li03fdds————",20));  
  42.         set1.add(new Person("li05asf————",19));  
  43.         set1.add(new Person("li02sdfs————",21));  
  44.         show(set1);  
  45.   
  46.     }  
  47.     public static void show(Set set){  
  48.         for(Iterator it = set.iterator(); it.hasNext();){  
  49.             Person p = (Person) it.next();  
  50.             System.out.println(p.getName()+":"+p.getAge());  
  51.         }  
  52.     }  
  53. }  

        2)第二种方式:比较器

        当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。

        在集合初始化时,就有了比较方式。定义一个比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。

        比较器构造方式:定义一个类,实现Comparator接口,覆盖compare方法。创建一个带有Comparator对象的构造函数

        当两种排序都存在时,以比较器为主。

示例:

[java]  view plain copy print ?
  1. /*比较器*/  
  2. public class TreeSetDemo   
  3. {  
  4.     public static void main(String[] args)   
  5.     {  
  6.         Set set1 = new TreeSet(new Com());  
  7.         set1.add(new Person("li04————",23));  
  8.         set1.add(new Person("li02————",21));  
  9.         set1.add(new Person("li00————",24));  
  10.         set1.add(new Person("li03————",20));  
  11.         set1.add(new Person("li05————",19));  
  12.         set1.add(new Person("li01————",21));  
  13.         show(set1);  
  14.   
  15.     }  
  16.     public static void show(Set set){  
  17.         for(Iterator it = set.iterator(); it.hasNext();){  
  18.             Person p = (Person) it.next();  
  19.             System.out.println(p.getName()+":"+p.getAge());  
  20.         }  
  21.     }  
  22. }  
  23. //比较器排序  
  24. class Com implements Comparator  
  25. {  
  26.     public int compare(Object obj1,Object obj2){  
  27.         Person p =(Person)obj1;  
  28.         Person p2 =(Person)obj2;  
  29.         int num = p.getName().compareTo(p2.getName());  
  30.         if (num==0)  
  31.             return new Integer(p.getAge()).compareTo(new Integer(p2.getAge()));  
  32.         return num;  
  33.     }  
  34. }  

泛型

一、泛型概述

泛型是JDK1.5版本后出现的新特性,用来解决安全问题,是一个安全机制

二、作用

1、把运行时期会遇到的类型转换错误(ClassCastException)转移到编译时期,方便程序员解决问题

2、避免了强制转换的麻烦

三、泛型定义

1、泛型定义在类上(泛型类)

    特点:泛型类定义在类上时,泛型在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体泛型后,所有操作的类型就已经固定了

[java]  view plain copy print ?
  1. /*泛型定义在类上*/  
  2. class FanXing<T>  
  3. {  
  4.     private T t;  
  5.     public void setObject(T t){  
  6.         this.t = t;  
  7.     }  
  8.     public T getObject(){  
  9.         return t;  
  10.     }  
  11.     public void show(T t){  
  12.         System.out.println(t);  
  13.     }  
  14. }  
  15. class Student  
  16. {  
  17. }  
  18. class Work  
  19. {  
  20. }  
  21. class  FanXingDemo  
  22. {  
  23.     public static void main(String[] args)   
  24.     {  
  25.         /* 
  26.             会出错的情况: 
  27.             1、 
  28.             FanXing<Student> f = new FanXing<Student>(); 
  29.             f.setObject(new Student()); 
  30.             //这样写会报错  因为前面返回值类型已经固定为Student 
  31.             Work w = f.getObject(); 
  32.              
  33.             2、 
  34.             FanXing<Work> f = new FanXing<Work>(); 
  35.             //这样写会报错  因为类型已经固定为Work 
  36.             f.setObject(new Student()); 
  37.             Work w = f.getObject(); 
  38.  
  39.             3、 
  40.             FanXing<String> f = new FunXing<String>(); 
  41.             f.show("mmmmmmmm"); 
  42.             //这样写会报错,因为类型已经固定位String类型 
  43.             f.show(4); 
  44.         */  
  45.   
  46.   
  47.         /*  
  48.             不会出错的情况 
  49.             1、 
  50.             FanXing<Student> f = new FanXing<Student>(); 
  51.             f.setObject(new Student()); 
  52.             Student s = f.getObject(); 
  53.  
  54.  
  55.             2、           
  56.             FanXing<String> f = new FunXing<String>(); 
  57.             f.show("mmmmmmmm"); 
  58.             f.show("kkkkkkkk"); 
  59.         */  
  60.     }  
  61. }  
2、泛型定义在方法上

[java]  view plain copy print ?
  1. class FanXing1<T>  
  2. {  
  3.     public <T> void show(T t){  
  4.         System.out.println(t);  
  5.     }  
  6. }  
  7. class  FanXingDemo  
  8. {  
  9.     public static void main(String[] args)   
  10.     {  
  11.         /*泛型定于在方法上,就没有了局限性 
  12.         虽然说类上也定义了泛型,但是方法上使用的并不是类上泛型的类型,所以不会报错 
  13.         */  
  14.   
  15.         FanXing1<String> f1 = new FanXing1<String>();  
  16.         f1.show("aaaaaaaaaaaaa");  
  17.         f1.show(5);  
  18.         f1.show(new Integer(111111));  
  19.         f1.show('b');  
  20.     }  
  21. }  
3、泛型定义在接口上

[java]  view plain copy print ?
  1. /* 
  2. 泛型定义在接口上 
  3. */  
  4. interface Demo<T>  
  5. {  
  6.     void show(T t);  
  7. }  
  8. class DemoTest<T> implements Demo<T>  //当不确定使用什么类型时,可以不定义类型,让子类去定义  
  9. {  
  10.     public void show(T t){   //泛型类型必须和接口的泛型一致,不然不会被重写,DemoTest类也会变成抽象类  
  11.         System.out.println(t);  
  12.     }  
  13. }  
  14.   
  15. public class  FanXingInterface  
  16. {  
  17.     public static void main(String[] args)   
  18.     {  
  19.         /* 
  20.             会出错的情况: 
  21.             1、 
  22.             //泛型类型不一致 
  23.             DemoTest<Integer> d = new DemoTest<Integer>(); 
  24.             d.show("aaaaaaaaa"); 
  25.  
  26.             2、 
  27.             //泛型类型不一致 
  28.             DemoTest<String> d = new DemoTest<String>(); 
  29.             d.show(3); 
  30.         */  
  31.               
  32.             //不会出错  
  33.             DemoTest<Integer> d = new DemoTest<Integer>();  
  34.             d.show(3);  
  35.   
  36.               
  37.   
  38.     }  
  39. }  
泛型高级应用:

1、?通配符   相当于Object

2、? extends E    可以接收E类型或E类型的子类型

3、? super E     可以接收E类型或E的父类型

[java]  view plain copy print ?
  1. import java.util.*;  
  2. /* 
  3. ? 通配符。也可以理解为占位符。 
  4. 泛型的限定; 
  5. ? extends E: 可以接收E类型或者E的子类型。上限。 
  6. ? super E: 可以接收E类型或者E的父类型。下限 
  7.  
  8. */  
  9.   
  10. class Person  
  11. {  
  12.     private String name;  
  13.     Person(String name)  
  14.     {  
  15.         this.name = name;  
  16.     }  
  17.     public String getName()  
  18.     {  
  19.         return name;  
  20.     }  
  21. }  
  22.   
  23. class Student extends Person  
  24. {  
  25.     Student(String name)  
  26.     {  
  27.         super(name);  
  28.     }  
  29.   
  30. }  
  31.   
  32. class  GenericDemo6  
  33. {  
  34.     public static void main(String[] args)   
  35.     {  
  36.         ArrayList<Person> al = new ArrayList<Person>();  
  37.         al.add(new Person("abc1"));  
  38.         al.add(new Person("abc2"));  
  39.         al.add(new Person("abc3"));  
  40.         printColl(al);  
  41.   
  42.         ArrayList<Student> al1 = new ArrayList<Student>();  
  43.         al1.add(new Student("abc--1"));  
  44.         al1.add(new Student("abc--2"));  
  45.         al1.add(new Student("abc--3"));  
  46.         printColl(al1);  //ArrayList<? extends Person> al = new ArrayList<Student>();error  
  47.   
  48.     }  
  49.     public static void printColl(Collection<? extends Person> al)  //这样写代表printColl函数可以接收Collection集合,而collection集合中的元素必须是Person类型或Person的子类型  
  50.     {  
  51.         Iterator<? extends Person> it = al.iterator();  
  52.   
  53.   
  54.         while(it.hasNext())  
  55.         {  
  56.             System.out.println(it.next().getName());  
  57.         }  
  58.     }  
  59.     /* 
  60.     public static void printColl(ArrayList<?> al)   //代表printColl函数可以接收的类型是ArrayList集合,而集合中的元素可以是任意类型 
  61.     { 
  62.         Iterator<?> it = al.iterator(); 
  63.  
  64.  
  65.         while(it.hasNext()) 
  66.         { 
  67.             System.out.println(it.next().toString()); 
  68.         } 
  69.     } 
  70.     */  
  71. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值