Java--Collection集合

一、Collection

1.1 概述

  • Collection 层次结构 中的根接口。
  • Collection 表示一组对象,这些对象也称为 collection 的元素【集合中只能存储引用类型】。
  • 一些 collection 允许有重复的元素,而另一些则不允许。
  • 一些 collection 是有序的,而另一些则是无序的。
  • JDK 不提供此接口的任何 直接实现:它提供更具体的子接口(如 Set 和 List)实现。
  • 此接口通常用来传递 collection,并在需要最大普遍性的地方操作这些 collection。

1.2 Collection体系

  1. Collection接口
    • 这是所有集合类的根接口,定义了添加、删除、迭代等基本方法。
    • 实现Collection接口的类有ArrayList, LinkedList, HashSet, TreeSet, Vector, Stack等。
  2. List接口
    • List是一个有序的集合,允许重复元素,并且每个元素都有一个位置索引。
    • 实现List接口的类有ArrayList, LinkedList, Vector等。
  3. Set接口
    • Set是一个不包含重复元素的集合,没有顺序的概念。
    • 实现Set接口的类有HashSet, LinkedHashSet, TreeSet等。
  4. Queue接口
    • Queue是一个主要用于实现队列操作的集合,如先进先出(FIFO)。
    • 实现Queue接口的类有ArrayDeque, LinkedList等。
  5. Deque接口
    • Deque是双端队列的缩写,可以作为堆栈、队列或列表使用。
    • 实现Deque接口的类有ArrayDeque, LinkedList等。
  6. Map接口
    • Map是一种将键映射到值的对象,不允许重复键。
    • 实现Map接口的类有HashMap, LinkedHashMap, TreeMap, Hashtable, Properties等。

除了上述接口,还有一些辅助类和接口,例如Iterator用于遍历集合,Spliterator用于并行流处理,EnumSet用于枚举类型集合等。

Java Collection Framework的设计遵循了一些基本原则,如泛型化、可变性、线程安全性等,使得开发人员能够更加高效地处理各种数据结构问题。

1.3 常用方法

增删改查
import java.util.ArrayList;
import java.util.Collection;

public class Demo02 {
    public static void main(String[] args) {
        /**
         * 方法摘要 
         * 增
             boolean add(E e) 
                      确保此 collection 包含指定的元素(可选操作)。 
             boolean addAll(Collection<? extends E> c) 
                      将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。 
         
         * 删
             boolean remove(Object o) 
                      从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。 
             boolean removeAll(Collection<?> c) 
                      移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。 
             void clear() 
                      移除此 collection 中的所有元素(可选操作)。 
        
         * 改
         
         * 查
             int size() 
                      返回此 collection 中的元素数。 
             boolean isEmpty() 
                      如果此 collection 不包含元素,则返回 true。 
             boolean contains(Object o) 
                      如果此 collection 包含指定的元素,则返回 true。 
             boolean containsAll(Collection<?> c) 
                      如果此 collection 包含指定 collection 中的所有元素,则返回 true。 
             boolean retainAll(Collection<?> c) 
                      仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。 
         */
        /**
         *  创建集合对象
         *      多态方式创建对象:
         *          声明的容器对象类型是接口,实际创建的对象类型是实现类
         *      声明了容器对象中的元素类型是String【泛型】
         */
        Collection<String> coll = new ArrayList<String>();
        
        // 添加数据
        coll.add("曹操");
        coll.add("曹丕");
        coll.add("曹植");
        coll.add("曹昂");
        
        // 输出容器中的内容
        System.out.println(coll.toString());
        
        Collection<String> c = new ArrayList<String>();
        // 添加数据
        c.add("曹爽");
        c.add("曹冲");
        c.add("曹洪");
        
        // 添加指定集合中的全部数据
        c.addAll(coll);
        System.out.println(c);
        
        // 删除数据,有布尔类型的返回值,表示删除是否成功
        coll.remove("曹昂");
        System.out.println(coll);
        
        // 移除两个集合中交集部分
        c.removeAll(coll);
        System.out.println(c);
        
        System.out.println("集合中元素的数量:" + c.size());
        // 清空集合
        // c.clear();
        System.out.println("集合中元素的数量:" + c.size());
        
        // 集合中是否包含指定元素
        System.out.println(c.contains("曹操"));
        System.out.println(c.contains("曹爽"));
        
        // 是否完全包含另一个集合中的数据
        System.out.println(c.containsAll(coll));
        System.out.println(c.containsAll(c));
        
        
        coll.add("曹爽");
        coll.add("曹冲");
        System.out.println(c);
        System.out.println(coll);
        
        // 在c集合中留下两个集合中交集部分内容
        c.retainAll(coll);
        System.out.println(c);
    }
}
遍历集合【重点】【掌握】
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Demo03 {
    public static void main(String[] args) {
        /**
         * 遍历
         *  foreach
         *  iterator
         */
        
        // 创建集合
        Collection<String> names = new ArrayList<String>();
        // 添加数据
        names.add("唐三藏");
        names.add("孙悟空");
        names.add("猪八戒");
        names.add("沙和尚");
        names.add("白龙马");
        
        /**
         *  foreach
            for(数据类型 变量名 : 容器对象){
            }
            
            容器对象:
                数组、集合
            数据类型:
                容器中元素的类型
            变量名字:
                临时变量名字,用来存储容器中的每一个元素
         */
        
        for (String name : names) {
            System.out.println(name);
        }
        
        /**
         *  迭代器
         *      先使用获取迭代器对象:
         *          调用集合的iterator()方法
         *      使用循环从迭代器中获取每一个元素
         *          使用while循环
         */
        Iterator<String> it = names.iterator();
        
        // 不断地判定是否有下一个数据
        while (it.hasNext()) {
            // 获取下一个对象,顺便把游标向下移动
            String name = it.next();
            System.out.println(name);
        }
        
    }
}

二、List

2.1 概述

  • 有序地Collection
    • 元素有索引
    • 元素能重复
  • 每个元素的插入位置进行精确地控制。
  • 以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。
  • List 接口中的方法超过了 Collection接口中指定的约定。
    • 包含Collection中继承的方法 + List接口中独有的方法

2.2 实现类

ArrayList【重点】
  • 基于数组实现的
  • 查询速度快,增删速度相对较慢
LinkedList
  • 基于链表实现的
  • 查询数据速度慢,增删数据速度快
Vector
  • 基于数组 && 线程安全的
  • Vector 是同步的。

三、ArrayList

3.1 概述

  • List
    • ArrayList容量可变,长度可变
    • 基于数组实现
  • 提供一些方法来操作内部用来存储列表的数组的大小。
    • ensureCapacity(int minCapacity)
      • 确保 ArrayList 的容量至少为指定的最小容量。这个方法主要是为了避免频繁的数组复制操作,因为 ArrayList 在内部使用一个数组来存储元素,当数组空间不足时,会创建一个新的更大的数组并将原有元素复制过去,这是一个相对昂贵的操作。
      • 参数 minCapacity 指定了 ArrayList 应该至少具有的容量。如果当前的容量小于 minCapacity,那么 ArrayList 会增加其内部数组的大小,以满足这个要求。
    • trimToSize
      • trimToSize() 方法是 java.util.ArrayList 类的一个成员方法,它的作用是将 ArrayList 的容量调整为其实际大小。在 ArrayList 中,容量是指底层数组的大小,而大小则是指 ArrayList 中实际元素的数量。
      • 通常,ArrayList 在添加元素超过其当前容量时,会自动扩展其底层数组的大小,以容纳更多的元素。这种扩展通常是按照一定的比例进行的(默认是增加50%)。然而,这可能导致 ArrayList 的容量远大于其实际大小,尤其是当你从一个较大的 ArrayList 中移除大量元素后。
      • trimToSize() 方法的作用就在于此。当你调用 trimToSize() 后,ArrayList 会重新分配一个刚好能容纳当前元素数量的新数组,并将所有元素复制到新数组中。这样,ArrayList 的容量就等于其大小,从而节省了内存。
  • 每个 ArrayList 实例都有一个容量。该容量是指用来存储列表元素的数组的大小。
  • 它总是至少等于列表的大小。随着向 ArrayList 中不断添加元素,其容量也自动增长。
  • 在添加大量元素前,应用程序可以使用 ensureCapacity 操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。

3.2 创建对象

import java.util.ArrayList;

public class Demo01 {
    public static void main(String[] args) {
        /**
         * 构造方法摘要 
            ArrayList() 
                      构造一个初始容量为 10 的空列表。 
            ArrayList(int initialCapacity) 
                      构造一个具有指定初始容量的空列表。 
            ArrayList(Collection<? extends E> c) 
                      构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。 
         */
        
        //  构造一个初始容量为 10 的空列表。 
        ArrayList<String> list01 = new ArrayList<String>();
        
        //  构造一个具有指定初始容量的空列表。 
        ArrayList<String> list02 = new ArrayList<String>(1024);
        list02.add("Hello");
        list02.add("World");
        
        // 基于其他集合创建List集合对象,包含其他集合中的数据
        ArrayList<String> list03 = new ArrayList<String>(list02);
        System.out.println(list03);
    }
}

3.3 常用方法

增删
import java.util.ArrayList;

public class Demo02 {
    public static void main(String[] args) {
        /**
            方法摘要 
            增
             boolean add(E e) 
                      将指定的元素添加到此列表的尾部。 
             void add(int index, E element) 
                      将指定的元素插入此列表中的指定位置。 
             boolean addAll(Collection<? extends E> c) 
                      按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部。 
             boolean addAll(int index, Collection<? extends E> c) 
                      从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。 
            
            删
             E remove(int index) 
                      移除此列表中指定位置上的元素。 
             boolean remove(Object o) 
                      移除此列表中首次出现的指定元素(如果存在)。 
             void clear() 
                      移除此列表中的所有元素。 
             removeAll
                移除两个集合中重复的内容
         */
        
        // 创建集合
        ArrayList<String> list01 = new ArrayList<String>();
        
        // 添加数据
        list01.add("刘备");
        list01.add("刘封");
        list01.add("刘禅");
        list01.add("刘表");
        System.out.println(list01);
        
        // 在指定位置插入数据
        list01.add(2, "关羽");
        list01.add(2, "关羽");
        System.out.println(list01);
        
        // 通过索引移除数据,返回被移除的数据
        String name = list01.remove(0);
        System.out.println(name);
        System.out.println(list01);
        
        // 移除指定的对象,返回移除是否成功
        boolean result = list01.remove("关羽");
        System.out.println(result);
        System.out.println(list01);
        
        // 创建集合,存储整数
        ArrayList<Integer> list = new ArrayList<Integer>();
        // 添加数据
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        
        // 输出
        System.out.println(list);
        Integer i = 1;
        list.remove(i);
        System.out.println(list);
      
    }
}
改查
import java.util.ArrayList;
import java.util.List;

public class Demo03 {
    public static void main(String[] args) {
        /**
         *  改
             E set(int index, E element) 
                      用指定的元素替代此列表中指定位置上的元素。 
             void ensureCapacity(int minCapacity) 
                      如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。 
             void trimToSize() 
                      将此 ArrayList 实例的容量调整为列表的当前大小。 
            
            查
             int size() 
                      返回此列表中的元素数。 
             E get(int index) 
                      返回此列表中指定位置上的元素。 
             boolean contains(Object o) 
                      如果此列表中包含指定的元素,则返回 true。 
             containsAll
                是否包含另一个集合中的所有内容
             int indexOf(Object o) 
                      返回此列表中首次出现的指定元素的索引,或如果此列表不包含该元素,则返回 -1。 
             int lastIndexOf(Object o) 
                      返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含该索引,则返回 -1。 
             retainAll
                保留两个集合中的交集部分内容
             subList
                截取集合中的区间数据
            
            其他
             iterator
             listIterator
             Object[] toArray() 
                      按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。  
         */
        // 创建集合
        ArrayList<String> list01 = new ArrayList<String>();
        
        // 添加数据
        list01.add("刘备");
        list01.add("刘封");
        list01.add("刘禅");
        list01.add("刘表");
        list01.add("关羽");
        list01.add("张飞");
        list01.add("赵云");
        System.out.println(list01);
        
        // 修改指定位置的元素
        list01.set(2, "刘阿斗");
        System.out.println(list01);
        
        // 元素的数量
        System.out.println(list01.size());
        
        // 获取指定索引位置的对象
        System.out.println(list01.get(0));
        System.out.println(list01.get(1));
        System.out.println(list01.get(2));
        System.out.println(list01.get(3));
        
        // 指定对象在集合中第一次出现的索引,如果对象不存在返回-1
        System.out.println(list01.indexOf("刘禅"));
        System.out.println(list01.indexOf("刘阿斗"));
        
        // 截取指定区间的数据,得到一个新的集合
        List<String> subList = list01.subList(2, 6);
        System.out.println(subList);
    }
}

3.4 遍历集合【重点】【掌握】

import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;

public class Demo04 {
    public static void main(String[] args) {
        /**
         *  遍历ArrayList集合
         *      索引遍历
         *          for
         *          while
         *          do-while
         *      无索引遍历
         *          foreach
         *          iterator
         *          listIterator
         */
        // 创建集合
        ArrayList<String> list = new ArrayList<String>();
        
        // 添加数据
        list.add("刘备");
        list.add("关羽");
        list.add("张飞");
        list.add("赵云");
        list.add("黄忠");
        
        System.out.println("===============for==================");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        
        System.out.println("===============while==================");
        int index = 0;
        while (index < list.size()) {
            System.out.println(list.get(index));
            index++;
        }
        
        System.out.println("===============do-while==================");
        index = 0;
        do {
            System.out.println(list.get(index));
            index++;
        } while (index < list.size());
        
        System.out.println("===============foreach==================");
        for (String name : list) {
            System.out.println(name);
        }
        
        System.out.println("===============iterator==================");
        // 获取迭代器对象
        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            String name = it.next();
            System.out.println(name);
        }
        
        System.out.println("===============listLterator==================");
        // 获取迭代器对象
        ListIterator<String> lit = list.listIterator();
        while (lit.hasNext()) {
            String name = lit.next();
            System.out.println(name);
        }
        
        while (lit.hasPrevious()) {
            String name = lit.previous();
            System.out.println(name);
        }
        
        System.out.println("----------------------------------------");
        // 从指定位置开始获取迭代器对象:开始的位置是最后一个元素
        ListIterator<String> litt = list.listIterator(list.size());
        
        // 逆序遍历集合
        while (litt.hasPrevious()) {
            String name = litt.previous();
            System.out.println(name);
        }
        
    }
}

3.5 比较ArrayList和LinkedList的性能

  • 增加

  • 查询

    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.List;

    public class Demo05 {
    public static void main(String[] args) {
    // 创建集合
    ArrayList<String> arrayList = new ArrayList<String>();
    LinkedList<String> linkedList = new LinkedList<String>();

          long arrayInsertStartTime = System.currentTimeMillis();  
          insertData(arrayList);  
          long arrayInsertEndTime = System.currentTimeMillis();  
          System.out.println("ArrayList插入数据消耗时间:" + (arrayInsertEndTime-arrayInsertStartTime));  
    
          long linkedInsertStartTime = System.currentTimeMillis();  
          insertData(linkedList);  
          long linkedInsertEndTime = System.currentTimeMillis();  
          System.out.println("LinkedList插入数据消耗时间:" + (linkedInsertEndTime-			linkedInsertStartTime));  
    
    
          long arraySelectStartTime = System.currentTimeMillis();  
          selectData(arrayList);  
          long arraySelectEndTime = System.currentTimeMillis();  
          System.out.println("ArrayList查询数据消耗时间:" + (arraySelectEndTime-arraySelectStartTime));  
    
          long linkedSelectStartTime = System.currentTimeMillis();  
          selectData(linkedList);  
          long linkedSelectEndTime = System.currentTimeMillis();  
          System.out.println("LinkedList查询数据消耗时间:" + (linkedSelectEndTime-linkedSelectStartTime));  
    
      }  
    
      /**  
      * 插入数据100000条  
      * @param list  
      */  
      public static void insertData(List<String> list) {  
          for (int i = 0; i < 100000; i++) {  
          	list.add(0,Math.random() + "");  
          }  
      }  
    
      public static void selectData(List<String> list) {  
          for (int i = 0; i < 100000; i++) {  
          	list.get(list.size()/2);  
          }  
      }
    

    }

相关推荐
Ajiang2824735304几秒前
对于C++中stack和queue的认识以及priority_queue的模拟实现
开发语言·c++
幽兰的天空5 分钟前
Python 中的模式匹配:深入了解 match 语句
开发语言·python
梓仁沐白2 小时前
ubuntu+windows双系统切换后蓝牙设备无法连接
windows·ubuntu
Theodore_10223 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
冰帝海岸4 小时前
01-spring security认证笔记
java·笔记·spring
世间万物皆对象5 小时前
Spring Boot核心概念:日志管理
java·spring boot·单元测试
没书读了5 小时前
ssm框架-spring-spring声明式事务
java·数据库·spring
----云烟----5 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024065 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
小二·5 小时前
java基础面试题笔记(基础篇)
java·笔记·python