【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. 集合的由来及集合继承体系图

  • 集合的由来

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

      扫描二维码关注公众号,回复: 11213277 查看本文章
    • 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. 数据结构之数组和链表

  • 数组

    • 查询快,修改也快

    • 增删慢

  • 链表

    • 查询慢,修改也慢

    • 增删快

 

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

猜你喜欢

转载自www.cnblogs.com/zoe233/p/12887465.html