Java-集合知识点整理

集合

概念

集合是存储任意数量的具有共同属性对象容器,集合存储的是 Java 对象的内存地址 / 引用,不能直接存储 Java 对象或基本数据类型,集合类与集合接口都在 java.util 包下。

分类

IMG_0299_20220225-102438_.PNG

Iterator 迭代器

  • 方法

    boolean hasNext():如果下一个元素可以迭代,则返回 true

    Object next():返回迭代中的下一个元素

    void remove():删除迭代器指向的当前对象

  • 迭代器和 ConcurrentModificationException 并发修改异常

    1. 该异常的触发条件是当前集合状态和迭代器快照(原集合状态)不同

    2. 解决方案:

      在遍历集合的过程中使用迭代器的 remove() 方法,不是集合对象的 remove() 方法删除元素

      获取迭代器后禁止改变集合结构(禁止对集合进行增删改操作)

      集合结构发生改变就必须重新获取迭代器

  • remove()

    删除的是迭代器指向的当前元素,同时删除迭代器快照和集合中的元素,删除元素时会自动更新迭代器与集合

Collection 接口

常用方法

boolean add(Object obj):向集合中添加元素 obj

boolean remove(Object obj):删除集合中的某个元素 obj,底层调用 equals() 方法进行比对

boolean contain(Object obj):判断集合中是否存在元素 obj,底层调用 equals() 方法进行比对

boolean isEmpty():判空

int size():获取集合中元素个数

void clear():清空

Object[] toArray():把集合转换成数组

Iterator<E> iterator():获取集合的迭代器对象

子接口 List 集合

List 集合存储元素的特点:有序(存储和读取顺序一致)、可重复、有下标

List 集合方法

void add(int index,Object element):指定位置添加元素

Object get(int index):获取指定位置元素

Object remove(int index):删除指定位置元素并返回该元素

Object set(int index,Object element):设置指定位置为某元素,并将原元素返回

int indexOf(Object obj):获取指定对象在集合中第一次出现的索引

int lastIndextOf(Object obj):获取指定对象在集合中最后一次出现的索引

List 集合分类
  1. Vector 集合:数组,查询效率高,增删效率低,线程安全(方法都带synchronized)

    创建方法:

    • new Vector():初始化容量为10每次扩容为原来的2倍
    • new Vector(int initialCapacity):指定初始化容量
    • new Vector(int initialCapacity,int capacityIncrement):指定初始化容量增量
    • new Vector(Collection coll):将 Collection 集合转换成 Vector 集合
  2. ArrayList 集合:数组,查询效率高,增删效率低,非线程安全

    创建方法:

    • new ArrayList():初始化容量为10每次扩容为原来的1.5倍
    • new ArrayList(int initialCapacity):指定初始化容量
    • new ArrayList(Collection coll):将 Collection 集合转换成 ArrayList 集合

    注意:数组扩容涉及到数组拷贝,应该尽可能减少扩容操作,要预估进行合适的初始化容量设置。

  3. LinkedList 集合:双向链表,查询效率低,增删效率高,非线程安全

    创建方法:

    • new LinkedList():创建一个空的集合(没有初始化容量和扩容机制
    • new LinkedList(Collection coll):将 Collection 集合转换成 LinkedList 集合

    **注意:**LinkedList 增删效率未必高于 ArrayList (头部、中间、尾部)

List 集合遍历
  1. 迭代器遍历

    Iterator<String> iterator=list.iterator();
    while(iterator.hasNext()) System.out.println(iterator.next());
    
  2. for 循环下标遍历

    for(int i=0;i<list.length;i++) System.out.println(list[i]);
    
  3. for-each 循环遍历

    for(String str:list) System.out.println(str);
    
子接口 Set 集合

Set 集合存储元素的特点:无序(存储和读取顺序不一定相同)、不可重复(元素唯一性)、无下标

Set 集合分类
  1. HashSet 集合:哈希表,非线程安全、效率高

    创建方法:

    • new HashSet():初始化容量为16每次扩容为原来的2倍扩容因子为0.75
    • new HashSet(int initialCapacity):指定初始化容量
    • new HashSet(int initialCapacity,float loadFactor):指定初始化容量和扩容因子
    • new HashSet(Collection coll):将 Collection 集合转换成 HashSet 集合

    补充:哈希表

    哈希表是一维数组和单链表 / 红黑树的结合体(拉链式)

    • 当哈希表中的单向链表上的结点 > 8,单向链表转换成红黑树
    • 当哈希表中的红黑树上的结点 < 6,红黑树转换成单向链表
    • 结合了数组的高效查询链表的高效增删(都只发生在某一条链表上)
    • 哈希碰撞
  2. TreeSet 集合:二叉树(中序遍历读取数据),非线程安全、效率高,存储元素自动排序(可排序集合)

    创建方法:

    • new TreeSet():创建一个空的集合
    • new TreeSet(Comparator comp):创建指定比较规则的集合
    • new TreeSet(Collection coll):将 Collection 集合转换成 TreeSet 集合
Set 集合遍历
  1. 迭代器遍历

    Iterator<String> iterator=set.iterator();
    while(iterator.hasNext()) System.out.println(iterator.next());
    
  2. for-each 遍历

    for(String str:set) System.out.println(str);
    
如何选择创建哪种 Collection 集合?

IMG_0300_20220225-130645_.PNG

Map 接口

Map 集合以键值对(key-value)的形式存储数据。key 和 value 都是引用数据类型、都是存储对象的内存地址 / 引用,key 起主导作用。

Map 集合存储元素的特点:无序(存储和读取顺序不一定相同)、不可重复(数据元素唯一性)

常用方法

V put(K key,V value):添加键值对

V get(Object key):通过 key 获取 value

V remove(Object key):通过 key 删除键值对

int size():获取键值对数量

void clear():清空

boolean isEmpty():判空

boolean containsKey(Object key):判断是否包含某个 key

boolean containsValue(Object value):判断是否包含某个 value

Set<K> keySet():获取集合中所有的 key,返回一个 Set 集合

Collection<V> values():获取集合中所有的 value,返回一个 Collection 集合

Set<Map.Entry<K,V>> entrySet():将 Map 集合转换成 Set 集合,Set 集合中的元素类型是 Map.Entry<K,V>

Map 集合分类
  1. HashMap 集合:哈希表,非线程安全,效率高

    创建方法:

    • new HashMap():初始容量为16,扩容为原来的2倍,扩容因子为0.75
    • new HashMap(int initialCapacity):指定初始容量,必须是2的倍数(保证散列分布均匀、提高存取效率)
    • new HashMap(int initialCapacity,float loadFactor):指定初始容量和扩容因子

    注意:允许 key 为 null,但是只能存在一个

  2. HashTable 集合:哈希表,线程安全(所有方法带 synchronized),效率低

    创建方法:

    • new HashTable():初始容量为11,扩容为原来的2倍+1,扩容因子为0.75
    • new HashTable(int initialCapacity):指定初始容量
    • new HashTable(int initialCapacity,float loadFactor):指定初始容量和扩容因子

    **注意:**不允许 key、value 为 null,否则报空指针异常。

  3. TreeMap 集合:红黑树

    创建方法:

    • new TreeMap():创建一个空的集合,无初始化容量和扩容机制

    注意:TreeMap 集合的 key 部分按大小自动排序(可排序集合)。

小结

数组 VS 集合

  1. 数组长度不可变,可以存储基本数据类型引用数据类型,只能存储同一类型的元素
  2. 集合长度可变,只能存储引用数据类型,可以存储不同类型的元素

底层数据结构

实现类底层数据结构特点
Vector数组有序,可重复,线程安全
ArrayList数组有序,可重复,非线程安全
LinkedList双链表有序,可重复,非线程安全
HashSet哈希表无序,不可重复,非线程安全
TreeSet二叉树无序,不可重复,非线程安全,自动排序
HashMap哈希表无序,不可重复,非线程安全
HashTable哈希表无序,不可重复,线程安全
TreeMap红黑树无序,不可重复,非线程安全,自动排序

补充:ConcurrentHashMap

JDK 1.5 中,有了 concurrent 包,ConcurrentHashMap 是线程安全的,但是跟 HashTable 不同,HashTable 是在所有方法上加了 synchronized 实现线程安全,而 ConcurrentHashMap 则是将整个 Map 分为 N 个 Segment (类似 HashTable),因此可以提供相同的线程安全。

泛型机制

本质是参数化类型,即在类、接口、方法的定义上指定元素的数据类型(只能是引用数据类型),作用是在编译阶段(泛型机制只在程序编译阶段起作用)检查元素类型是否匹配,避免程序在运行阶段出现过多错误。

优缺点

  1. 同一集合中的元素类型,不需要进行大量的向下转型
  2. 元素类型缺乏多样性

自定义泛型

List<E> list = new ArrayList<>(); Element

List<T> list = new ArrayList<>(); Type

仅供参考,如有错误,感谢指正!


版权声明:本文为qq_50011463原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。