zoukankan      html  css  js  c++  java
  • java:集合(Collection)和集合的应用方法,List(接口),泛型和泛型应用,instanceof关键字

    什么是集合

     简单来讲:集合就是一个放数据的容器,准确的说是放引用数据的容器。

    为什么要使用集合框架?

    传统的容器(数组)进行增、删破坏性操作时,需要移动元素,可能导致性能问题同时添加、删除等算法和具体业务耦合在一起,增加了程序开发的复杂度。

    Java集合框架提供了一套性能优良、使用方便的接口和类,它们位于java.util包中

    package cn.collection;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Iterator;
    
    /**Collection是java集合框架(collection-frame)中的顶层接口。
       Collection接口是一个容器,容器中只能存储引用数据类型,建议存同一类型的引用类型,方便后续遍历等操作。
            容器中的元素可以是有序的、可重复的,称为List接口
          也可能是无序的、唯一的,称为Set接口。
     * 
     * 
     *
     */
    public class TestCollection {
    public static void main(String[] args) {
        /**通过实现类来实现
         * 增:add/addAll
         * 删:clear/remove/removeAll/retainAll
         * 改:
         * 查:contains/containsAll/isEmpty/size
         */
        Collection c1=new ArrayList();//通过ArrayList类(本质上是List接口的实现类)实现Collection接口
        //通过ArrayList类把引用数据追加给Collection容器
        c1.add("apple"); // Object object = new String("apple");
        c1.add("banana");//把引用数据类型加入Collection容器
        System.out.println(c1);//输出结果:[apple, banana]
        
        //基本数据类型通过包装类存入Collection
        // c1.add(1);         // Object object = new Integer(1); 
        
        // 追加一个集合 
        Collection c2 = new ArrayList();
        c2.add("java");//把引用数据类型加入Collection容器
        c2.add("c+");
        c2.add("c");
        c2.add("c++");
        c2.add("a++");
        c2.add("d++");
        c1.addAll(c2);//可以直接把一个集合追加给另一个相同类型的集合
        System.out.println(c1);//输出结果:[apple, banana, java, c+, c, c++, a++, d++]
        
        
        
        
        Collection c3=new ArrayList();
        c3.add("d++");
        c3.add("ff++");
        //删除列表中的所有元素。
        //c1.clear();
        System.out.println(c1);//输出结果:[]
        
        // 删除此列表中首次出现的指定元素(如果存在,从左往右)。
        c2.remove("c++");
        System.out.println(c2);//输出结果:[java, c+, c, a++, d++]
        
        //删除c1中的和c3有同样的元素(删除两个容器中同样的元素)
        c1.removeAll(c3);
        System.out.println(c1);//输出结果:[apple, banana, java, c+, c, c++, a++]
        
        //提取两个容器中相同的元素,然后清空c1,再把相同元素追加给c1
        c1.retainAll(c2);
        System.out.println(c1);//输出结果:[java, c+, c, a++]
        
        
        
        //如果此列表中包含指定的元素,则返回 true。
        System.out.println(c1.contains("apple"));//输出结果:false
        System.out.println(c2);//输出结果:[java, c+, c, a++, d++]
        
        c1.add("d++");
        //c1和c2是否相等
        System.out.println(c1.containsAll(c2));//输出结果:true
        
        //c1是否为空
        //c1.clear();//清空c1//输出结果:true
        
        System.out.println(c1.isEmpty());//输出结果:false
        // 返回集合元素的个数
        System.out.println(c1.size());//输出结果:5
        //c1和c2内元素是否相等
        System.out.println(c1.equals(c2));//输出结果:true
        
        
        
    
        Collection c4 = new ArrayList();
        c4.add("apple");
        c4.add("banana");
        c4.add("coco");
        
        
        // 快速遍历
        // for-each
        // Object 表示元素类型 
        // object 表示迭代变量(循环输出的变量)
        // c1表示集合
        for (Object object : c4) {
            
            System.out.println(object.toString());//输出结果:apple(循环输出)
                     }                                 //  banana
                                                        // coco
        
        /**Iterator接口:几乎所有接口的都继承与它的超级接口
         * 有hasNext方法:如果仍有元素可以迭代,则返回 true。
         *  next()方法:返回迭代的下一个元素。
         *  remove() :  从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。
          */
        // 迭代器遍历(国内)
        /**快速遍历的本质
         * Collection继承Iterable接口,表示集合支持快速遍历。Iterable接口定义了一个方法iterator()用于获取集合的迭代器,
                    是一个Iterator接口类型,iterator()内部返回一个实现类实现类Iterator接口。
                    这个实现类一定具有hasNext和next方法用于判断是否有下一个元素和获取下一个元素。快速遍历就是基于迭代器工作的。
          
         */
        //Iterator是对 collection 进行迭代的迭代器,蕴含了迭代的能力的接口
        Iterator it = c4.iterator();////iterator是Iterable类的方法,通过方法的接口Iterator返回在此 collection 的元素上进行迭代的迭代器。
        while(it.hasNext()) {         //是否还有下个元素
        Object item = it.next();       //Object是几乎所有类的父类,所以通过父类引用子类来实现方法
        System.out.println(item.toString());//输出结果:apple(循环输出)
        }                                        //  banana
                                                 // coco
                
                                                    
        // 国外
        for(Iterator it2=c4.iterator();it2.hasNext();) {
        Object item = it2.next();
        System.out.println(item.toString());
        }
       }
    }
    package cn.collection;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.ListIterator;
    
    /**1.3List接口(继承了collection接口)
     List 接口中的元素时有序的、可重复的。List接口中的元素通过索引(index)来确定元素的顺序。
    有序的 collection(也称为序列)。可以对列表中每个元素的插入位置进行精确地控制。
    用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素
     */
    public class ArraysList {
        public static void main(String[] args) {
        /**通过List接口实现类来实现,比collection接口本身使用实现类来实现更完善方法更多
         * 增:add/addAll/add(index,el)/addAll(index,collection)
         * 删:clear/remove/removeAll/remove(index)
         * 改:set(index,el)
         * 查:get(index)/indexOf/lastIndexOf()
         * 其他:contains/containsAll/isEmpty/size
         */
        List list1 = new ArrayList();//接口引用实现类,ArrayList类是collection接口和List接口共有的实现类
        // 添加元素
        list1.add("apple");
        list1.add("banana");
        // 在指定位置添加元素
        list1.add(0, "coco");
        
        System.out.println(list1);//输出结果:[coco, apple, banana]
        
        List list2 = new ArrayList();
        list2.add("java");
        list2.add("c++");
        
        list1.addAll(1, list2); //把list2的元素放在list1的第一个位置
        System.out.println(list1);//输出结果:[coco, java, c++, apple, banana]
        
        // 删除
        //从此列表中移除第一次出现的指定元素(如果存在)(可选操作)。
        list1.remove("coco");
        System.out.println(list1);//输出结果:[java, c++, apple, banana]
        //移除列表中指定位置的元素(可选操作)。
        list1.remove(0);
        System.out.println(list1);//输出结果:[c++, apple, banana]
                
        // 修改:指定元素替换列表中指定位置的元素(可选操作)。
        list1.set(0, "javax");
        System.out.println(list1);//输出结果:[javax, apple, banana]
                
        // 查: 返回列表中指定位置的元素。
        System.out.println(list1.get(0));//输出结果:javax
        list1.add("apple");
        list1.add("apple");
        //List:元素是有序的、可重复的。
        System.out.println(list1);//输出结果:[javax, apple, banana, apple, apple]
        //从左到右返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。
        System.out.println(list1.indexOf("apple"));//输出结果:1
        //从右到左返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。
        System.out.println(list1.lastIndexOf("apple"));//输出结果:4
        
        /**ListIterator 继承于Iterator,在Iterator的基础上提供了以正向遍历集合,也可以以逆序遍历集合。
           * 所以有hasNext/next 以正向遍历
                         还多了 hasPrevious/previous 以逆序遍历
          */
        
        List list3 = new ArrayList();
        list3.add("apple");
        list3.add("banana");
        list3.add("coco");
        
        
       // 【1】快速遍历
        for (Object item : list3) {
            System.out.println(item.toString());//输出结果:apple  banana   coco   
        }
        
        
        // 【2】普通for(collection接口不行)
        //size()返回列表中的元素数。
        for(int i=0;i<list3.size();i++) {//因为知道元素个数,所以通过循序遍历输出
            System.out.println(list3.get(i));//输出结果:apple  banana   coco 
        }
        
        
        // 【3】集合迭代器
        Iterator it = list3.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());//输出结果:apple  banana   coco 
        }
        
        
        //ListIterator接口是继承了Iterator接口,所以ListIterator接口能力更强大
        // listIterator()返回此列表元素的列表迭代器(按适当顺序)
        //listIterator(int index)  返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。
       // 正向遍历
        ListIterator it2 = list3.listIterator();
        while(it2.hasNext()) {
            System.out.println(it2.next());//输出结果:apple  banana   coco 
        }
        
        // 逆序遍历
        //hasPrevious()逆序输出
        while(it2.hasPrevious()) {
            System.out.println(it2.previous());//输出结果: coco banana  apple
        }
        
    
        
        ////listIterator(int index)  返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。
        ListIterator it3 = list3.listIterator(1);
        while(it3.hasNext()) {
            System.out.println(it3.next());//输出结果:banana  coco
             }    
        }
    }
    package cn.collection;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.ListIterator;
    
    /**ArrayList 是List接口的实现类,底层数据结构是数组,实现大小可变的数组。
    ArrayList 线程不安全,jdk1.2
    ArrayList 底层数据结构是数组,默认数组大小是10,如果添加的元素个数超过默认容量,
    ArrayList会自动拓容,拓容原则:newCapacity = oldCapacity + oldCapacity / 2;
    如果未来确定序列的元素不在增加,通过调用trimToSize()调制容量至合适的空间。
    ArrayList作为List接口的实现类,常用方法和遍历方法参考List接口。
     
     */
    public class ArraysList01 {
    public static void main(String[] args) {
        ArrayList list1 = new ArrayList();
        list1.add("apple1");
        list1.add("apple2");
        list1.add("apple3");
        list1.add("apple4");
        list1.add("apple5");
        list1.add("apple6");
        list1.add("apple7");
        list1.add("apple8");
        list1.add("apple9");
        list1.add("apple10");
        System.out.println(list1.size());
        //结果输出:10
        
        
        ArrayList list = new ArrayList();
        list.add("apple1");
        list.add("apple2");
        list.add("apple3");
        
        
        for (Object item: list) {
            System.out.println(item);//结果输出:apple1 apple2 apple3
        }
        
        for (int i = 0; i < list.size(); i++) {
            Object item = list.get(i);
            System.out.println(item);//结果输出:apple1 apple2 apple3
        }
        
        Iterator it = list.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());//结果输出:apple1 apple2 apple3
        }
        
        ListIterator it2 = list.listIterator();
        while(it2.hasNext()) {
            System.out.println(it2.next());}//结果输出:apple1 apple2 apple3
    }
    }
    package cn.collection;
    
    import java.util.ListIterator;
    import java.util.Vector;
    
    /*Vector 是List接口的实现类,底层数据结构也是数组,也是大小可变的数组。
    Vector是线程安全的,jdk1.0
    Vector底层数据结构是数组,默认数组大小是10,如果添加的元素个数超过默认容量,Vector会自动拓容,
    拓容原则:newCapacity = oldCapacity +capacityIncrement(增长因子);
    如果未来确定序列的元素不在增加,通过调用trimToSize()调制容量至合适的空间。
    注意:Vector 在实现List接口的同时,同添加了自身特有的方法xxxElement,
    
    
    未来使用时为了程序的可拓展性,一定要按照接口来操作Vector。*/
    public class Vector01 {
    public static void main(String[] args) {
        Vector list = new Vector();
        list.add("apple1");
        list.add("apple2");
      System.out.println(list.size());//输出结果:2
      // 返回此向量的当前容量。
      System.out.println(list.capacity());//输出结果:10
        // 返回此向量中第一次出现的指定元素的索引,从 index 处正向搜索,如果未找到该元素,则返回 -1。
      System.out.println(list.indexOf("apple2",1));//输出结果:1
      
      
      //将指定的元素添加在容器末尾,容量加1
      list.addElement("apple3");
      ListIterator it = list.listIterator();
        while(it.hasNext()) {
            System.out.println(it.next());}//结果输出:apple1 apple2 apple3
    // vector:特有的方法都加了:Element
      
    
      
      }
    }
    package cn.collection;
    
    import java.util.LinkedList;
    
    /*LinkedList是List接口的实现类,底层数据结构是链表。
    LinekList常用方法和遍历方法参照List接口。
    LinkedList 线程不安全。
    
    除了实现List接口, 还实现栈接口
    */
    
    //push入栈操作  pop出栈操作
    public class LinkedList01 {
    public static void main(String[] args) {
        //push入栈操作(add/remove/element() 可能会出现NoSuchElementException异常)
        LinkedList list = new LinkedList();
        list.push("apple");
        list.push("banana");
        list.push("coco");
        System.out.println(list.element());//获取表头元素:输出结果:coco(先入的在最底下)
        // pop出栈操作:从此列表所表示的堆栈处弹出一个元素。(先入后出)入口和出口相同
        System.out.println(list.pop());//输出结果:coco
        System.out.println(list.pop());//输出结果:banana
        System.out.println(list.pop());//输出结果:apple
        
        //如果容器内已没有元素,再次 pop出栈操作就会 异常输出
        //System.out.println(list.pop());// 输出结果:java.util.NoSuchElementException(没有元素异常)
        
        
        
        //以队列形式操作LinkedList,(先入后出)一个入口和一个出口(分开来的)
        LinkedList queue = new LinkedList();
        // 入队
        /**
         * 队列头                          队列尾
         *<-----          <-----
         * [apple, banana, coco]
         */
        queue.add("apple");//将指定元素添加到此列表的结尾。
        queue.add("banana");
        queue.add("coco");
        System.out.println(queue);//输出结果:[apple, banana, coco]
            // 获取表头元素
        System.out.println(queue.element());//输出结果:apple
        // 出队,
        System.out.println(queue.remove());//输出结果:apple
        System.out.println(queue.remove());//输出结果:banana
        System.out.println(queue.remove());    //输出结果:coco    
        System.out.println(queue);//输出结果:[]
        //System.out.println(queue.remove());// java.util.NoSuchElementException
        
        
        // 入队(offer/poll/peek 可能会返回特殊值(null))
                /**先入先出
                 * 队列头                          队列尾
                 *<-----          <-----
                 * [apple, banana, coco]
                 */
        LinkedList list1 = new LinkedList();
        list1.offer("apple");
        list1.offer("banana");
        list1.offer("coco");
        System.out.println(list1);//输出结果:[apple, banana, coco]
        System.out.println(list1.peek());//输出结果:apple
         
        
        // 出队列
        System.out.println(list1.poll());//输出结果:apple
        System.out.println(list1.poll());//输出结果:banana
        System.out.println(list1.poll());//输出结果:coco    
         //获取但不移除此列表的头(第一个元素)。
         System.out.println(list1.peek());//输出结果:null(因为已经全部取出了,容器已没有元素)
        
         
         
         LinkedList queue2 = new LinkedList();
        // 入队
        /**头和尾同时输出
         *<-----          <-----
         * [apple, banana, coco]
         * ---->          ----->
         */
        
        queue2.addFirst("apple");
        queue2.addFirst("banana");
        queue2.addFirst("coco");
        System.out.println(queue2);//输出结果:[coco, banana, apple]
        System.out.println(queue2.getFirst());//表头:输出结果:coco
        //先输出尾在输出头最后才输出中间
        System.out.println(queue2.removeLast());//输出结果:apple
        System.out.println(queue2.removeFirst());//输出结果:coco
        System.out.println(queue2.removeFirst());//输出结果:banana
        System.out.println(queue2);//输出结果:[]
        
        // 获取头元素
        System.out.println(queue2.getFirst());//输出结果: java.util.NoSuchElementException
    
        
        }
    }

     数据结构(补充)

    数据结构就是数据在内存中存储结构。根据存储的方式不同,分为线性表、二叉树、图、栈、队列等

     线性

    线性表数据按照一定的逻辑顺序存储在内存中。线性表是有序的。线性表根据内存的物理结构分为两种:数组和链表

    数组是一种逻辑上有序的线性表,物理上也连续

     

    链表是一种逻辑上有序的线性表,但物理上不连续。

     

    数组和链表的区别

    数组在查询时效率高,在添加、删除元素时效率低(涉及移动元素)

    链表在查询时效率(每次从头开始不能跳跃访问),在添加、删除元素时效率高(不涉及移动元素)

     

    特性:进后出,后进先出

     

    队列

    特性:进先出

     
    package cn.collection;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.ListIterator;
    
    /*Iterator在迭代过程中不允许向集合中添加元素
     * 但ListIterator接口继承于Iterator,在这基础上拥有了在运行时增加元素的功能

    当通过Iterator集合迭代器遍历集合过程中,不能再向集合汇总添加元素否则出现ConcurrentModificationException 并发修改异常。

    ListIterator允许程序员按任一方向遍历列表、迭代期间修改列表,并获得迭代器在列表中的当前位置* */

    public class Iterator1 {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add("apple");
        list.add("banana");
        list.add("coco");
        
        /*Iterator it=list.iterator();
        
        while(it.hasNext()) {
            String item = (String) it.next();
            if(item.equals("banana")) {
                it.add("test");输出过程中增加元素(直接编译不了,属于检查性异常)
            }
        }
        System.out.println(list);*/
        
        
        //ListIterator接口继承于Iterator,在这基础上拥有了在运行时增加元素的功能
        ListIterator it1 = list.listIterator();
        while(it1.hasNext()) {
            String item = (String) it1.next();
            if(item.equals("banana")) {
                it1.add("test");
            }
        }
        
        System.out.println(list);//输出结果:[apple, banana, test, coco]
    }
    }


    package cn.collection;
    //泛型类:当一个类中属性的数据类型不确定时,具体是什么类型由使用者来确定时,使用泛型。泛型类的形式public class 类名<T> {}
    public class FanClass<T> {
        private T t;
    
        public T getT() {
            return t;
        }
    
        public void setT(T t) {
            this.t = t;
        }
    
        public FanClass(T t) {
            super();
            this.t = t;
        }
    
        public FanClass() {
            super();
    }
        
        public void fan(){
            System.out.println(t);
        }
    }
    
    
    



    package cn.collection;
    
    import java.util.Arrays;
    
    /**/
    public class Student {
        /*如果定义一个不知道什么类型的方法重载,要把每个类型写一遍,但用泛类型只用写一个就可以了
         * 泛型方法可以定义多个泛型类型
                   多个泛型类型进一步优化了方法重载。
                   
        public void showInfo(int a) {
            System.out.println(a);
        }
        
        public void showInfo(float a) {
            System.out.println(a);
        }
        
        public void showInfo(String a) {
            System.out.println(a);
        }*/
        /*泛型方法:当一个方法的参数类型不确定时,具体是什么类型由使用者来确定,可以考虑使用泛型方法。
                   形式:public <T> void xxx(T a) {System.out.println(a);}
                 泛型方法在调用时确定(指明)类型。
                       泛型方法在一定程度上优化了方法重载。*/
        //用泛类型的方法重载
        public <T> void showInfo(T a) {
            System.out.println(a);
        }
        
        
        // 可以定义多个泛型的类型
        public <A,B> void showInfo(A a,B b) {
            System.out.println(a);
            System.out.println(b);
        }
        
        // 多个同类型的泛型
        public <A> void print(A a) {
            System.out.println(a);
        }
        public <A> void print(A a,A b) {
            System.out.println(a);
            System.out.println(b);
        }
        
        /*多个同类型的泛型
    A… a 表示方法可以接受多个参数。当调用方法传递多个参数时,多个参数被放到a数组中,a是什么类型的数组由开发者调用处传参决定。
    print(A...a) 方法称为可变参数的泛型形式。*/
        public void foo(int...a) {//多个同类型的int组成的数组a
            System.out.println(a);
            System.out.println(Arrays.toString(a));
        }
        
        public <A> void print(A...a) {//多个同类型的泛型组成的数组a
            // a 是一个数组
            // System.out.println(a);
    
            System.out.println(Arrays.toString(a));
        }
    }
    
    
    


    package
    cn.collection; //泛型(generic) /*泛型的概念: * 泛型允许开发者在强类型程序设计语言(java)编写代码时定义一些可变部分,这些部分在使用前必须作出指明。 泛型就是将类型参数化 ArrayList<E> list表示声明了一个列表list,列表的元素是E类型 ArrayList<String> list = new ArrayList<String>(); 声明了一个列表list,列表的元素只能是String类型。 泛型在编译器起作用,运行时jvm察觉不到泛型的存在。泛型在运行时已经被擦除了。 * */ public class Test { public static void main(String[] args) { //在提取时确定类型 FanClass<String> fan = new FanClass<String>(); fan.setT("apple"); fan.fan();//输出结果:apple FanClass<Integer> fan2 = new FanClass<Integer>(); fan2.setT(1); fan2.fan();//输出结果:1 Student stu = new Student(); stu.showInfo(1);//输出结果:1 stu.showInfo("apple",1.0f);//输出结果:apple 1.0 //stu.print(1, "apple");不行 //必须stu.print(1, 5);同类型 stu.print(1);//输出结果:1 stu.print(1,2);//输出结果:1 2 stu.print("apple");//输出结果:apple stu.print("apple","banana");//输出结果:apple banana stu.foo(1,2,3,4,5,6);//输出结果:[I@747541f8(证明它是一个数组) //输出结果:[apple, banana, banana, banana, banana] stu.print("apple","banana","banana","banana","banana");//输出结果:[apple, banana, banana, banana, banana] } }
        ArrayList<String> list = new ArrayList<String>();//泛型的集合(因为集合底层结构是数组,所以基本类型要包装才能存进集合)
        list.add("apple");
    
        ArrayList<Integer> list2 = new ArrayList<Integer>();
        list2.add(1);
        
        
        // list instanceof ArrayList
        // list instanceof ArrayList<String>
        
        /*instanceof是Java、php的一个二元操作符(运算符),和==、>、<是同一类东西。由于它是由字母组成的,所以也是Java的保留关键字。
         * 它的作用是判断其左边对象是否为其右边类的实例,返回boolean类型的数据。可以用来判断继承中的子类的实例是否为父类的实现。
         * 相当于c#中的is操作符。java中的instanceof运算符是用来在运行时指出对象是否是特定类的一个实例。
         * instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。*/
        
        
        System.out.println(list instanceof ArrayList);//输出结果:true
        // System.out.println(list instanceof ArrayList<String>);
        System.out.println(list instanceof ArrayList<?>);//输出结果:true
        
     
    package cn.collection;
    //如果接口中的方法的参数(形参、返回值)不确定时,可以考虑使用泛型接口。形式
    public interface FANString<T> {
        public void showInfo(T t);
    }
    
    /**
     * 泛型的命名规则:
     * 【1】一定要大写,推荐使用单个字母
     * 【2】字母任意,一般情况下下 T--type  E---Element
     */
    
    
    


    package
    cn.collection; //[1]实现类能确定泛型接口的类型 // public class Test00 implements FANString<String>{ @Override public void showInfo(String t) { // TODO Auto-generated method stub } } //实现类不能确定泛型接口的类型->继续泛。 /* public class Test00<T> implements FANString<T>{ @Override public void showInfo(T t) { } }*/

     泛型的上限和下限 (C)

    public static void print(ArrayList<? extends Pet> list) {

    for (Pet pet : list) {

    pet.showInfo();

    }

    }

    泛型的上限ArrayList(? extends Pet) list 声明了一个容器,容器中的元素类型一定要继承于Pet,我们称这种形式叫做泛型的上限。

    泛型的下ArrayList(? super Pet) list 声明了一个容器容器中的元素类型一定要是Pet的父类我们称这个形式为泛型的下限。

  • 相关阅读:
    Java实现花朵数
    Java实现花朵数
    Java实现花朵数
    Java实现花朵数
    Java实现花朵数
    Java实现 黑洞数
    Java实现 黑洞数
    Java实现 黑洞数
    Could not create the view: An unexpected exception was thrown.问题解决
    让 SVN (TortoiseSVN)提交时忽略指定目录
  • 原文地址:https://www.cnblogs.com/406070989senlin/p/10802515.html
Copyright © 2011-2022 走看看