13.集合

集合

  • 概念:对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能。

  • 和数组区别:

    1. 数组长度固定,集合长度不固定
    2. 数组可以存储基本类型和引用类型,集合只能存储引用类型
  • 位置:

    java.util.*;
    

Collection体系集合

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eXTrXLm3-1629187824176)(file://C:/Users/LXK/AppData/Roaming/Typora/typora-user-images/image-20210805092449217.png?lastModify=1628126803)]

Collection父接口

  • 特点:代表一组任意类型的对象,无序、无下标、不能重复。

  • 方法:

    boolean add(Object obj)// 添加一个对象
    boolean addAll(Collection c) // 将一个集合中的所有对象添加到此集合中。
    void clear() // 清空此集合中的所有对象。
    boolean contains(Object o) // 检查此集合中是否包含o对象。
    boolean equals(Object o) // 比较此集合中是否与指定对象相等。
    boolean isEmpty() // 判断此集合是否为空。
    boolean remove(Object o) // 在此集合中移除o对象。
    int size() // 返回此集合中的元素个数。
    Object[] toArray() // 将此集合转换成数组。
    
  • package gather;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Iterator;
    
    /**
     * Collection接口的使用
     * 1、添加元素
     * 2、删除元素
     * 3、遍历元素
     * 4、判断
     */
    public class Test01 {
        public static void main(String[] args) {
            // 创建集合
            Collection collection = new ArrayList();
    //         * 1、添加元素
            collection.add("苹果");
            collection.add("西瓜");
            collection.add("榴莲");
            System.out.println("元素个数:"+collection.size());//元素个数:3
            System.out.println(collection);//[苹果, 西瓜, 榴莲]
    //         * 2、删除元素
            collection.remove("榴莲");
            System.out.println("删除之后元素个数:"+collection.size());//删除之后元素个数:2
            System.out.println(collection);//[苹果, 西瓜]
    //        collection.clear();
    //        System.out.println("清空之后元素个数:"+collection.size());
    //        System.out.println(collection);
    //         * 3、遍历元素【重点】
            // (1)使用增强for
            System.out.println("----使用增强for遍历----");
            for (Object o : collection) {
                System.out.println(o);//苹果  西瓜
            }
            // (2)使用迭代器(专门用来遍历集合的方式)
            //1.hasNext();有没有下一个元素
            //2.next(); 获取下一个元素
            System.out.println("---使用Iterator迭代器---");
            Iterator iterator = collection.iterator();
            while (iterator.hasNext()){
               String s = (String) iterator.next();
                System.out.println(s);//苹果  西瓜
            }
            //3.remove(); 删除当前元素
    //        System.out.println("-----删除-----");
    //        iterator.remove();
    //        System.out.println("删除后元素个数:"+collection.size());//删除后元素个数:1
    //        for (Object o : collection) {
    //            System.out.println(o);//苹果
    //        }
    //        System.out.println("-----清空-----");
    //        collection.clear();
    //        System.out.println("清空后元素个数:"+collection.size());// 清空后元素个数:0
    //         * 4、判断
            System.out.println("-----判断-----");
            System.out.println(collection.contains("苹果"));//true
            System.out.println(collection.isEmpty());// false
    
        }
    }
    
  • package gather.Student;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Iterator;
    
    /**
     * Collection的使用:保存学生信息
     */
    public class Test02 {
        public static void main(String[] args) {
            // 新建Collection对象
            Collection collection = new ArrayList();
            Student s1 = new Student("张三", 20);
            Student s2 = new Student("张无忌", 18);
            Student s3 = new Student("王二", 22);
            // 1.添加数据
            collection.add(s1);
            collection.add(s2);
            collection.add(s3);
            System.out.println("元素个数"+collection.size());//元素个数3
            System.out.println(collection.toString());// [Student [name=张三,age=20], Student [name=张无忌,age=18], Student [name=王二,age=22]]
            // 2.删除
            collection.remove(s1);
            System.out.println("删除之后:"+collection.size());//删除之后:2
            System.out.println(collection.toString());//[Student [name=张无忌,age=18], Student [name=王二,age=22]]
            // 清空,清空的是对象的地址(引用),对象本身并未删除。
    //        collection.clear();
    //        System.out.println("清空之后:"+collection.size());//清空之后:0
            // 3.遍历
            //1.增强for
            System.out.println("----增强for遍历----");
            /*
            ----增强for遍历打印结果----
                 Student [name=张无忌,age=18]
                 Student [name=王二,age=22]
             */
            for (Object o : collection) {
                Student s = (Student) o;
                System.out.println(o.toString());// 
    //            System.out.println(o);
            }
            //2.迭代器:hasNext()  next(); remove(); 迭代过程中不能使用collection的删除方法。
            System.out.println("---迭代遍历---");
            /*
            ----迭代器遍历打印结果----
                 Student [name=张无忌,age=18]
                 Student [name=王二,age=22]
             */
            Iterator iterator = collection.iterator();
            while (iterator.hasNext()){
                // 一定要强转换
                 Student student = (Student)iterator.next();
                System.out.println(student.toString());
            }
            // 4.判断
            System.out.println(collection.contains(s1));// 被删除了,所以打印结果:false
            System.out.println(collection.contains(s2));// true
            System.out.println(collection.isEmpty()); // false
        }
    }
    

List子接口

  • 特点:有序、有下标、元素可以重复。

  • 方法:

    • void add(int index,Object o) // 在index位置插入对象o。
      boolean addAll(int index,Colection c) // 将一个集合中的元素添加到此集合中的index位置。
      Object get(int index) // 返回集合中指定位置的元素。
      List subList(int fromIndex,int toIndex) // 返回fromIndex和toIndex之间的集合元素。
      
    • package gather.List;
      
      import java.lang.reflect.Array;
      import java.util.ArrayList;
      import java.util.Iterator;
      import java.util.List;
      import java.util.ListIterator;
      
      /**
       *List接口的使用
       * 特点:1.有序有下标 2.可以重复
       */
      public class Test01 {
          public static void main(String[] args) {
              // 先创建集合对象
              List list = new ArrayList<>();
              //1.添加元素
              list.add("苹果");
              list.add("小米");
              list.add("华为");
              System.out.println("元素个数:"+list.size());//元素个数:3
              System.out.println(list.toString());//[苹果, 小米, 华为]
              //2.删除元素
              // list.remove("苹果");
      //        list.remove(0);
      //        System.out.println("删除之后:"+list.size());
      //        System.out.println(list.toString());
              // 3.遍历【重点】
              //1.使用for遍历
              System.out.println("---使用for遍历---");
              for (int i = 0; i <list.size() ; i++) {
                  System.out.println(list.get(i));
              }
              // 2.使用增强for
              System.out.println("---使用增强for遍历---");
              /*
                 打印结果为:
                      苹果
                      小米
                      华为
               */
              for (Object o : list) {
                  System.out.println(o);
              }
              //3.使用迭代器
              System.out.println("---使用迭代器遍历---");
              /*
                  打印结果为:
                      苹果
                      小米
                      华为
               */
              Iterator iterator = list.iterator();
              while (iterator.hasNext()){
                  System.out.println(iterator.next());
              }
              //4.使用列表迭代器(新增),和Iterator的区别。
              //ListIterator可以向前或向后遍历,添加,删除,修改元素。
              ListIterator listIterator = list.listIterator();
              System.out.println("----使用列表迭代器从前往后----");
              /*
              打印结果为:
                  0:苹果
                  1:小米
                  2:华为
               */
              while (listIterator.hasNext()){
                  System.out.println(listIterator.nextIndex()+":"+listIterator.next());
              }
              System.out.println("----使用列表迭代器从后往前----");
              /*
              打印结果为:
                  2:华为
                  1:小米
                  0:苹果
               */
              while (listIterator.hasPrevious()){
                  System.out.println(listIterator.previousIndex()+":"+listIterator.previous());
              }
              //4.判断
              System.out.println(list.contains("苹果"));//true
              System.out.println(list.isEmpty());//false
              //5.获取“华为”在集合的位置
              System.out.println(list.indexOf("华为"));//2
          }
      }
      
    • package gather.List;
      
      import java.util.ArrayList;
      import java.util.List;
      
      /**
       * List的使用
       */
      public class Test02 {
          public static void main(String[] args) {
              // 创建对象
              List list = new ArrayList();
              // 1.添加数字数据(自动装箱)
              list.add(20);
              list.add(30);
              list.add(40);
              list.add(50);
              list.add(60);
              System.out.println("元素个数:"+list.size());//元素个数:5
              System.out.println(list.toString());//[20, 30, 40, 50, 60]
              // 2.删除操作
      //        list.remove(1);
      //        System.out.println("元素个数:"+list.size());//元素个数:4
      //        System.out.println(list.toString());//[20, 40, 50, 60]
      
      //        list.remove(new Integer(20));
      //        System.out.println("元素个数:"+list.size());//元素个数:4
      //        System.out.println(list.toString());//[30, 40, 50, 60]
              
              //3.补充方法subList,返回子集合,含头不含尾
              List list1 = list.subList(1, 3);
              System.out.println(list1.toString());//[30, 40]
          }
      }
      

List实现类

  • ArrayList【重点】:

    源码分析:默认容量DEFAULT_CAPACITY = 10;

    ​ 注意:如果没有向集合中添加任何元素时,容量为0,添加一个元素后容量为10,每次扩容大小为原来的1.5倍。

    ​ 存放元素的数组 elementData

    ​ 实际元素个数:size

    package gather.ArrayList;
    
    import gather.Student.Student;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.ListIterator;
    
    /**
     * ArrayList的使用
     * 存储结构:数组,查找遍历速度快、增删慢
     */
    public class Test01 {
        public static void main(String[] args) {
            //创建集合
            ArrayList arrayList = new ArrayList<>();
            //1.添加元素
            Student s1 = new Student("刘德华",20);
            Student s2 = new Student("郭富城",22);
            Student s3 = new Student("梁朝伟",18);
            arrayList.add(s1);
            arrayList.add(s2);
            arrayList.add(s3);
            System.out.println("元素个数"+arrayList.size());//元素个数3
            System.out.println(arrayList.toString());//[Student [name=刘德华,age=20], Student [name=郭富城,age=22], Student [name=梁朝伟,age=18]]
            //2.删除元素
    //        System.out.println("---删除元素---");;
    //        arrayList.remove(s1);
    //        System.out.println("删除之后元素个数:"+arrayList.size());//删除之后元素个数:2
    //        System.out.println(arrayList.toString());//[Student [name=郭富城,age=22], Student [name=梁朝伟,age=18]]
            //3.遍历元素【重点】
            //1.使用迭代器
            System.out.println("---使用迭代器---");
            /**
             * Student [name=刘德华,age=20]
             * Student [name=郭富城,age=22]
             * Student [name=梁朝伟,age=18]
             */
            Iterator iterator = arrayList.iterator();
            while (iterator.hasNext()){
                Student student = (Student) iterator.next();
                System.out.println(student.toString());
            }
            //2.增强for遍历
            /**
             *Student [name=刘德华,age=20]
             *Student [name=郭富城,age=22]
             *Student [name=梁朝伟,age=18]
             */
    //        System.out.println("---使用增强for循环---");
    //        for (Object o : arrayList) {
    //            Student o1 = (Student) o;
    //            System.out.println(o1.toString());
    //        }
            // 3.列表迭代器
            /**
             * Student [name=刘德华,age=20]
             * Student [name=郭富城,age=22]
             * Student [name=梁朝伟,age=18]
             */
            System.out.println("---使用列表迭代器遍历---");
            ListIterator listIterator = arrayList.listIterator();
            while (listIterator.hasNext()){
                Student student = (Student) listIterator.next();
                System.out.println(student.toString());
            }
            //4.列表迭代器逆序
            /**
             * Student [name=梁朝伟,age=18]
             * Student [name=郭富城,age=22]
             * Student [name=刘德华,age=20]
             */
            System.out.println("---逆序---");
            while (listIterator.hasPrevious()){
                Student student = (Student) listIterator.previous();
                System.out.println(student.toString());
            }
            // 判 断
            System.out.println(arrayList.contains(s1));//true
            System.out.println(arrayList.isEmpty());//false
            //查找
            System.out.println(arrayList.indexOf(s2));//1
        }
    }
    
    • 数组结构实现,查询快、增删慢;
    • JDK1.2版本,运行效率快,线程不安全。
  • Vector:

    • 数组结构实现,查询快,增删慢;
    • JDK1.0版本,运行效率慢、线程安全。
package Vector;

import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;

/**
 * 演示Vector集合的使用
 * 存储结构:数组
 */
public class Test01 {
    public static void main(String[] args) {
        // 创建集合
        Vector vector = new Vector<>();
        //1.添加元素
        vector.add("草莓");
        vector.add("芒果");
        vector.add("西瓜");
        System.out.println("元素个数:"+vector.size());//元素个数:3
        // 2.删除
//        vector.remove(0);
//        vector.remove("西瓜");
//        vector.clear();
        // 3.遍历

        System.out.println("---增强for循环遍历---");
        /**
         * ---增强for循环遍历---
         * 草莓
         * 芒果
         * 西瓜
         */
        for (Object o : vector) {
            String str = (String)o;
            System.out.println(str.toString());
        }
        System.out.println("---使用迭代器遍历---");
        /**
         * ---使用迭代器遍历---
         * 草莓
         * 芒果
         * 西瓜
         */
        Iterator iterator = vector.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        System.out.println("---使用枚举器遍历---");
        /**
         * ---使用枚举器遍历---
         * 草莓
         * 芒果
         * 西瓜
         */
        Enumeration elements = vector.elements();
        while (elements.hasMoreElements()){
//            Object o = elements.nextElement();
//            String str = (String) o;
            String str =(String) elements.nextElement();
            System.out.println(str);
        }

        // 4.判 断
        System.out.println(vector.contains("西瓜"));//true
        System.out.println(vector.isEmpty());//false
    }

}
  • LinkedList:

    • 链表结构实现,增删快,查询相对慢。
    package LinkedList;
    
    import gather.Student.Student;
    
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.ListIterator;
    
    /**
     * LinkList的使用
     * 存储结构:双向链表
     */
    public class Test01 {
        public static void main(String[] args) {
            // 创建集合
            LinkedList linkedList = new LinkedList<>();
            //1.添加元素
            Student s1 = new Student("刘德华",20);
            Student s2 = new Student("郭富城",22);
            Student s3 = new Student("梁朝伟",18);
            linkedList.add(s1);
            linkedList.add(s2);
            linkedList.add(s3);
            System.out.println("元素个数"+linkedList.size());//元素个数3
            System.out.println(linkedList.toString());//[Student [name=刘德华,age=20], Student [name=郭富城,age=22], Student [name=梁朝伟,age=18]]
            //2.删除
    //        linkedList.remove(s1);
    //        System.out.println("元素个数"+linkedList.size());//元素个数2
    //        System.out.println(linkedList.toString());//[Student [name=郭富城,age=22], Student [name=梁朝伟,age=18]]
            //3.遍历
            //使用for遍历
            System.out.println("---使用for遍历---");
            /**
             * ---使用for遍历---
             * Student [name=刘德华,age=20]
             * Student [name=郭富城,age=22]
             * Student [name=梁朝伟,age=18]
             */
            for (int i = 0; i <linkedList.size() ; i++) {
                System.out.println(linkedList.get(i));
            }
            //使用增强for遍历
            System.out.println("---使用增强for遍历---");
            /**
             * ---使用增强for遍历---
             * Student [name=刘德华,age=20]
             * Student [name=郭富城,age=22]
             * Student [name=梁朝伟,age=18]
             */
            for (Object o : linkedList) {
                Student student = (Student)o;
                System.out.println(student.toString());
            }
            //使用迭代器
            System.out.println("---使用迭代器遍历---");
            /**
             * ---使用迭代器遍历---
             * Student [name=刘德华,age=20]
             * Student [name=郭富城,age=22]
             * Student [name=梁朝伟,age=18]
             */
            Iterator iterator = linkedList.iterator();
            while (iterator.hasNext()){
                Student student = (Student)iterator.next();
                System.out.println(student.toString());
            }
            //使用listIterator列表迭代器遍历
            System.out.println("---使用列表迭代器遍历---");
            /**
             * ---使用列表迭代器遍历---
             * Student [name=刘德华,age=20]
             * Student [name=郭富城,age=22]
             * Student [name=梁朝伟,age=18]
             */
            ListIterator listIterator = linkedList.listIterator();
            while (listIterator.hasNext()){
                Student student1 = (Student)listIterator.next();
                System.out.println(student1.toString());
            }
            System.out.println("---逆序---");
            /**
             * ---逆序---
             * Student [name=梁朝伟,age=18]
             * Student [name=郭富城,age=22]
             * Student [name=刘德华,age=20]
             */
            while (listIterator.hasPrevious()){
                Student student1 = (Student)listIterator.previous();
                System.out.println(student1.toString());
            }
            //4.判断
            System.out.println(linkedList.contains(s1));//true
            System.out.println(linkedList.isEmpty());//false
            //5.获取
            System.out.println(linkedList.indexOf(s2));//1
        }
    }
    

泛型

  • Java泛型是JDK1.5中引入的一个新特性,其本质是参数类型,把类型作为参数传递。

  • 常见形式有泛型类、泛型接口、泛型方法。

  • 语法:

    • <T,…> T称为类型占位符,表示一种引用类型
  • package gather.FanXing;
    
    public class TestGeneric {
        public static void main(String[] args) {
            //使用泛型类T来创建对象
            /*
                注意:
                     1.泛型只能使用引用类型。
                     2.不同泛型类型对象之间不能相互赋值。
             */
            MyGeneric<String> myGeneric = new MyGeneric<String>();
            myGeneric.t = "Hello";
            myGeneric.show("大家好,加油!");
            String string = myGeneric.getT();
    
            MyGeneric<Integer> myGeneric1 = new MyGeneric<Integer>();
            myGeneric1.t = 100;
            myGeneric1.show(200);
            Integer integer = myGeneric1.getT();
        }
    }
    
    package gather.FanXing;
    
    /**
     * 泛型类
     * 语法:类名<T,...>
     *     T表示类型占位符,表示一种引用类型,若编写多个,使用逗号隔开。
     */
    // 泛型类
    public class MyGeneric<T> {
        // 使用泛型T(不能实例化)
        //1.创建变量
        T t;
        //2.泛型作为方法的参数
        public void show(T t){
            System.out.println(t);
        }
        //3.泛型作为方法的返回值
        public T getT(){
            return t;
        }
    }
    
  • 泛型接口:

    • package gather.FanXing;
      
      public class TestGeneric {
          public static void main(String[] args) {
              //使用泛型类T来创建对象
              /*
                  注意:
                       1.泛型只能使用引用类型。
                       2.不同泛型类型对象之间不能相互赋值。
               */
              MyGeneric<String> myGeneric = new MyGeneric<String>();
              myGeneric.t = "Hello";
              myGeneric.show("大家好,加油!");// 大家好,加油!
              String string = myGeneric.getT();
      
              MyGeneric<Integer> myGeneric1 = new MyGeneric<Integer>();
              myGeneric1.t = 100;
              myGeneric1.show(200);//200
              Integer integer = myGeneric1.getT();
              // 泛型接口,参数类型已经固定
              MyInterfaceTest test = new MyInterfaceTest();
              test.server("xxxxx");//xxxxx
              // 两个泛型类,参数类型为任意类型
              MyInterfaceTest2 test2 = new MyInterfaceTest2();
              test2.server(10000);//100000
          }
      }
      
      package gather.FanXing;
      
      /**
       * 泛型接口
       * 语法:接口名<T>
       *     注意:不能使用泛型来创建静态常量
       */
      public interface MyInterface<T> {
          String name = "张三";
          T server(T t);
      }
      
      package gather.FanXing;
      
      public class TestGeneric {
          public static void main(String[] args) {
              //使用泛型类T来创建对象
              /*
                  注意:
                       1.泛型只能使用引用类型。
                       2.不同泛型类型对象之间不能相互赋值。
               */
              MyGeneric<String> myGeneric = new MyGeneric<String>();
              myGeneric.t = "Hello";
              myGeneric.show("大家好,加油!");// 大家好,加油!
              String string = myGeneric.getT();
      
              MyGeneric<Integer> myGeneric1 = new MyGeneric<Integer>();
              myGeneric1.t = 100;
              myGeneric1.show(200);//200
              Integer integer = myGeneric1.getT();
              // 泛型接口,参数类型已经固定
              MyInterfaceTest test = new MyInterfaceTest();
              test.server("xxxxx");//xxxxx
              // 两个泛型类,参数类型为任意类型
              MyInterfaceTest2 test2 = new MyInterfaceTest2();
              test2.server(10000);//100000
          }
      }
      
      package gather.FanXing;
      
      public class MyInterfaceTest2<T> implements MyInterface<T> {
          @Override
          public T server(T t) {
              System.out.println(t);
              return t;
          }
      }
      
  • 泛型方法:

    • package gather.FanXing;
      
      public class TestGeneric {
          public static void main(String[] args) {
                  //泛型方法  类型与传递的参数有关
              MyGenericMethod myGenericMethod = new MyGenericMethod();
              myGenericMethod.show(12);
          }
      }
      
      package gather.FanXing;
      
      /**
       * 泛型方法
       * 语法:<T>,返回值类型
       */
      public class MyGenericMethod {
      
          // 泛型方法
          public <T> void show(T t){
              System.out.println("泛型方法");
              return;
          }
      }
      
  • 好处:

    1. 提高代码的重要性
    2. 防止类型转换异常,提高代码的安全性

泛型集合

  • 概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致。

  • 特点:

    • 编译时及时检查,并非运行时抛出异常。
    • 访问时,不必类型转换(拆箱)。
    • 不同泛型之间引用不能相互赋值,泛型不存在多态。

Set集合概述

Set子接口
  • 特点:无序、无下标、元素不可重复。

  • 方法:全部继承自Collection中的方法

package gather.Set;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * 测试Set接口的使用
 * 特点:(1)无序 、没有下标  (2)不能重复
 */
public class Test01 {
    public static void main(String[] args) {
        //创建集合
        Set<String> set = new HashSet<>();
        //1.添加数据
        set.add("华为");
//        set.add("华为");
        set.add("苹果");
        set.add("小米");
        System.out.println("数据个数"+set.size());//数据个数3
        System.out.println(set.toString());//[苹果, 华为, 小米]
        //2.删除数据
//        set.remove("小米");
//        System.out.println(set.toString());
        //3.遍历【重点】
        //使用增强for
        /**
         * ---使用增强for循环遍历---
         * 苹果
         * 华为
         * 小米
         */
        System.out.println("---使用增强for循环遍历---");
        for (String s : set) {
            System.out.println(s);
        }
        //使用迭代器
        /**
         * ---使用迭代器遍历---
         * 苹果
         * 华为
         * 小米
         */
        System.out.println("---使用迭代器遍历---");
        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //4.判断
        System.out.println(set.contains("华为"));//true
        System.out.println(set.isEmpty());//false
    }
}
Set实现类
  • HashSet【重点】

    • 基于HashCode实现元素不重复。

    • 当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入。

    • package gather.Set;
      
      import java.util.HashSet;
      import java.util.Iterator;
      
      /**
       * HashSet集合的使用
       * 存储结构:哈希表(数组+链表+红黑树)
       */
      public class Test02 {
          public static void main(String[] args) {
              //新建集合
              HashSet<String> hashSet = new HashSet<>();
              //1.添加元素
              hashSet.add("刘德华");
              hashSet.add("林志玲");
              hashSet.add("周润发");
              hashSet.add("梁朝伟");
      //        hashSet.add("刘德华");//不允许重复
              System.out.println("元素个数:"+hashSet.size());//元素个数:4
              System.out.println(hashSet.toString());//[林志玲, 梁朝伟, 周润发, 刘德华]
              //2.删除数据
              hashSet.remove("刘德华");
              System.out.println("元素个数:"+hashSet.size());//元素个数:3
              System.out.println(hashSet.toString());//[林志玲, 梁朝伟, 周润发]
              //3.遍历
              //增强for循环遍历
              /**
               * ---增强for循环遍历---
               * 林志玲
               * 梁朝伟
               * 周润发
               */
              System.out.println("---增强for循环遍历---");
              for (String s : hashSet) {
                  System.out.println(s);
              }
              //迭代器遍历
              /**
               * ----使用迭代器遍历----
               * 林志玲
               * 梁朝伟
               * 周润发
               */
              System.out.println("----使用迭代器遍历----");
              Iterator<String> iterator = hashSet.iterator();
              while (iterator.hasNext()){
                  System.out.println(iterator.next());
              }
              //4.判断
              System.out.println(hashSet.contains("郭富城"));//false
          }
      }
      
    • package gather.Set;
      
      import java.util.HashSet;
      
      /**
       *  * HashSet集合的使用
       *  * 存储结构:哈希表(数组+链表+红黑树)
       *  存储过程:
       *  (1)根据hashcode计算保存的位置,如果此位置为空,则直接保存,如果不为空则执行第二步
       *  (2)在执行eqyals方法,如果equals方法为true,则认为是重复,否则,形成链表
       */
      public class Test03 {
          public static void main(String[] args) {
              //创建集合
              HashSet<Persion> persions = new HashSet<>();
              //1.添加集合
              Persion persion = new Persion("刘德华",20);
              Persion persion1 = new Persion("林志玲",18);
              Persion persion2 = new Persion("梁朝伟",22);
              persions.add(persion);
              persions.add(persion1);
              persions.add(persion2);
      //        persions.add(persion2);//重复,不能添加
              persions.add(new Persion("梁朝伟",22));
              System.out.println("元素个数:"+persions.size());
              System.out.println(persions.toString());
      
          }
      }
      
      package gather.Set;
      
      /**
       * 人类
       */
      public class Persion {
          private String name;
          private int age;
      
          public Persion() {
          }
      
          public Persion(String name, int age) {
              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 "Persion [name="+name+", age="+age+"]";
          }
      
          @Override
          public int hashCode() {
              int n1 = this.name.hashCode();
              int n2 = this.age;
              return n1+n2;
          }
      
          @Override
          public boolean equals(Object obj) {
              if (this==obj){
                  return true;
              }
              if (obj==null){
                  return false;
              }
              if (obj instanceof Persion){
                  Persion p = (Persion)obj;
                  if (this.name.equals(p.getName())&&this.age ==p.getAge()){
                      return true;
                  }
              }
              return false;
          }
      }
      
  • TreeSet:

    • 基于排列顺序实现元素不重复。
    • 实现了SortedSet接口,对集合元素自动排序。
    • 元素对象的类型必须实现Comparable接口,指定排序规则。
    • 通过CompareTo方法确定是否为重复元素。
  • package gather.Set;
    
    import java.util.TreeSet;
    
    /**
     *  * TreeSet的使用
     *  * 存储结构:红黑树
     *  要求:元素必须实现Comparable接口,compareTo()方法返回值为0,认为是重复元素
     */
    public class Test05 {
        public static void main(String[] args) {
            //1.创建集合
            TreeSet<Persion> persions = new TreeSet<>();
            Persion persion = new Persion("lxk",20);
            Persion persion1 = new Persion("abc",18);
            Persion persion2 = new Persion("zeh",22);
            Persion persion3 = new Persion("zeh",24);
            persions.add(persion);
            persions.add(persion1);
            persions.add(persion2);
            persions.add(persion3);
            System.out.println("元素个数"+persions.size());
            System.out.println(persions.toString());
            //2.删除
            persions.remove(persion1);
            System.out.println(persions.size());
    
        }
    }
    
    package gather.Set;
    
    /**
     * 人类
     */
    public class Persion implements Comparable<Persion> {
        private String name;
        private int age;
    
        public Persion() {
        }
    
        public Persion(String name, int age) {
            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 "Persion [name="+name+", age="+age+"]";
        }
    
        @Override
        public int hashCode() {
            int n1 = this.name.hashCode();
            int n2 = this.age;
            return n1+n2;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this==obj){
                return true;
            }
            if (obj==null){
                return false;
            }
            if (obj instanceof Persion){
                Persion p = (Persion)obj;
                if (this.name.equals(p.getName())&&this.age ==p.getAge()){
                    return true;
                }
            }
            return false;
        }
    // 先按姓名比,再按年龄比
        @Override
        public int compareTo(Persion o) {
            int n1 = this.getName().compareTo(o.getName());
            int n2 = this.age-o.getAge();
            return n1 == 0 ? n2 : n1;
    
        }
    }
    
    comparator:是实现定制比较器
    /**
     * TreeSet集合的使用
     * Comparator:是实现定制比较(比较器)
     * Comparable:可比较的
     */
    public class Test06 {
        public static void main(String[] args) {
            // 创建集合并制定比较规则
            TreeSet<Persion> persions = new TreeSet<>(new Comparator<Persion>() {
                @Override
                public int compare(Persion o1, Persion o2) {
                    int n1 = o1.getAge()-o2.getAge();
                    int n2 = o1.getName().compareTo(o2.getName());
                    return n1==0? n2 : n1;
                }
            });
    
    TreeSet案例
    package gather.Set.anli;
    
    import java.util.Comparator;
    import java.util.TreeSet;
    
    /**
     * 要求:使用TreeSet集合实现字符串按照长度排序
     * helloworld  zhang  lisi  wangwu  beijing  xian  nanjing
     * Comparator接口实现定制比较
     */
    public class Test07 {
        public static void main(String[] args) {
            //创建集合,并制定比较规则
            TreeSet<String> treeSet = new TreeSet<>(new Comparator<String>() {
                @Override
                public int compare(String o1, String o2) {
                    int n1 = o1.length()-o2.length();
                    int n2 = o1.compareTo(o2);
                    return n1==0 ? n2:n1;
                }
            });
            // 添加数据
            treeSet.add("helloworld");
            treeSet.add("pingguo");
            treeSet.add("lisi");
            treeSet.add("zhangsan");
            treeSet.add("beijing");
            treeSet.add("cat");
            treeSet.add("nanjing");
            treeSet.add("xian");
            System.out.println(treeSet.toString());
        }
    }
    

Map集合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zDeUmSPn-1629187824178)(C:\Users\LXK\AppData\Roaming\Typora\typora-user-images\image-20210807104200341.png)]

  • Map接口特点:
    1. 用于存储任意键值对(Key-Value)
    2. 键:无序、无下标、不允许重复(唯一)
    3. 值:无序、无下标、允许重复

Map接口

  • 特点:存储一对数据(Key-Value),无序、无下标,键不可重复,值可重复。

  • 方法:

    • V put(K key,V value) //将对象存入到集合中,关联键值。key重复则覆盖原值。
      Object get(Object key) // 根据键获取对应的值。
      KeySet<K> // 返回所有key。
      Collection<V> values() //返回包含所有值的Collection集合。
      Set<Map,Entry<K,V>> // 键值匹配的Set集合。
      
  • package gather.Map;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    
    /**
     * Map接口的使用
     * 特点:1.存储键值对 2.键不能重复,值可以重复 3.无序
     */
    public class Test01 {
        public static void main(String[] args) {
            //创建Map集合
            Map<String, String> map = new HashMap<>();
            //1.添加元素
            map.put("cn","中国");
            map.put("uk","英国");
            map.put("usa","美国");
            map.put("cn","zhongguo");//键唯一,把前面的“中国”替换掉了
            System.out.println("元素个数:"+map.size());//元素个数:3
            System.out.println(map.toString());//{usa=美国, uk=英国, cn=zhongguo}
            // 2.删除
    //        map.remove("usa");
    //        System.out.println("删除之后:"+map.size());//删除之后:2
    //        System.out.println(map.toString());//{uk=英国, cn=zhongguo}
            //3.遍历
            //3.1使用keySet();
            /**
             * usa---美国
             * uk---英国
             * cn---zhongguo
             */
            System.out.println("---使用keySet遍历---");//---使用keySet遍历---
            Set<String> keySet = map.keySet();
            for (String key : keySet) {
                System.out.println(key+"---"+map.get(key));
            }
            //3.2使用entrySet()方法
            /**
             * ---使用entrySet()方法---
             * usa----美国
             * uk----英国
             * cn----zhongguo
             */
            System.out.println("---使用entrySet()方法---");
            Set<Map.Entry<String, String>> entries = map.entrySet();
            for (Map.Entry<String, String> entry : entries) {
                System.out.println(entry.getKey()+"----"+entry.getValue());
            }
            //4.判断
            System.out.println(map.containsKey("cn"));//true
            System.out.println(map.containsKey("泰国"));//false
    
        }
    }
    

Map集合的实现类

  • HashMap【重点】:

    • JDK1.2版本,线程不安全,运行效率快:允许用null去哦为key或是value。

    • package gather.Map;
      
      import gather.Set.Persion;
      
      import java.util.HashMap;
      import java.util.Map;
      
      /**
       * HashMap集合的使用
       * 存储结构:哈希表(数组+链表+红黑树)
       * 使用key的hashcode和equals作为重复依据
       */
      public class Test02 {
          public static void main(String[] args) {
              // 创建集合
              HashMap<Student, String> students = new HashMap<Student,String>();
              //添加元素
              Student s1 = new Student("孙悟空",100);
              Student s2 = new Student("猪八戒",101);
              Student s3 = new Student("沙和尚",102);
      //        Student s4 = new Student("沙和尚",102);
              students.put(s1,"北京");
              students.put(s2,"上海");
              students.put(s3,"杭州");
      //        students.put(s4,"北京");
      //        students.put(s3,"南京");
              students.put(new Student("沙和尚",102),"周口");//因为key不能重复,覆盖了原先的杭州
              System.out.println("元素个数:"+students.size());//素个数:3
              System.out.println(students.toString());//{Student [name=猪八戒,sno=101]=上海, Student [name=沙和尚,sno=102]=周口, Student [name=孙悟空,sno=100]=北京}
              //删除
      //        students.remove(s1);
      //        System.out.println("元素个数:"+students.size());
      //        System.out.println(students.toString());
              //遍历
              //1.使用keySet();
              System.out.println("---使用keySet遍历---");
              /**
               * ---使用keySet遍历---
               * Student [name=猪八戒,sno=101]===上海
               * Student [name=沙和尚,sno=102]===周口
               * Student [name=孙悟空,sno=100]===北京
               */
              for (Student key : students.keySet()) {
                  System.out.println(key.toString()+"==="+students.get(key));
              }
              //2.使用entrySet()
              System.out.println("---使用entrySet遍历---");
              /**
               * ---使用entrySet遍历---
               * Student [name=猪八戒,sno=101]-----上海
               * Student [name=沙和尚,sno=102]-----周口
               * Student [name=孙悟空,sno=100]-----北京
               */
              for (Map.Entry<Student, String> entry : students.entrySet()) {
                  System.out.println(entry.getKey()+"-----"+entry.getValue());
              }
              //判断
              System.out.println(students.containsKey(s1));//true
              System.out.println(students.containsValue("杭州"));//false
              System.out.println(students.isEmpty());//false
          }
      }
      
      package gather.Map;
      
      import java.util.Objects;
      
      public class Student {
          private String name;
          private int sno;
      
          public Student(String name, int sno) {
              this.name = name;
              this.sno = sno;
          }
      
          public Student() {
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public int getSno() {
              return sno;
          }
      
          public void setSno(int sno) {
              this.sno = sno;
          }
      
          @Override
          public boolean equals(Object o) {
              if (this == o) return true;
              if (o == null || getClass() != o.getClass()) return false;
              Student student = (Student) o;
              return sno == student.sno && Objects.equals(name, student.name);
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(name, sno);
          }
      
          @Override
          public String toString() {
              return "Student [name=" + name + ",sno=" + sno + "]";
          }
      }
      

源码分析

默认初始化容量:static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

数组最大容量:static final int MAXIMUM_CAPACITY = 1 << 30;
默认加载因子:static final float DEFAULT_LOAD_FACTOR = 0.75f;

链表调整为红黑树的链表长度阈值(JDK1.8):static final int TREEIFY_THRESHOLD = 8;

红黑树调整为链表的链表长度阈值(JDK1.8):static final int UNTREEIFY_THRESHOLD = 6;

链表调整为红黑树的数组最小阈值(JDK1.8):static final int MIN_TREEIFY_CAPACITY = 64;

HashMap存储的数组:transient Node<K,V>[] table;

HashMap存储的元素个数:transient int size;

总结

HashMap刚创建时,table是null,节省空间,当添加第一个元素时,table容量调整为16
当元素个数大于阈值(16*0.75 = 12)时,会进行扩容,扩容后的大小为原来的两倍,目的是减少调整元素的个数
jdk1.8 当每个链表长度 >8 ,并且数组元素个数 ≥64时,会调整成红黑树,目的是提高效率
jdk1.8 当链表长度 <6 时 调整成链表
jdk1.8 以前,链表时头插入,之后为尾插入

Map集合的实现类

  • HashMap【重点】:
    • JDK1.2版本,线程不安全,运行效率快:允许用null去哦为key或是value。
  • Hashtable:
    • JDK1.0版本,线程安全,运行效率慢;不允许null作为key或是value。
  • Properties:
    • Hashtable的子类,要求key和value都是String。通常用于配置文件的读取。
  • TreeMap:
    • 实现了SortedMap接口(是Map的子接口),可以对key自动排序。

Collection工具类

  • 概念:集合工具类,定义了除了存储以外的集合常用方法。

  • 方法:

    • public static void reverse(List<?> list) //反转集合中元素的排序
      public static void shuffle(List<?> list) // 随机重置集合元素的排序
      public static void sort(List<T> list) // 升序排序(元素类型必须实现Compare接口)
      
  • package gather.Map.Collection;
    
    import java.util.*;
    
    /**
     * 演示Collection工具类的使用
     */
    public class Test {
        public static void main(String[] args) {
            List<Integer> list = new ArrayList<>();
            list.add(20);
            list.add(5);
            list.add(13);
            list.add(30);
            list.add(4);
            list.add(6);
            //sort排序前
            System.out.println(list.toString());//[20, 5, 13, 30, 4, 6]
            Collections.sort(list);//[4, 5, 6, 13, 20, 30]
            //排序后
            System.out.println(list.toString());//3
            //binarySearch  二分查找
            int i = Collections.binarySearch(list,13);
            System.out.println(i);
            int j = Collections.binarySearch(list,12);
            System.out.println(j);//-4(不存在,为负数)
            //copy 复制
            List<Integer> list1 = new ArrayList<>();
            for (int k = 0; k <list.size() ; k++) {
                list1.add(0);
            }
            Collections.copy(list1,list);
            System.out.println(list1.toString());//[4, 5, 6, 13, 20, 30]
            //reverse反转
            Collections.reverse(list);
            System.out.println("反转之后:"+list);//反转之后:[30, 20, 13, 6, 5, 4]
            //shuffle 打乱
            Collections.shuffle(list);
            System.out.println("打乱之后:"+list);//打乱之后:[6, 13, 5, 4, 30, 20]
            // 补充:1.list转为数组
            Integer[] arr = list.toArray(new Integer[0]);
            System.out.println(arr.length);//6
            System.out.println("转为数组之后"+Arrays.toString(arr));//转为数组之后[6, 13, 5, 4, 30, 20]
            //数组转为list
            String[] name = {"张三","李四","王二"};
            List<String> list2 = Arrays.asList(name);
            // 受限集合:不能添加和删除
            System.out.println("数组转集合:"+list2);//数组转集合:[张三, 李四, 王二]
    //基本类型数组在转成集合时,需要修改为包装类型
            Integer[] nums = {100,200,300,400,500};
            List<Integer> list3 = Arrays.asList(nums);
            System.out.println(list3);
        }
    }
    

集合总结

  • 集合的概念:
    • 对象的容器,和数组类似,定义了多个对象进行操作的常用方法。
  • List集合:
    • 有序、有下标、元素可以重复。(ArrayList、LinkedList、Vector)
  • Set集合:
    • 无序、无下标、元素不可重复。(HashSet、TreeSet)
  • Map集合:
    • 存储一对数据,无序、无下标,键不可重复,值可重复。(HashMap、HashTable、TreeMap)
  • Collections:
    • 集合工具类,定义了除了存储以外的集合常用方法。
      int j = Collections.binarySearch(list,12);
      System.out.println(j);//-4(不存在,为负数)
      //copy 复制
      List list1 = new ArrayList<>();
      for (int k = 0; k <list.size() ; k++) {
      list1.add(0);
      }
      Collections.copy(list1,list);
      System.out.println(list1.toString());//[4, 5, 6, 13, 20, 30]
      //reverse反转
      Collections.reverse(list);
      System.out.println(“反转之后:”+list);//反转之后:[30, 20, 13, 6, 5, 4]
      //shuffle 打乱
      Collections.shuffle(list);
      System.out.println(“打乱之后:”+list);//打乱之后:[6, 13, 5, 4, 30, 20]
      // 补充:1.list转为数组
      Integer[] arr = list.toArray(new Integer[0]);
      System.out.println(arr.length);//6
      System.out.println(“转为数组之后”+Arrays.toString(arr));//转为数组之后[6, 13, 5, 4, 30, 20]
      //数组转为list
      String[] name = {“张三”,“李四”,“王二”};
      List list2 = Arrays.asList(name);
      // 受限集合:不能添加和删除
      System.out.println(“数组转集合:”+list2);//数组转集合:[张三, 李四, 王二]
      //基本类型数组在转成集合时,需要修改为包装类型
      Integer[] nums = {100,200,300,400,500};
      List list3 = Arrays.asList(nums);
      System.out.println(list3);
      }
      }
    
    
    
    

集合总结

  • 集合的概念:
    • 对象的容器,和数组类似,定义了多个对象进行操作的常用方法。
  • List集合:
    • 有序、有下标、元素可以重复。(ArrayList、LinkedList、Vector)
  • Set集合:
    • 无序、无下标、元素不可重复。(HashSet、TreeSet)
  • Map集合:
    • 存储一对数据,无序、无下标,键不可重复,值可重复。(HashMap、HashTable、TreeMap)
  • Collections:
    • 集合工具类,定义了除了存储以外的集合常用方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值