• 【JAVA基础】17 集合


    1. 对象数组的概述和使用

    • 案例演示

      • 需求:我有5个学生,请把这个5个学生的信息存储到数组中,并遍历数组,获取得到每一个学生信息。

      • package com.heima.collection;
        
        import com.heima.bean.Student;
        
        public class Demo1_Array {
        
            /**
            需求:我有5个学生,请把这个5个学生的信息存储到数组中,并遍历数组,获取得到每一个学生信息。
             */
            public static void main(String[] args) {
                // 创建基本数据类型数组
                int[] arr_base = {1,2,3,4,5};
                
                // 创建引用数据类型数组
                Student[] arr = new Student[5];
                arr[0] = new Student("张三",23);  // 创建一个学生对象,存储在数组的第一个位置
                arr[1] = new Student("李四",24);
                arr[2] = new Student("王五",25);
        
                for(int i = 0; i < arr.length; i++) {
                    System.out.println(arr[i]);
                }
                
            }
        
        }
        View Code
      • package com.heima.bean;
        
        public class Student {
        
            /**
             
             */
            
            private String name;
            private int age;
            
            
            public Student() {
                super();
                
            }
            
            
            public Student(String name, int age) {
                super();
                this.name = name;
                this.age = age;
            }
        
        
            public String getName() {
                return name;
            }
            public void setName(String name) {
                this.name = name;
            }
            
            public int getAge() {
                return age;
            }
            public void setAge(int age) {
                this.age = age;
            }
        
        
            @Override
            public String toString() {
                return "Student [name=" + name + ", age=" + age + "]";
            }
            
            
            
        }
        Student类

         

    • 画图演示

      • 把学生数组的案例画图讲解

      • 数组和集合存储引用数据类型,存的都是地址值

     

    2. 集合的由来及集合继承体系图

    • 集合的由来

      • 数组长度是固定,当添加的元素超过了数组的长度时需要对数组重新定义。太麻烦!

      • java内部给我们提供了集合类,能存储任意对象,长度是可以改变的,随着元素的增加而增加,随着元素的减少而减少

    • 数组和集合的区别

      • 区别1 :

        • 数组既可以存储基本数据类型,又可以存储引用数据类型。

          • 基本数据类型存储的是值,引用数据类型存储的是地址值

        • 集合只能存储引用数据类型(对象)

          • 集合中也可以存储基本数据类型,但是在存储的时候会自动装箱变成对象

            • 如:存储100,自动装箱,存储new Integer(100);
      • 区别2:

        • 数组长度是固定的,不能自动增长

        • 集合的长度的是可变的,可以根据元素的增加而增长

    • 数组和集合什么时候用

      • 如果元素个数是固定的推荐用数组

      • 如果元素个数不是固定的推荐用集合

    • 集合继承体系图

     

    3. Collection集合的基本功能测试

    • 案例演示

      • package com.heima.collection;
        
        import java.util.ArrayList;
        import java.util.Collection;
        
        import com.heima.bean.Student;
        
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public class Demo2_Collection {
        
            /**
             
             */
            public static void main(String[] args) {
                demo1();
                
                demo2();
            }
        
            public static void demo2() {
                Collection c = new ArrayList();
                c.add("a");
                c.add("b");
                c.add("c");
                c.add("d");
                c.remove("b");
                System.out.println(c);
                
                c.remove("e");  // 返回值boolean类型,false,移除失败
                System.out.println(c);
                
                c.clear();  // 清空集合
                System.out.println(c);
                
                System.out.println(c.isEmpty());  // 判断数组集合是否为空
                
                c.add("a");
                System.out.println(c.contains("e"));  // 验证是否包含指定元素
                System.out.println(c.contains("a"));
                
                System.out.println(c.size());  // 获取元素的个数
            
            }
        
            public static void demo1() {
                // Collection是接口,无法实例化
                // 可以通过父类指向子类对象,生成对象,调用Collection的方法
                Collection c = new ArrayList();
                boolean b1 = c.add("abc");  //自动装箱 new String("abc")
                boolean b2 = c.add(true);   // new Boolean(true)
                boolean b3 = c.add(100);    // new Integer(100)
                boolean b4 = c.add(new Student("张三",23));
                boolean b5 = c.add("abc");
                
                
                System.out.println(c);
                /*
                 * add方法如果是List集合使用,则一直都返回true,因为List集合是可以存储重复元素的;
                 * 如果是Set集合,当存储重复元素的时候,就会返回false
                 * 
                 * ArrayList的父类的父类,重写了toString方法,所以打印对象的引用的时候,输出的结果不是Object类中的toString的结果
                 */
            }
        
        }
        View Code
    • 基本功能演示

      • boolean add(E e)

      • boolean remove(Object o)

      • void clear()

      • boolean contains(Object o)

      • boolean isEmpty()

      • int size()

    • 注意:

      • collectionXxx.java使用了未经检查或不安全的操作。

      • 注意:要了解详细信息,请使用 -Xlint:unchecked重新编译。

      • java编译器认为该程序存在安全隐患

      • 温馨提示:这不是编译失败,所以先不用理会,等学了泛型你就知道了

     

    4. 集合的遍历之集合转数组遍历

    • 集合的遍历

      • 其实就是依次获取集合中的每一个元素。

    • 案例演示

      • 把集合转成数组,可以实现集合的遍历

      • package com.heima.collection;
        
        import java.util.ArrayList;
        import java.util.Collection;
        
        import com.heima.bean.Student;
        
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public class Demo3_Collection {
        
            /**
             * @param args
             */
            public static void main(String[] args) {
                demo1();
                
                demo2();
                
            }
        
            public static void demo2() {
                Collection c = new ArrayList();
                c.add(new Student("Ann", 23));  // Object obj = new Student("Ann",23)
                c.add(new Student("Bill", 24));
                c.add(new Student("Caro", 25));
                c.add(new Student("Dai", 26));
                
                Object[] arr = c.toArray();
                
                for(int i = 0; i < arr.length; i++) {
                    System.out.println(arr[i]);
                    //System.out.println(arr[i].getName());
                    /*
                     * Object obj = new Student("Ann",23)
                     * 父类引用指向子类对象
                     * 多态的弊端:不能使用子类特有的属性和行为
                     * 
                     * 类型提升上去了,想要使用Student中的getName和getAge方法, 还需要向下转型
                     */
                    
                    Student s = (Student)arr[i];
                    System.out.println(s.getName() + "," + s.getAge());
                }
            }
        
            public static void demo1() {
                Collection c = new ArrayList();
                c.add("a");
                c.add("b");
                c.add("c");
                c.add("d");
                
                Object[] arr = c.toArray();
                for(int i = 0; i < arr.length; i++) {
                    System.out.println(arr[i]);
                }
            }
        
        }
        View Code

         

    5. Collection集合的带All功能测试

    • 带All的功能演示

      • boolean addAll(Collection c)

      • boolean removeAll(Collection c)

      • boolean containsAll(Collection c)

      • boolean retainAll(Collection c)

    • 案例演示
      • package com.heima.collection;
        
        import java.util.ArrayList;
        import java.util.Collection;
        
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public class Demo4_Collection {
        
            /**
             * @param args
             */
            public static void main(String[] args) {
        //        demo1();
        //        demo2();
        //        demo3();
                demo4();
                
                
            }
        
            public static void demo4() {
                /*
                 * retainAll 取交集
                 * 逻辑:
                 * 如果调用的集合改变,则返回true;
                 * 如果调用的集合未改变,则返回false。
                 * 
                 * 如:
                 * c1 和 c2的交集是[](空集合),则将[] 赋值给c1,c1的值改变了,返回true;
                 * c1 和 c2的交集是[a,b,c,d](和c1一样),则将[a,b,c,d]赋值给c1,c1的值未发生变化,返回false;
                 * c1 和 c2的交集是[a,b],则将[a,b] 赋值给c1,c1的值改变了,返回true;
                 */
                Collection c1 = new ArrayList();
                c1.add("a");
                c1.add("b");
                c1.add("c");
                c1.add("d");
                
                
        //        Collection c2 = new ArrayList();
        //        c2.add("a");
        //        c2.add("b");
                
                Collection c3 = new ArrayList();
                c3.add("a");
                c3.add("b");
                c3.add("f");
                
                Collection c4 = new ArrayList();
                c4.add("f");
                
                //System.out.println(c1.retainAll(c2));  // 取交集
                System.out.println(c1);  // 输出  [a, b]
                System.out.println(c1.retainAll(c3));  //false
                System.out.println(c1);
                System.out.println(c1.retainAll(c4));   //true
                System.out.println(c1);
            }
        
            public static void demo3() {
                Collection c1 = new ArrayList();
                c1.add("a");
                c1.add("b");
                c1.add("c");
                c1.add("d");
                
                
                Collection c2 = new ArrayList();
                c2.add("a");
                c2.add("b");
                
                Collection c3 = new ArrayList();
                c3.add("a");
                c3.add("b");
                c3.add("f");
                
                System.out.println(c1.containsAll(c2));
                System.out.println(c1.containsAll(c3));
            }
        
            public static void demo2() {
                Collection c1 = new ArrayList();
                c1.add("a");
                c1.add("b");
                c1.add("c");
                c1.add("d");
                
                
                Collection c2 = new ArrayList();
                c2.add("a");
                c2.add("b");
                c2.add("f");
                
                Collection c3 = new ArrayList();
                c3.add("m");
                c3.add("n");
                c3.add("f");
                
                System.out.println(c1.removeAll(c2));  //删除的是c1和c2的交集
                System.out.println(c1);
                
                System.out.println(c1.removeAll(c3));  //若没有交集,则返回false
                System.out.println(c1);
            }
        
            public static void demo1() {
                Collection c1 = new ArrayList();
                c1.add("a");
                c1.add("b");
                c1.add("c");
                c1.add("d");
                
                
                Collection c2 = new ArrayList();
                c2.add("a");
                c2.add("b");
                c2.add("c");
                c2.add("d");
                
                c1.addAll(c2);
                System.out.println(c1);  // 输出[a, b, c, d, a, b, c, d]
                
                c1.add(c2);
                System.out.println(c1);  // 输出[a, b, c, d, a, b, c, d, [a, b, c, d]]
            }
        
        }
        View Code

    6. 集合的遍历之迭代器遍历

    • 迭代器概述

      • 集合是用来存储元素,存储的元素需要查看,那么就需要迭代(遍历)

    • 案例演示

      • Iterator<E> iterator()    返回在此 collection 的元素上进行迭代的迭代器。
      • 迭代器的使用

        • package com.heima.collection;
          
          import java.util.ArrayList;
          import java.util.Collection;
          import java.util.Iterator;
          
          import com.heima.bean.Student;
          
          @SuppressWarnings({ "rawtypes", "unchecked" })
          public class Demo5_Iterator {
          
              /**
               * @param args
               */
              public static void main(String[] args) {
          //        demo1();
                  
                  demo2();
                  
                  
              }
          
              public static void demo2() {
                  Collection c = new ArrayList();
                  c.add(new Student("Ann", 23));  // Object obj = new Student("Ann",23)
                  c.add(new Student("Bill", 24));
                  c.add(new Student("Caro", 25));
                  c.add(new Student("Dai", 26));
                  
                  Iterator it = c.iterator();
                  while(it.hasNext()) {
                      Student s = (Student)it.next();
                      System.out.println(s.getName());
                  }
              }
          
              public static void demo1() {
                  Collection c = new ArrayList();
                  c.add("a");
                  c.add("b");
                  c.add("c");
                  c.add("d");
                  
                  Iterator it = c.iterator();
                  while(it.hasNext()) {
                      System.out.println(it.next());
                  }
              }
          }
          View Code

           

    7. 迭代器的原理及源码解析

    • 迭代器原理

      • 迭代器是对集合进行遍历,而每一个集合内部的存储结构都是不同的,所以每一个集合存和取都是不一样,那么就需要在每一个类中定义hasNext()和next()方法,这样做是可以的,但是会让整个集合体系过于臃肿。

      • 迭代器是将这样的方法向上抽取出接口,然后在每个类的内部,定义自己迭代方式。

      • 这样做的好处有二:

        • 第一规定了整个集合体系的遍历方式都是hasNext()和next()方法

        • 第二,代码有底层内部实现,使用者不用管怎么实现的,会用即可

    • 迭代器源码解析

      • 在eclipse中  ctrl + shift + t  找到ArrayList类

      • ctrl+o查找iterator()方法

      • 查看返回值类型是new Itr(),说明 Itr 这个类实现Iterator接口

      • 查找Itr这个内部类,发现重写了Iterator中的所有抽象方法

     

    8. List集合的特有功能概述和测试

    • List的概述
      • 有序的Collection 也称为 序列。
      • 此接口的用户可以对列表中每个元素的插入位置进行精确地控制。
      • 用户可以根据元素的整数索引访问元素,并搜索列表中的元素。
      • List允许重复的元素。
    • List接口提供了4种对元素进行定位(索引)访问方法
      • 所以从0开始
      • 在列表元素上迭代通常优于用索引遍历列表
    • List接口提供了特殊的迭代器,称为ListIterator
      • 除了允许Iterator接口提供的正常操作外
      • 还允许元素插入 和 替换,以及双向访问
      • 还提供了一个方法来获取从列表中指定位置开始的列表迭代器
    • List集合的特有功能概述

      • void add(int index,E element)

      • E remove(int index)

      • E get(int index)

      • E set(int index,E element)

      • package com.heima.list;
        
        import java.util.ArrayList;
        import java.util.List;
        
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public class Demo1_List {
        
            /**
            
             */
            public static void main(String[] args) {
        //        demo1();
        //        demo2();
                
        //        demo3();
        //        demo4();
            }
        
            public static void demo4() {
                /* E get(int index) 
                    返回列表中指定位置的元素。 */
                List list = new ArrayList();
                list.add("a");
                list.add(1);
                list.add(2);
                list.add("big");
                System.out.println(list.set(0, "set a new value"));
                System.out.println(list);
                
            }
            
            public static void demo3() {
                /* E get(int index) 
                    返回列表中指定位置的元素。 */
                List list = new ArrayList();
                list.add("a");
                list.add(1);
                list.add(2);
                list.add("big");
                System.out.println(list.get(0));
                
                // 通过索引遍历
                for(int i = 0;i < list.size(); i++) {
                    System.out.println(list.get(i));
                }
                
            }
        
            public static void demo2() {
                 /*
                  * E remove(int index) 
                  *     移除列表中指定位置的元素(可选操作)。 
                  * boolean remove(Object o) 
                  *     从此列表中移除第一次出现的指定元素(如果存在)(可选操作)。 
                 */
                List list = new ArrayList();
                list.add("A");
                list.add(1);
                list.add(2);
                System.out.println(list);
                list.remove(1);
                System.out.println(list);
            }
            
            public static void demo1() {
                 /*
                  * boolean add(E e) 
                  * 向列表的尾部添加指定的元素(可选操作)。
                  * 
                  *  void add(int index, E element) 
                  *  在列表的指定位置插入指定元素(可选操作)。 
                 */
                List list = new ArrayList();
                list.add("0");
                System.out.println(list);
                list.add("1");
                list.add("2");
                list.add("3");
                System.out.println(list);
                list.add(3,"add in index 3");
                list.add(list.size(),"last one");
                System.out.println(list);
            }
        }
        View Code

     

    9. List集合存储学生对象并遍历

    • 案例演示

      • 通过size()和get()方法结合使用遍历。

      • package com.heima.list;
        
        import java.util.ArrayList;
        import java.util.List;
        
        import com.heima.bean.Student;
        
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public class Demo2_List {
            public static void main(String[] args) {
                List list = new ArrayList(); 
                list.add(new Student("张三", 18)); 
                list.add(new Student("李四", 18)); 
                list.add(new Student("王五", 18)); 
                list.add(new Student("赵六", 18));
        
                for(int i = 0; i < list.size(); i++) {
                    Student s = (Student)list.get(i);
                    System.out.println(s.getName() + "," + s.getAge());
                }
            }
            
            
        }
        View Code

    10. 并发修改异常产生的原因及解决方案

    • 案例演示

      • 需求:我有一个集合,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现。

      • package com.heima.list;
        
        import java.util.ArrayList;
        import java.util.Iterator;
        import java.util.List;
        
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public class Demo3_List {
        
            /**
             需求:我有一个集合,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现。
             */
            public static void main(String[] args) {
                List list = new ArrayList(); 
                list.add("a"); 
                list.add("b"); 
                list.add("world"); 
                list.add("d"); 
                list.add("e");
                
                Iterator it = list.iterator();
                while(it.hasNext()){
                    String str = (String)it.next();
                    if(str.equals("world")) {
                        list.add("javaee");  
                        //这里会抛出ConcurrentModificationException 并发修改异常
                    }
                }
        
            
            }
        
        }
        View Code
    • ConcurrentModificationException出现

      • 迭代器遍历,集合修改集合

      • 因为遍历的同时,list在添加元素,这就是 并发修改异常
    • 解决方案

      • 迭代器迭代元素,迭代器修改元素(ListIterator的特有功能add)

      • 集合遍历元素,集合修改元素

      • package com.heima.list;
        
        import java.util.ArrayList;
        import java.util.List;
        import java.util.ListIterator;
        
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public class Demo3_List {
        
            /**
             需求:我有一个集合,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现。
             */
            public static void main(String[] args) {
                List list = new ArrayList(); 
                list.add("a"); 
                list.add("b"); 
                list.add("world"); 
                list.add("d"); 
                list.add("e");
                
                ListIterator lit = list.listIterator(); 
                //如果想在遍历的过程中添加元素,可以用ListIterator中的add方法 
                while(lit.hasNext()) { 
                    String str = (String)lit.next(); 
                    if(str.equals("world")) { 
                        lit.add("javaee"); 
                        // 输出[a, b, world, javaee, d, e]
        
                        //list.add("javaee"); } }
                    }
                }
                
                System.out.println(list);
                
            
            }
        
        }
        View Code

     

    11. ListIterator

    • boolean hasNext()   是否有下一个

    • boolean hasPrevious()   是否有前一个

    • Object next()    返回下一个元素

    • Object previous()    返回上一个元素

    • package com.heima.list;
      
      import java.util.ArrayList;
      import java.util.List;
      import java.util.ListIterator;
      
      public class Demo4_ListIterator {
      
          /**
           * @param args
           */
          public static void main(String[] args) {
              List list = new ArrayList();
              list.add("a");                                    //Object obj = new String();
              list.add("b");
              list.add("world");
              list.add("c");
              list.add("d");
              list.add("e");
              
              ListIterator lit = list.listIterator();            //获取迭代器
              while(lit.hasNext()) {
                  System.out.println(lit.next());             //迭代器向后
              }
              
              System.out.println("-----------------");
              
              while(lit.hasPrevious()) {
                  System.out.println(lit.previous());         //迭代器向前
              }
          }
      
      }
      View Code

     

    12. Vector的特有功能

    • Vector类概述

      • Vector类可以实现可增长的对象数组。
      • 与数组一样,它包含可以使用整数索引进行访问的组件。
      • Vector的大小可以根据需要增大或缩小,以适应创建Vector后进行添加或移除项的操作。
      • Vector类是从JDK1.0版本就存在的,后期改进加入List接口,使得成为Java Collections Framework的成员。与新collection实现不同,Vector是同步的。
    • Vector类特有功能

      • public void addElement(E obj)

      • public E elementAt(int index)

      • public Enumeration elements()

    • 案例演示

      • Vector的迭代

      • package com.heima.list;
        
        import java.util.Enumeration;
        import java.util.Vector;
        
        public class Demo5_Vector {
        
            /**
             * @param args
             */
            public static void main(String[] args) {
                Vector v = new Vector();
                v.addElement("a");
                v.addElement("b");
                v.addElement("c");
                v.addElement("d");
                
                Enumeration en = v.elements();                    //获取枚举
                while(en.hasMoreElements()) {                    //判断是否还有元素
                    System.out.println(en.nextElement());        //迭代下一个元素
                }
            }
        
        }
        View Code

     

    13. 数据结构之数组和链表

    • 数组

      • 查询快,修改也快

        • 因为有索引,直接找到索引即可
      • 增删慢

        • 数组是固定的大小,新增会新增1.5倍大小的数组,再存储,垃圾回收掉旧的数组
    • 链表

      • 查询慢,修改也慢

        • 只能判断是从头开始找还是从尾巴开始找比较快,一个一个找过去
      • 增删快

     

    14. List的三个子类的特点

    • List的三个子类的特点

      • ArrayList: 底层数据结构是数组,查询快,增删慢。 线程不安全,效率高。

      • Vector: 底层数据结构是数组,查询快,增删慢。 线程安全,效率低。

        • Vector相对ArrayList查询慢(线程安全的)

        • Vector相对LinkedList增删慢(数组结构)

      • LinkedList: 底层数据结构是链表,查询慢,增删快。 线程不安全,效率高。

    • Vector 和 ArrayList的区别
      • Vector是线程安全的,效率低
      • ArrayList是线程不安全的,效率高
    • Vecotr 和 ArrayList的共同点
      • 都是数组实现的
    • ArrayList 和 LinkedList 的区别
      • ArrayList底层是数组实现的,查询和修改快
      • LinkedList底层是链表结构的,增删比较快,查询和修改比较慢
    • ArrayList 和 LinkedList 的共同点
      • 都是线程不安全的
    • List有三个儿子,我们到底使用谁呢?

      • 查询多用ArrayList

      • 增删多用LinkedList

      • 如果都多ArrayList

    15. 去除ArrayList中重复字符串元素方式

    • 案例演示1
      • 需求:ArrayList去除集合中字符串的重复值(字符串的内容相同)
      • 思路:创建新集合方式
      • package com.heima.list;
        
        import java.util.ArrayList;
        import java.util.List;
        import java.util.ListIterator;
        
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public class Demo2_ArrayList {
        
            public static void main(String[] args) {
                List list = new ArrayList();
                list.add("a");
                list.add("a");
                list.add("b");
                list.add("b");
                list.add("b");
                list.add("c");
                list.add("c");
                list.add("c");
                list.add("c");
                
                System.out.println(list);
                //System.out.println(getSingle(list));
                ArrayList newList = getSingle(list);
                System.out.println(newList);
            }
        
            /*
             * 创建新集合,将重复元素去掉
             * 1. 明确返回值类型,返回ArrayList
             * 2. 明确参数列表, ArrayList
             */
            public static ArrayList getSingle(List list) {
                ListIterator lit = list.listIterator();
                ArrayList newList = new ArrayList();
                while(lit.hasNext()) {
                    Object obj = lit.next();
                    if(!newList.contains(obj)) {
                        newList.add(obj);
                    }
                }
                return newList;
            }
        }
        View Code
    • 案例演示2
      • 需求:ArrayList去除集合中自定义对象元素的重复值(对象的成员变量值相同)
      • 注意事项:重写equals()方法的
      • 参考案例1旧方法出错的原因:
        • newList.contains 的底层依赖Object类中的 equals方法,比较的自定义对象是 比较对象本身,即对象的地址。
        • 想要不出错,则在Person类(自定义类)中重写 equals方法
      • 代码:
        • package com.heima.bean;
          
          public class Person {
              private String name;
              private int age;
              
              public Person() {
                  super();
              }
          
              public Person(String name, int age) {
                  super();
                  this.name = name;
                  this.age = age;
              }
          
              public String getName() {
                  return name;
              }
          
              public void setName(String name) {
                  this.name = name;
              }
          
              public int getAge() {
                  return age;
              }
          
              public void setAge(int age) {
                  this.age = age;
              }
          
              @Override
              public String toString() {
                  return "Person [name=" + name + ", age=" + age + "]";
              }
          
              @Override
              public boolean equals(Object obj) {
                  Person p = (Person)obj;
                  return this.name.equals(p.name) && this.age == p.age;
              }
              
              
              
              
          }
          Person类 
          package com.heima.list;
          
          import java.util.ArrayList;
          import java.util.Iterator;
          
          import com.heima.bean.Person;
          
          @SuppressWarnings({ "rawtypes", "unchecked" })
          public class Demo3_ArrayList {
          
              public static void main(String[] args) {
                  ArrayList list = new ArrayList();
                  list.add(new Person("Ann",23));
                  list.add(new Person("Bill",24));
                  list.add(new Person("Ann",23));
                  list.add(new Person("Bill",24));
                  list.add(new Person("Ann",23));
                  list.add(new Person("Carolle",25));
                  list.add(new Person("Dell",26));
                  list.add(new Person("Ann",23));
                  list.add(new Person("Carolle",25));
                  list.add(new Person("Dell",26));
                  
                  ArrayList newList = getSingle(list);
                  System.out.println(newList);
          
                  
                  
              }
              
              /*
               * 创建新集合,将重复元素去掉
               * 1. 明确返回值类型,返回ArrayList
               * 2. 明确参数列表, ArrayList
               */
              public static ArrayList getSingle(ArrayList list) {
                  Iterator it = list.iterator();
                  ArrayList newList = new ArrayList();
                  while(it.hasNext()) {
                      Object obj = it.next();
                      if(!newList.contains(obj)) {
                          newList.add(obj);
                      }
                  }
                  return newList;
              }
          
          }
          View Code

    16. LinkedList的特有功能

    • LinkedList类概述
      • List接口的链接列表实现。
      • 实现所有可选的列表操作,并且允许所有元素(包括null)
      • 除了实现List接口外,LinkedList类还为在列表的开头及结尾 get、remove 和insert元素提供了统一的命令方法
      • 这些操作允许将链接列表用作堆栈、队列或双端队列。
    • LinkedList类特有功能
      • public void addFirst(E e)
      • public void addLast(E e)
      • public E getFirst()
      • public E getLast()
      • public E removeFirst()
      • public E removeLast()
      • public E get(int index)
      • package com.heima.list;
        
        import java.util.LinkedList;
        
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public class Demo1_LinkedList {
        
            /**
             * @param args
             */
            public static void main(String[] args) {
                LinkedList lis = new LinkedList();
                
                System.out.println("----addXxx方法----");
                lis.addFirst("a");
                lis.addFirst("b");
                lis.addFirst("c");
                lis.addFirst("d");
                lis.addLast("e");
                
                System.out.println(lis);
                
                System.out.println("----getXxx方法----");
                System.out.println(lis.getFirst());
                System.out.println(lis.getLast());
                
                System.out.println("----removeXxx方法----");
                lis.removeFirst();
                System.out.println(lis.getFirst());
                lis.removeLast();
                System.out.println(lis.getLast());
                
                System.out.println("----get方法----");
                System.out.println(lis);
                System.out.println(lis.get(0));  // 通过查看源码,发现是通过判断index值是否大于size的一半,离哪边近,选择从头或从末尾开始找
                System.out.println(lis.get(1));
                System.out.println(lis.get(2));
            }
        
        }
        View Code

    17. 栈和队列数据结构

      • 先进后出
    • 队列
      • 先进先出

    18. 用LinkedList模拟栈数据结构的集合并测试

    • 案例演示
      • 需求:请用LinkedList模拟栈数据结构的集合,并测试

      • 创建一个类将LinkedList中的方法封装

      • package com.heima.list;
        
        import java.util.LinkedList;
        
        public class Stack {
            private LinkedList list = new LinkedList(); 
            
            /* 
             * 模拟进栈方法
             */
            public void in(Object obj) {
                list.addLast(obj);
            }
            
            /*
             * 模拟出栈
             */
            public Object out() {
                return list.removeLast();
            }
            
            /*
             * 模拟栈结构是否为空
             */
            public boolean isEmpty() {
                return list.isEmpty();
            }
        
            @Override
            public String toString() {
                return "Stack [list=" + list + "]";
            }
            
            
        }
        封装LinkedList类,变成Stack类
        package com.heima.list;
        
        import java.util.LinkedList;
        
        @SuppressWarnings({"rawtypes","unchecked"})
        public class Demo2_LinkedList {
        
            /**
             用LinkedList模拟 栈数据 结构的集合,并测试
             */
            public static void main(String[] args) {
        //        demo1();
                Stack s = new Stack();
                s.in("a");   // 进栈
                s.in("b");
                s.in("c");
                
                while(!s.isEmpty()) {
                    System.out.println(s.out());  // 弹栈
                }
                System.out.println(s.toString());
            }
        
            public static void demo1() {
                LinkedList lis = new LinkedList();  //创建集合对象
                
                lis.addLast("a");
                lis.addLast("b");
                lis.addLast("c");
                
                while(!lis.isEmpty()) {
                    System.out.println(lis.removeLast());
                }
            }
        
        }
        演示

    19. 泛型概述和基本使用

    • 泛型概述

      • 泛型,即“参数化类型”。
      • 将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称为类型形参),然后在使用/调用时传入具体的类型(类型实参)
      • 泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型),即,在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为“泛型类”,“泛型接口”,“泛型方法”
    • 泛型好处

      • 提高安全性(将运行期的错误转换到编译期)

      • 省去强转的麻烦

    • 泛型基本使用

      • <> 中放的必须是引用数据类型

    • 泛型使用注意事项

      • 前后的泛型必须一致

      • 或者后面的泛型可以省略不写(1.7版本的新特性)

    • package com.heima.generic;
      
      import java.util.ArrayList;
      import java.util.Iterator;
      
      import com.heima.bean.Person;
      
      @SuppressWarnings({ "rawtypes", "unchecked" })
      public class Demo1_Generic {
      
          /**
           
           */
          public static void main(String[] args) {
      //        demo1();
              
      //        int[] arr = new byte[5];  // 数组要保证前后的数据类型一致
      //        ArrayList<Object> list = new ArrayList<Person>(); // 集合的泛型,要保证前后的数据类型一致
              ArrayList<Object> list = new ArrayList<>();  //1.7 版本新特性,后面的泛型可以不写
              
              /*
               * 泛型最好不要定义成Object,因为泛型可以支持其指定类型及其所有的子类。
               * Object作为所有类的父类,没有意义。
               */
              list.add(100);
              list.add("s");
              list.add(true);
          }
      
          public static void demo1() {
              ArrayList<Person> list = new ArrayList<Person>();
      //        list.add(110);
      //        list.add(true);
              list.add(new Person("Ann",23));
              
              Iterator<Person> it = list.iterator();
              while(it.hasNext()) {
                  
                  Person p = it.next();
                  System.out.println(p);
              }
          }
      
      }
      View Code

     

    20. ArrayList存储字符串和自定义对象并遍历泛型版

    • 案例演示

      • ArrayList存储字符串并遍历泛型版

      • package com.heima.generic;
        
        import java.util.ArrayList;
        import java.util.Iterator;
        
        public class Demo2_Generic {
        
            /**
            需求:ArrayList存储字符串并遍历泛型版
             */
            public static void main(String[] args) {
                ArrayList<String> list = new ArrayList<String>();
                list.add("a");
                list.add("123");
                list.add("111");
                
                Iterator<String> it = list.iterator();
                while(it.hasNext()) {
                    System.out.println(it.next());
                }
                
            }
        
        }
        View Code

    21. 泛型的由来

    • 案例演示

      • 泛型的由来:通过Object转型问题引入

      • 早期的Object类型可以接收任意的对象类型,但是在实际的使用中,会有类型转换的问题。也就存在这隐患,所以Java提供了泛型来解决这个安全问题。

      • package com.heima.generic;
        
        import com.heima.bean.Student;
        import com.heima.bean.Tool;
        import com.heima.bean.Worker;
        
        public class Demo3_Generic {
        
            /**
             
             */
            public static void main(String[] args) {
                Tool t = new Tool();  // 创建工具类对象
                t.setObj(new Student());
                
                t.setObj(new Student("Ann",23));
                
        
        //        Worker w = (Worker) t.getObj(); //向下转型
                // ClassCastException 报错,t里面getObj()获取的是Student类的向上转型Person类  Person [name=Ann, age=23]
        //        System.out.println(w);
            }
        
        }
        View Code
      • package com.heima.bean;
        
        public class Tool {
            private Object obj;
        
            public Tool() {
                super();
                
            }
        
            public Tool(Object obj) {
                super();
                this.obj = obj;
            }
        
            public Object getObj() {
                return obj;
            }
        
            public void setObj(Object obj) {
                this.obj = obj;
            }
            
            
        }
        Tool类
      • package com.heima.bean;
        
        public class Person {
            private String name;
            private int age;
            public Person() {
                super();
                
            }
            public Person(String name, int age) {
                super();
                this.name = name;
                this.age = age;
            }
            public String getName() {
                return name;
            }
            public void setName(String name) {
                this.name = name;
            }
            public int getAge() {
                return age;
            }
            public void setAge(int age) {
                this.age = age;
            }
            @Override
            public String toString() {
                return "Person [name=" + name + ", age=" + age + "]";
            }
            @Override
            public boolean equals(Object obj) {
                Person p = (Person)obj;
                //return super.equals(obj);
                return this.name.equals(p.name) && this.age == p.age;
            }
            
            
            
        }
        Person类
      • package com.heima.bean;
        
        public class Student extends Person {
        
            public Student() {
            }
        
            public Student(String name, int age) {
                super(name, age);
        
            }
        
        }
        Student类
      • Worker类

    22. 泛型类的概述及使用

    • 泛型类概述<T>

      • 把泛型定义在类上

      • package com.heima.bean;
        
        public class Tool<E> {
            private E e;
        
            public Tool() {
                super();
                
            }
        
            public Tool(E e) {
                super();
                this.e = e;
            }
        
            public E getObj() {
                return e;
            }
        
            public void setObj(E e) {
                this.e = e;
            }
            
            public void show(E e) {
                System.out.println(e);
            }
            
        }
        View Code
    • 定义格式

      • public class 类名<泛型类型1,…>

    • 注意事项

      • 泛型类型必须是引用类型

    • 案例演示

      • 泛型类的使用

     

    23. 泛型方法的概述和使用

    • 泛型方法概述

      • 把泛型定义在方法上

    • 定义格式

      • public <泛型类型> 返回类型 方法名(泛型类型 变量名)

      • 方法泛型需要与类的泛型一致
        • public class Tool<E>
        • public void show(E e)  类的泛型为E,如果方法不重新定义泛型,则需要与类泛型一致
      • 如果方法泛型要和类的泛型不一致,需要在方法上声明一个新的泛型
        • public<T> void show(T t)
        • 相当于给方法定义了一个新的泛型
      • 静态方法必须要声明一个自己的泛型
        • public static<W> void print(W w)
    • 案例演示

      • 泛型方法的使用

      • package com.heima.bean;
        
        public class Tool<E> {
            private E e;
        
            public Tool() {
                super();
                
            }
        
            public Tool(E e) {
                super();
                this.e = e;
            }
        
            public E getObj() {
                return e;
            }
        
            public void setObj(E e) {
                this.e = e;
            }
            
            public void show(E e) {
                System.out.println(e);
            }
            
            // 静态方法必须声明一个自己的泛型
            public static<W> void print(W w) {
                System.out.println(w);
            }
        }
        View Code

     

    24. 泛型接口的概述和使用

    • 泛型接口概述

      • 把泛型定义在接口上

    • 定义格式

      • public interface 接口名<泛型类型>

    • 案例演示

      • 泛型接口的使用

      • package com.heima.generic;
        
        public class Demo4_Generic {
        
            /**
             * @param args
             */
            public static void main(String[] args) {
        
            }
        
        }
        
        interface Inter<T> {
            public void show(T t);
        }
        
        // 第一种:接口泛型的使用方法,推荐
        class Demo implements Inter<String> {
        
            @Override
            public void show(String t) {
                System.out.println(t);
            }
            
        }
        
        // 第二种:接口泛型的使用方法
        // 没有必要在实现接口泛型的时候,还要给自己类加一个泛型
        class Demo2<T> implements Inter<T> {
        
            @Override
            public void show(T t) {
            }
            
        }
        View Code

     

    25. 泛型高级之通配符

    • 泛型通配符<?>

      • 任意类型,如果没有明确,那么就是Object以及任意的Java类了

    • ? extends E

      • 向下限定,E及其子类

      • package com.heima.generic;
        
        import java.util.ArrayList;
        import java.util.Collection;
        import java.util.List;
        
        import com.heima.bean.Person;
        import com.heima.bean.Student;
        
        public class Demo5_Generic {
            
            /*
             * 泛型通配符<?>
             *         任意类型,如果没有明确,那么就是Object以及任意的Java类了
             * ? extends E
             *         向下限定,E及其子类
             * ? super E
             *         向上限定,E及其父类
             */
            public static void main(String[] args) {
        //        demo1();
                
        //        demo2();
                
                
            }
        
            public static void demo2() {
                ArrayList<Person> list1 = new ArrayList<>();
                list1.add(new Person("Ann",23));
                list1.add(new Person("Bill",24));
                list1.add(new Person("Carolle",25));
                list1.add(new Person("Dell",26));
                
                ArrayList<Student> list2 = new ArrayList<>();
                list2.add(new Student("stu1",18));
                list2.add(new Student("stu2",17));
                
                list1.addAll(list2);  //  public boolean addAll(Collection<? extends E> c) 
                System.out.println(list1);
            }
        
            public static void demo1() {
                List<?> list = new ArrayList<String>();
                // 当右边的泛型是不确定时,那么左边可以指定为"?"
            }
        
        }
        View Code
    • ? super E

      • 向上限定,E及其父类

     

    26. 增强for的概述和使用

    • 增强for概述

      • 简化数组和Collection集合的遍历

    • 格式:

      • for(元素数据类型 变量 : 数组或者Collection集合) { 使用变量即可,该变量就是元素 }

      • for (int i : arr) {}
    • 案例演示

      • 数组,集合存储元素用增强for遍历

      • package com.heima.jdk5;
        
        import java.util.ArrayList;
        
        public class Demo1_Foreach {
        
            /**
             * @param args
             */
            public static void main(String[] args) {
        
                int[] arr = {11,22,33,44,55};
                // fore + alt + / 快捷键生成
                // 会找到离它最近的集合或数组,生成代码块
                for (int i : arr) {
                    System.out.println(i);
                }
                
                ArrayList<String> list = new ArrayList<>();
                list.add("a");
                list.add("b");
                list.add("c");
                list.add("d");
                
                for (String string : list) {
                    System.out.println(string);
                }
                
                
                
            }
        
        }
        View Code
    • 好处

      • 简化遍历

     

    27. ArrayList存储字符串和自定义对象并遍历增强for版

    • 案例演示

      • ArrayList存储字符串并遍历增强for版

        • package com.heima.jdk5;
          
          import java.util.ArrayList;
          
          public class Demo2_Foreach {
          
              /**
              需求:ArrayList存储字符串并遍历增强for版
              */
              public static void main(String[] args) {
                  ArrayList<String> list = new ArrayList<>(); 
                  list.add("a"); 
                  list.add("b"); 
                  list.add("c"); 
                  list.add("d");
          
                  for(String s : list) {
                      System.out.println(s);
                  }
              }
          
          }
          View Code
      • ArrayList存储自定义对象并遍历增强for板
        • package com.heima.jdk5;
          
          import java.util.ArrayList;
          
          import com.heima.bean.Person;
          
          public class Demo2_Foreach {
          
              /**
              需求:ArrayList存储字符串并遍历增强for版
              */
              public static void main(String[] args) {
                  ArrayList<Person> list = new ArrayList<>(); 
                  list.add(new Person("Ann",23));
                  list.add(new Person("Bill",24));
                  list.add(new Person("Carolle",23));
                  list.add(new Person("Dell",29));
                  list.add(new Person("Ella",30));
                  
                  for (Person person : list) {
                      System.out.println(person);
                  }
          
                  
              }
          
          }
          View Code
        • 增强for循环底层依赖的是迭代器(Iterator)

     

    28. 三种迭代的能否删除

    • 普通for循环,可以删除,但是索引要--

    • 迭代器,可以删除,但是必须使用迭代器自身的remove方法,否则会出现并发修改异常

    • 增强for循环不能删除

    package com.heima.jdk5;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    
    public class Demo3_Foreach {
    
        /**
         1. 普通for循环,可以删除,但是索引要--,即:i--
         2. 迭代器,可以删除,但是必须使用迭代器自身的remove方法,否则会出现并发修改异常
         3. 增强for循环不能删除
         */
        public static void main(String[] args) {
    //        demo1();
            
    //        demo2();
            
            demo3();
            
            
        }
    
        public static void demo3() {
            ArrayList<String> list = new ArrayList<>();
            list.add("a");
            list.add("b");
            list.add("b");
            list.add("c");
            list.add("b");
            list.add("d");
            
            for (String string : list) {
                if("b".equals(string)) {
                    // 增强for循环,不能删除,只能遍历
                }
                
            }
        }
    
        public static void demo2() {
            ArrayList<String> list = new ArrayList<>();
            list.add("a");
            list.add("b");
            list.add("b");
            list.add("c");
            list.add("b");
            list.add("d");
            
            // 迭代器遍历
            Iterator<String> it = list.iterator();
            while(it.hasNext()){
                /*it.next();
                it.remove();*/
                if("b".equals(it.next())) {
                    it.remove();
    //                list.remove("b");// 不能用集合的remove方法,会出现并发修改异常
                }
            }
            System.out.println(list);
            
            for(Iterator<String> it2 = list.iterator();it.hasNext();) {
                if("b".equals(it2.next())) {
                    it2.remove();
                }
            }
            System.out.println(list);
        }
    
        public static void demo1() {
            ArrayList<String> list = new ArrayList<>();
            list.add("a");
            list.add("b");
            list.add("b");
            list.add("c");
            list.add("b");
            list.add("d");
            
            // 第一种,普通for循环删除
            /*for(int i = 0; i < list.size(); i++) {
                list.remove(i);
                i--;
            }
            System.out.println(list);*/
            
            // 第一种,普通for循环删除,条件判断
            for(int i = 0; i < list.size(); i++) {
                if("b".equals(list.get(i))) {
                    list.remove(i);
                    i--;
                }
            }
            System.out.println(list);
        }
    
    }
    View Code

    29. 静态导入的概述和使用

    • 静态导入概述

      • 导入包中的静态方法
      • 在开发中一般是不用的
    • 格式:

      • import static 包名….类名.方法名;

      • 可以直接导入到方法的级别

    • 注意事项

      • 方法必须是静态的,如果有多个同名的静态方法,容易不知道使用谁?

      • 这个时候要使用,必须加前缀。

      • 由此可见,意义不大,所以一般不用,但是要能看懂。

    • 示例
      • package com.heima.list;
        
        import static java.util.Arrays.sort;
        
        public class Demo3_Static {
            public static void main(String[] args) {
                int[] arr = {11,44,5,56,77,99,10};
                sort(arr);
                /*
                 * 缺点:
                 * 容易对同名方法,不知道调用哪个
                 */
            }
        }
        View Code

     

    30. 可变参数的概述和使用

    • 可变参数概述

      • 定义方法的时候不知道该定义多少个参数

    • 格式

      • 修饰符 返回值类型 方法名(数据类型… 变量名){}

      • public static void func(int ... arr) {}
      • package com.heima.jdk5;
        
        public class Demo4_ChangeableArgs {
        
            /**
             * @param args
             */
            public static void main(String[] args) {
                int[] arr = {11,22,33,44,55};
                print(11, arr);
                print(1,2,3,4,5); // 将1,2,3,4,5封装成了一个 数组
            }
            
            /*public static void print(int[] arr) {
                for (int i : arr) {
                    System.out.println(i);
                }
            }
            */
            public static void print(int x , int ... arr) {  // 可变参数其实就是一个数组
                for (int i : arr) {
                    System.out.println(i);
                }
            }
        
        }
        View Code
    • 注意事项:

      • 这里的变量其实是一个数组

      • 如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个

     

    31. Arrays工具类的asList()方法的使用

    • static<T> List<T> asList(T ... a)  返回一个受指定数组支持的固定大小的列表
    • 案例演示

      • Arrays工具类的asList()方法的使用

        • package com.heima.jdk5;
          
          import java.util.Arrays;
          import java.util.List;
          
          public class Demo5_asList {
          
              /**
               * static <T> List<T> asList(T... a) 返回一个受指定数组支持的固定大小的列表。 
               * 数组转换成集合
               * 虽然不能增加或减少元素,但是可以用集合的思想操作数组,也就是说可以使用其他集合中的方法(除add和remove方法)
               */
              public static void main(String[] args) {
          //        demo1();
                  
                  int[] arr = {1,2,3,4,5};
                  List list = Arrays.asList(arr);
                  System.out.println(list); // 输出[[I@1813c12]
                  
                  List<int[]> list2 = Arrays.asList(arr);
                  System.out.println(list2);  // 输出[[I@1813c12]
                  // 上述arr中由于存储的是基本数据类型int,而List存储的是引用数据类型,故默认将整个数组作为一个对象,存储在List中
                  
                  
                  // 如果想要将arr中的每个数字变成Integer,逐个存储到List中去
                  Integer[] arr2 = {1,2,3,4,5};
                  List<Integer> list3 = Arrays.asList(arr2);
                  System.out.println(list3);  // 输出[1, 2, 3, 4, 5]
                  
                  
              }
          
              public static void demo1() {
                  String[] arr = {"a","b","c","d"};
                  List<String> list = Arrays.asList(arr);  // 将数组转换成集合
                  System.out.println(list);
                  // list.add("aaa");  // java.lang.UnsupportedOperationException
              }
          
          }
          View Code
        • 将数组转换成集合,数组必须是引用数据类型
      • Collection中toArray(T[] a)泛型版的集合转数组

        • package com.heima.list;
          
          import java.util.ArrayList;
          
          public class Demo4_Collection {
              /*
               *  Object[] toArray() 
               *      返回包含此 collection 中所有元素的数组。 
               *  <T> T[] toArray(T[] a) 
               *      返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。 
               */
              public static void main(String[] args) {
                  ArrayList<String> list = new ArrayList<>();
                  list.add("a");
                  list.add("b");
                  list.add("c");
                  list.add("d");
                  list.add("e");
                  
                  // 将集合转成数组
                  String[] arr = list.toArray(new String[0]);
                  // 当集合转换数组时,数组的长度如果是小于等于集合的size时,转换后的数组长度等于集合的size;
                  // 数组的长度如果大于集合的size时,转换后的数组长度为指定长度,且超出部分为null
                  for (String string : arr) {
                      System.out.println(string);
                  }
              }
          }
          View Code

     

    32. 集合嵌套之ArrayList嵌套ArrayList

    • 案例演示

      • 集合嵌套之ArrayList嵌套ArrayList

      • package com.heima.list;
        
        import java.util.ArrayList;
        
        import com.heima.bean.Person;
        
        public class Demo5_ArrayList {
        
            /**
             集合嵌套之ArrayList嵌套ArrayList
             */
            public static void main(String[] args) {
                ArrayList<ArrayList<Person>> list = new ArrayList<>();
                ArrayList<Person> first = new ArrayList<>(); // 创建第一个班级
                first.add(new Person("Ann",23));
                first.add(new Person("Bill",24));
                first.add(new Person("Carolle",25));
                
                ArrayList<Person> second = new ArrayList<>();
                second.add(new Person("张三",23));
                second.add(new Person("李四",24));
                second.add(new Person("王五",25));
                
                // 将班级添加到学科集合中
                list.add(first);
                list.add(second);
                
                // 遍历学科集合
                for(ArrayList<Person> a: list) {
                    for (Person person : a) {
                        System.out.println(person);
                    }
                }
                
            }
        
        }
        View Code
  • 相关阅读:
    哈希表详解
    简单字典实现(KV问题)
    【数据结构】——搜索二叉树的插入,查找和删除(递归&非递归)
    【数据结构】——堆及其应用
    初学者的迷茫
    【数据结构】顺序表和链表
    程序运行机理
    回调函数到底是怎么一回事呢?
    C语言中函数可变参数解析
    《剑指offer》数组中出现次数超过数组长度一半的数字
  • 原文地址:https://www.cnblogs.com/zoe233/p/12887465.html
Copyright © 2020-2023  润新知