Java---不知道用哪个集合?史上最全面的集合框架让你分清各个集合的区别,小白也能懂

集合框架

在这里插入图片描述

单列集合

Collection(接口)

  特点: 部分集合有序,部分集合无序,部分集合唯一,部分集合可重复
   常用方法:
     添加
       boolean add(E e) 将指定的元素添加到此列表的尾部。
       boolean addAll(Collection<? extends E> c)
       将指定 collection 中的所有元素都添加到此 collection 中

     删除
       void clear() 移除此 collection 中的所有元素(可选操作)。
      boolean remove(Object o) 从此 collection 中移除指定元素的单个实例
       boolean removeAll(Collection<?> c) 移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。

     修改 【无】

     遍历
       Object[] toArray() 将集合转换成数组
       注意: 数组转换成集合: Arrays.asList(T… a);
       T[] toArray(T[] a) 泛型方法,将集合转换成数组
       Iterator iterator() 返回在此 collection 的元素上进行迭代的迭代器。
       任何一个Collection的子类都可以使用迭代器遍历

     判断
       boolean contains(Object o) 判断集合中是否包含某个元素o
       boolean containsAll(Collection<?> c) 如果此 collection 包含指定 collection 中的所有元素,则返回 true。
       boolean isEmpty() 如果此 collection 不包含元素,则返回 true。

     其他
       boolean retainAll(Collection<?> c) 求交集
       int size() 获取集合的长度
   遍历方式:
     1.普通toArray
     2.泛型toArray
     3.迭代器Iterator
     4.foreach遍历

List

  特点: 有序,可重复
   方法:
     添加
       void add(int index, E element)
         在列表的指定位置插入指定元素(可选操作)。
       boolean addAll(int index, Collection<? extends E> c)
        将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。

     删除
       E remove(int index)
         移除列表中指定位置的元素(可选操作)。

     修改
       E set(int index, E element)
         用指定元素替换列表中指定位置的元素(可选操作)。

    遍历
       E get(int index)
       ListIterator listIterator()
         返回此列表元素的列表迭代器(按适当顺序)。
       ListIterator listIterator(int index)
         返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。

     获取
       int indexOf(Object o) 返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。
       int lastIndexOf(Object o)
         返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1。
       List subList(int fromIndex, int toIndex)
         返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。

   遍历方式:
     5.普通for list.size() + list.get(int index)
     6.列表迭代器
       a.正向遍历
       b.逆向遍历
       c.从指定位置开始正向或者逆向遍历

ArrayList

  特点:
   1. 底层数据结构是数组
   2. 增加和删除的效率低,查询和修改的效率高
   3. 能够存储 null 值
   4. 线程不安全,效率高 可以通过 Collections.synchronizedList();变安全
   5. 有索引,能够方便检索
   6. 元素可重复,我们自己可以通过
   去除重复元素
      a.创建一个新的集合,地址传递
      b.选择排序思想去除重复元
      c.利用LinkedHashSet的构造器
   7. 不可以排序,但是可以通过 Collections.sort();方法排序
   8. 动态扩容原理
核心源码解析
      private void grow(int minCapacity) {
         // overflow-conscious code
        int oldCapacity = elementData.length; // 0
        int newCapacity = oldCapacity + (oldCapacity / 2); // 扩容系数
        // ==> (1 + 1/2) * oldCapcity == > 1.5 * oldCapcity
         if (newCapacity < minCapacity)
         newCapacity = minCapacity; // 10
         if (newCapacity > MAX_ARRAY_SIZE)
        newCapacity = hugeCapacity(minCapacity);
         // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
      }
      a.扩容系数1.5倍
      b.如果超过int类型的范围,抛出错误
      c.底层依赖的是Arrays.copyOf()方法,还是利用new或者反射创建了新的数组,copyOf方法底层依赖System.arraycopy方法

  常用方法: 来自于Collection和List接口

Vector

特点:和ArrayList完全兼容,但是它是线程安全,效率低,就算安全我们也不用,过时了
   常用方法:
     增加
       public synchronized void addElement(E obj) 添加元素 obj 到集合中
       public synchronized void insertElementAt(E obj, int index) 在指定索引 index 处插入元素 obj

     删除
       public synchronized void removeElementAt(int index) 移除指定索引 index 处的元素
       public synchronized void removeAllElements() 移除所有元素

     修改
       public synchronized void setElementAt(E obj, int index) 修改指定索引 index 的元素为 obj

    遍历
         public synchronized ElementAt(int index) + size() for循环遍历集合中的所有元素
       public synchronized Enumeration elements() 使用 Enumeration 迭代器遍历集合中的元素

    获取
       public synchronized E firstElement() 获取集合中的第一个元素
       public synchronized E lastElement() 获取集合中的最后一个元素
       public synchronized E elementAt(int index) 获取指定索引 index 的元素

    遍历方式:
       7. 普通for的老版本形式 ElementAt(int index) + size()
       8. 旧版迭代器Enumeration Enumeration elements()

ArrayList和Vector的区别?
    1) Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。

     2) 当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间。

Stack

  特点: 是Vector的子类,也过时了,同时具备栈结构的特点 【先进后出】
     可以考虑使用LinkedList

  常用方法:
     E push(E item) 将元素压入栈底
     E pop() 将元素从栈结构中弹出,并作为此函数的值返回该对象,此方法会影响栈结构的大小
     E peek() 查看堆栈顶部的对象,但不从栈中移除它。
     boolean empty() 测试栈是否为空。
     int search(Object o) 返回对象在栈中的位置,以 1 为基数。

  遍历方式:
     栈结构的先进后出遍历方式
         Stack stack = new Stack<>();
         // 压栈
         stack.push(“A”);
         stack.push(“B”);
         stack.push(“C”);

        while (!stack.isEmpty()) {
         System.out.println(“栈顶元素:” + stack.peek());
         // 弹栈
         System.out.println(“弹出栈顶元素:” + stack.pop());
         }

LinkedList

  和ArrayList一样可以通用
  但是它的底层数据结构是链表

Queue

  特点: 队列数据结构相关的集合 【先进先出】
      1. 该接口是队列接口的根接口,先进先出
      2. 该接口提供队列相关两种形式的方法,一种抛出异常(操作失败时),另一种返回一个特殊值(nullfalse,具体取决于操作)。插入操作的后一种形式是用于专门为有容量限制的 Queue 实现设计的;在大多数实现中,插入操作不会失败。

   常用方法:
      抛出异常 返回特殊值
   插入 add(e) offer(e)
   移除 remove() poll()
   检查 element() peek()

   遍历方式:
      10.队列结构遍历方式
      Queue queue = new ArrayDeque<>();
      queue.add(“A”);
      queue.add(“B”);
      queue.add(“C”);

     while (!queue.isEmpty()) {
         System.out.println(queue.remove());
      }
      // 或者
      queue.offer(“A”);
      queue.offer(“B”);
      queue.offer(“C”);

    while (!queue.isEmpty()) {
        System.out.println(queue.poll());
      }

Deque

  特点:
   1. Deque是一个Queue的子接口,是一个双端队列,支持在两端插入和移除元素
   2. deque支持索引值直接存取。
   3. Deque头部和尾部添加或移除元素都非常快速。但是在中部安插元素或移除元素比较费时。
   4. 插入、删除、获取操作支持两种形式:快速失败和返回nulltrue/false
   5. 不推荐插入null元素,null作为特定返回值表示队列为空

   常用方法
      xxxFirst xxxLast 支持从两段插入和溢出还有查看, 并且有两套方法

ArrayDeque

  1.底层数据是数组
   2.没有实现List接口,所以不能够通过索引来操作队列

LinkedList

   1.底层数据结构是链表
   2.实现了List接口,具备List接口的功能,可以通过索引来获取数据
   3.实现了Queue接口的功能,支持在对尾插入,对头取出数据的特点,先进先出
   4.实现了Deque接口的功能,支持在两段插入和删除
   5.实现了栈结构,支持先进后出的存取数据

Set

  特点: 无序,唯一
   常用方法: 和Collection一模一样
   遍历方式: 和Collection一模一样

HashSet

    底层数据结构是哈希表
     哈希表如何保证唯一?
     依赖hashcode和equals方法
       首先判断hashCode是否相同
         不相同
           就存储到集合中
         相同
           比较equals方法是否相同
         相同 就不存储
           不相同就以链表的方式存储到集合中

  哈希表结构是如何存储数据的?
     根据对象本身计算出来的hash值进行存储,这个hash和对象的hashCode的有关
     如果hash不同,存储到哈希表中,如果hash值一样,那么比较equals方法,如果
     equals不同那么就以链表的形式存储在同一个hash索引的位置,如果存储的链表
     长度过长,这个时候会自动调整为红黑树,红黑树是一种自平衡的二叉树,该树查找的
     次数就是树的深度,弥补了链表查找效率低的问题

TreeSet

  底层数据结构是自平衡的二叉树
   二叉树如何保证唯一?
       根据二叉树的存储特点
         首先第一个元素进来,作为根节点存储【类型检查】
         第二个元素和第一个元素比较
         大了放在根的右边
         小了放在根的左边
         相等 不处理
   二叉树如何保证可排序
       根据二叉树的取的特点
         中序遍历: 左根右
   已知 前序遍历和中序遍历 求后序遍历
   自然排序
       使用无参构造方法 Comparable接口
   比较排序
       使用带Comparator接口的参数
       实现类
       匿名内部类
   当同时使用自然排序和比较器排序时,比较器排序优先
注意标准的排序写法

public int compare(Student s1, Student s2) {
						// 注:总分相同等情况下按照语文成绩排序,其次是数学成绩、英语成绩、年龄、姓名
						double num1 = s1.getTotalScore() - s2.getTotalScore();
						double num2 = (num1 == 0) ? s1.getChineseScore() - s2.getChineseScore() :  num1;
						double num3 = (num2 == 0) ? s1.getMathScore() - s2.getMathScore() : num2;
						double num4 = (num3 == 0) ? s1.getEnglishScore() - s2.getEnglishScore() : num3;
						double num5 = (num4 == 0) ? s1.getAge() - s2.getAge() : num4;
						double num6 = (num5 == 0) ? s1.getName().compareTo(s2.getName()) : num5;
						return (num6 < 0) ? -1 : ( (num6 == 0) ? 0 : 1 );
					}

  HashSet去重复 数据库的一个关键字 distinct
   TreeSet排序 数据库的一个语法 order by

   LinkedHashSet
      底层数据结构是链表 + 哈希表,链表保证元素有序,哈希表保证元素唯一
      让无序的set集合变有序
   EnumSet
      底层数据结构是枚举数组,枚举本身就是唯一的,方便

双列集合

Map

Map<K,V>(接口)
  Map集合的特点
     1.能够存储唯一的列的数据(唯一,不可重复) Set
     2.能够存储可以重复的数据(可重复) Collection
     3.值的顺序取决于键的顺序
     4.键和值都是可以存储null元素的

    一个映射不能包含重复的键。
     每个键最多只能映射到一个值。

  常用功能
   1.添加功能
     V put(K key, V value)
     void putAll(Map<? extends K,? extends V> m)
   2.删除功能
     V remove(Object key)
     void clear()
   3.遍历功能
     Set keySet()
     Collection values()
     Set<Map.Entry<K,V>> entrySet()
   4.获取功能
     V get(Object key)
   5.判断功能
     boolean containsKey(Object key)
     boolean containsValue(Object value)
     boolean isEmpty()
   6.修改功能
     V put(K key, V value)
     void putAll(Map<? extends K,? extends V> m)
   7.长度功能
     int size()
   遍历方式
     Set keySet() 获取键的集合
     Collection values() 获取值的集合
     Set<Map.Entry<K,V>> entrySet()

	interface Entry<K,V> {
			  			K getKey();
			   			V getValue();
			   			V setValue(V value);
			  		}

    两种常用遍历方式
       方式1:根据Key查找Value Set set = map.keySet()
       获取所有Key的集合
       遍历Key的集合,获取到每一个Key
       根据Key查找Value
       方式2:根据键值对对象找键和值
           Set<Map.Entry<Key, Value>> set = map.entrySet();
       获取所有键值对对象的集合
       遍历键值对对象的集合,获取到每一个键值对对象
       根据键值对对象找键和值

HashMap

    底层数据结构和HashSet一样

Hashtable

    底层数据结构是哈希表,线程安全,效率低,不允许null值null键

TreeMap

    底层数据结构和TreeSet一样

LinkedHashMap

    底层数据结构是哈希表和链表

WeakHashMap

    以弱键存储的哈希表结构Map集合

EnumMap

    枚举映射在内部表示为数组。此表示形式非常紧凑且高效。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章