zoukankan      html  css  js  c++  java
  • Java 容器

    概述

    Java 的集合框架大致分为 Collection 和 Map 两种,两者区别:

    • Collection 是单元素集合;Map 是双元素键值对集合;
    • Collection 中只有 Set 系列要求元素唯一;Map 中要求键唯一,值可以重复;
    • Collection 的数据结构是针对元素的;Map 的数据结构是针对键的。


    Collection 集合

    i 标识的是 Collection 派生出的子接口,c 标识是实现类。


    Collection

    Collection 接口是 Set、List 和 Queue 接口的父接口,该接口定义的方法既可以用于操作 Set 集合,也可用于操作 List 和 Queue 集合。

    //向集合添加一个元素,成功返回true
    boolean add(E e);
    
    //把集合c的全部元素添加入指定集合,成功返回true
    boolean addAll(Collection<E> c);
    
    //删除集合中指定元素o,当集合中包含一个或多个元素o时,只删除第一个
    boolean remove(E o);
    
    //从集合中删除集合c里包含的所有元素(相当于调用该集合减集合c)
    boolean removeAll(Collection<E> c);
    
    //集合里是否包含指定元素
    boolean contains(E o);
    
    //集合里是否包含集合c里的所有元素
    boolean containsAll(Collection<E> c);
    
    //返回集合里元素的个数
    int size();
    
    //清除集合里的所有元素,将集合长度变为0
    void clear();
    
    //返回Iterator对象,用于遍历集合中的元素
    Iterator<E> iterator();
    
    //从集合中删除集合c里不包含的元素(相当于取该集合和集合c的交集)
    boolean retainAll(Collection<E> c);
    
    //该方法把集合转换成一个数组,所有集合元素变成数组元素,一般不推荐使用这个方法
    Object[] toArray();
    
    //该方法把集合转换成一个数组,传入的参数一般为类型为 T 长度为 0 的空数组,推荐使用
    //例如:Integer[] newText = c.toArray(new Integer[0]);
    <T> T[] toArray(T[] a);
    
    //该方法是Java 8为Map新增的一个遍历key-value对的方法,使用Lambda表达式
    void forEach(BiConsumer action);
    
    //Java 8新增,将集合转换为Stream流
    void forEach(Consumer<? super T> action)
    

    Set

    • TreeSet:基于红黑树实现,支持有序性操作,在增加和删除数据上特别高效。查找效率不如 HashSet,HashSet 查找的时间复杂度为 O(1),TreeSet 则为 O(logN)
    • HashSet:基于哈希表实现,支持快速查找,但不支持有序性操作。并且失去了元素的插入顺序信息,也就是说使用 Iterator 遍历 HashSet 得到的结果是不确定的。
    • LinkedHashSet:是 HashSet 的子类,在 HashSet 基础上使用双向链表维护元素的插入顺序。

    Set 作为 Collection 接口的子接口,可以使用 Collection 接口里的全部方法。


    List

    • ArrayList:基于动态数组实现,所以查询速度快,增删速度慢。
    • Vector:和 ArrayList 功能类似,是线程安全的。
    • Stack:栈数据结构,是 Vector 的子类,因此也是线程安全的。
    • LinkedList:基于双向链表实现,只能顺序访问,所以查询特别慢,但是可以快速地在链表中间插入和删除元素。因为 LinkedList 还实现了 Queue 接口,所以还可以用作栈、队列和双向队列。

    注意:vector 和 Stack 过于古老,性能不佳,不推荐使用。栈操作一般使用 ArrayDeque 来代替。

    List 作为 Collection 接口的子接口,可以使用 Collection 接口里的全部方法。另外,由于 List 是有序集合,所以添加了根据索引来插入、替换和删除集合元素的方法。

    //将元素 element 添加到 List 集合索引 index 处,原 index 及后续的元素往后移动 
    void add(int index, E element);
    
    //将 Collection 集合中的所有元素插入到 List 集合的 index 处。
    boolean addAll(int index, Collection<? extends E> c);
    
    //删除并返回 index 索引处的元素
    E remove(int index);
    
    //返回索引 index 处的元素。
    E get(int index);
    
    //将位置索引为 index 的元素,替换为 element。
    E set(int index, E element);
    
    //返回元素 o 在 list 集合中第一次出现的位置索引。  
    int indexOf(E o);
    
    //返回元素 o 在 List 集合中最后一次出现的位置索引。  
    int lastIndexOf(E o);
    
    //返回 List 集合中从索引fromIndex (包含)到索引 toIndex(不包含)之间的所有元素。
    List<E> subList(int fromIndex, int toIndex);
    
    //Java 8新增根据 operator 指定的计算规则来重新设置 List 集合的所有元素。
    void replaceAll(UnaryOperator<E> operator);
    
    //Java 8新增根据 Comparator 参数对 List 集合的元素排序。
    void sort(Comparator<? super E> c);
    

    Queue

    • PriorityQueue:优先级队列,基于堆结构实现。
    • ArrayDeque:双端队列,基于一个动态数组实现,常用来代替 Vector 的栈操作。
    • LinkedList:双端队列,基于一个双向链表实现。

    Queue 作为 Collection 接口的子接口,可以使用 Collection 接口里的全部方法。另外,由于 Queue 是队列集合,所以添加了根据队列特性来插入、替换和删除集合元素的方法。

    //将指定元素插入到队列的尾部。
    boolean add(E e);
    
    //获取队列头部的元素,并删除该元素。
    E remove();
    
    //获取队列头部的元素,但是不删除该元素。
    E element();
    
    //将指定的元素插入此队列的尾部。当使用容量有限的队列时,此方法通常比add(Object e)有效。
    boolean offer(E e);
    
    //返回队列头部的元素,并删除该元素。如果队列为空,则返回null。
    E poll();
    
    //返回队列头部的元素,但是不删除该元素。如果队列为空,则返回null。
    E peek();
    

    Deque 是 Queue 接口的子接口,它是一个双端队列,既可以当队列用,也可以当栈用。如果 Deque 当做常规的队列用使用,最左端(如果以数组存储,就是第一个元素)是队头,最右端是队尾;当成常规的栈用,最左端是栈顶,最右端是栈底。Deque 根据双端队列的特性也定义了一些方法:

    //将指定元素添加到双端队列的头部。
    void addFirst(E e);
    
    //将指定元素添加到双端队列的尾部。
    void addLast(E e);
    
    //将指定元素添加到双端队列的头部。
    boolean offerFirst(E e);
    
    //将指定元素添加到双端队列的尾部。
    boolean offerLast(E e);
    
    //获取但不删除双端队列的第一个元素(头)。
    E getFirst();
    
    //获取但不删除双端队列的最后一个元素(尾)。
    E getLast();
    
    //获取但不删除双端队列的第一个元素;如果双端队列为空,则返回null。
    E peekFirst();
    
    //获取但不删除双端队列的最后一个元素;如果双端队列为空,则返回null。
    E PeekLast();
    
    //获取并删除双端队列的第一个元素;如果双端队列为空,则返回null。
    E pollFirst();
    
    //获取并删除双端队列的最后一个元素;如果双端队列为空,则返回null。
    E pollLast();    
    
    //获取并删除该双端队列的第一个元素。
    E removeFirst();
    
    //获取并删除该双端队列的最后一个元素o。
    E removeLast();
    
    //pop出该双端队列所表示的栈的栈顶元素。相当于removeFirst()。
    E pop(); //(栈方法)
    
    //将一个元素push进该双端队列所表示的栈的栈顶。相当于addFirst()。
    void push(E e); //(栈方法): 
    
    • Deque 的方法与 Queue 的方法对比
    Queue 的方法 Deque 的方法
    add(e)/offer(e) addLast(e)/offerLast(e)
    remove()/poll() removeFirst()/pollFirst()
    element()/peek() getFirst()/peekFirst()

    Deque 也可以直接使用 offer(e) 和 poll() 方法实现入队和出队,用 peek() 访问队头,

    • Deque 的方法与 Stack 的方法对比
    Stack 的方法 Deque 的方法
    push(e) addFirst(e)/offerFirst(e)
    pop() removeFirst()/pollFirst()
    peek() getFirst()/peekFirst()

    Deque 也可以直接使用 push(e) 和 pop() 方法实现入栈和出栈,用 peek() 访问栈顶。



    Map 集合

    i 标识的是 map 派生出的子接口,c 标识是实现类。

    • TreeMap:基于红黑树实现。

    • HashMap:基于哈希表实现。

    • LinkedHashMap:是 HashMap 的子类,在 HashMap 基础上使用双向链表维护元素的顺序,顺序为插入顺序或者最近最少使用(LRU)顺序。

    • HashTable:和 HashMap 类似,是线程安全的。

    注意:HashTable 是一个古来的遗留类,不应该去使用它。现在可以使用 ConcurrentHashMap 来支持线程安全,并且 ConcurrentHashMap 的效率会更高,因为 ConcurrentHashMap 引入了分段锁。


    Map接口方法

    //添加一个key-value对,如果当前Map中已有一个与该key相等的key-value对,
    //则新的key-value会覆盖原来的key-value对。
    V put(K key, V value);
    
    //将指定Map中key-value复制到当前Map中。
    void putAll(Map<? extends K, ? extends V> m);
    
    //返回指定的key所对应的value;如果此Map中不包括该key,则返回null。
    V get(Object key);
    
    //返回指定的key所对应的value;如果此Map中不包括该key,则返回defalutValue。
    V getOrDefault(Object key, V defaultValue);
    
    //删除指定key所对应的key-value对,返回被删除key所对应的value,如果key不存在返回null。
    V remove(Object key);
    
    //删除指定key,value所对应的key-value对。如果成功删除,则返回true,否则返回false。
    boolean remove(Object key, Object value);
    
    //查询Map集合中是否包含指定的key,如果包含,返回true。
    boolean containsKey(object key);
    
    //查询Map集合中是否包含指定的value,如果包含返回true。
    boolean containsValue(Object value);
    
    //返回该map中所有key所组成的集合。
    Set<K> keySet();
    
    //返回Map中包含的key-value对所组成的Set集合,
    //每个集合元素都是Map.Entry(Entry是Map的内部类,用于存储key-value的)对象。
    Set<Map.Entry<K, V>> entrySet();
    
    //返回该Map中key-value的个数。
    int size();
    
    //删除Map集合中的所有key-value对。
    void clear();
    
    //查询该Map是否为空,如果为空则返回null。
    boolean isEmpty();
    
    //返回该Map中所有value组成的collection。
    Collection<V> values();
    
    //该方法是Java8为Map新增的一个遍历key-value对的方法,使用Lambda表达式。
    void forEach(BiConsumer<? super K, ? super V> action)
    
    //Java 8新增,将Map中指定key对应的value替换成新value。
    //如果key在Map中不存在,该方法不会添加key-value对,而是返回null。
    V replace(K key, V value);
    
    //Java 8新增,将Map中指定的key-value对的原value替换成新value。
    //如果在Map中找到指定的key-value对,则执行替换并返回true,否则返回false。
    boolean replace(K key, V oldValue, V newValue);
    

    内部类Map.Entry

    Map 中包含一个内部类 Map.Entry<K, V>,该类用来封装 key-value 对。Map 接口的 entrySet() 方法返回所有 Map.Entry 所组成的 Set 集合。该类方法如下:

    //返回该Entry里包含的key值
    K getKey();
    
    //返回该Entry里包含的value值
    V getValue();
    
    //设置该Entry里包含的value值,并返回新设置的value值
    V setValue(V value);
    


    参考

    1. https://github.com/CyC2018/CS-Notes/blob/master/notes/Java%20%E5%AE%B9%E5%99%A8.md
    2. <<疯狂 Java 讲义>>
  • 相关阅读:
    使用Twitter异常检测框架遇到的坑
    Python从入门到精通
    Windows中几个内存相当的指标
    Windows应用程序进程级别统一监控实践
    基于时序数据的微内核预警引擎架构设计
    Flink1.4.0连接Kafka0.10.2时遇到的问题
    wait和sleep的区别
    JVM几种垃圾回收器介绍
    二叉树的非递归遍历
    段页式内存管理
  • 原文地址:https://www.cnblogs.com/zongmin/p/11350844.html
Copyright © 2011-2022 走看看