集合

集合是“确定的一堆东西”,集合里的“东西”则称为元素。现代的集合一般被定义为:由一个或多个确定的元素所构成的整体 。

集合分类

Collection 接口的接口 对象的集合(单列集合)
├——-List 接口:元素按进入先后有序保存,可重复
│—————-├ LinkedList 接口实现类, 链表, 插入删除, 没有同步, 线程不安全
│—————-├ ArrayList 接口实现类, 数组, 随机访问, 没有同步, 线程不安全
│—————-└ Vector 接口实现类 数组, 同步, 线程安全
│ ———————-└ Stack 是Vector类的实现类
└——-Set 接口: 仅接收一次,不可重复,并做内部排序
├—————-└HashSet 使用hash表(数组)存储元素
│————————└ LinkedHashSet 链表维护元素的插入次序
└ —————-TreeSet 底层实现为二叉树,元素排好序

Map 接口 键值对的集合 (双列集合)
├———Hashtable 接口实现类, 同步, 线程安全
├———HashMap 接口实现类 ,没有同步, 线程不安全-
│—————–├ LinkedHashMap 双向链表和哈希表实现
│—————–└ WeakHashMap
├ ——–TreeMap 红黑树对所有的key进行排序
└———IdentifyHashMap

线程安全的集合都有哪些

线程安全

就是当多线程访问时,采用了加锁的机制;即当一个线程访问该类的某个数据时,会对这个数据进行保护,其他线程不能对其访问,直到该线程读取完之后,其他线程才可以使用。防止出现数据不一致或者数据被污染的情况。

线程安全的集合对象

Vector 线程安全
HashTable 线程安全
StringBuffer 线程安全

集合大纲图

java 元素需要有序 数据结构_线程安全

Collection 接口

collection的父类是Iterable接口,Iterable是集合中的顶级父类。
我们翻源码可以发现 collection 下都有哪些集合
让我们一起来看看这个Collection里边的方法
package java.util;

import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 * @author  Josh Bloch
 * @author  Neal Gafter
 * @see     Set    Set 接口: 仅接收一次,不可重复,并做内部排序 
 * @see     List    List 接口:元素按进入先后有序保存,可重复 
 * @see     Map  Map 接口 键值对的集合 (双列集合) 
 * @see     SortedSet
 * @see     SortedMap
 * @see     HashSet
 * @see     TreeSet
 * @see     ArrayList
 * @see     LinkedList
 * @see     Vector
 * @see     Collections
 * @see     Arrays
 * @see     AbstractCollection
 */
public interface Collection<E> extends Iterable<E> {
	int size(); //获取集合的大小
	boolean isEmpty();//判断集合是否为空
	boolean contains(Object o);//判断这个集合中是否存在这个数据 存在返回true 不存在则 false
	Iterator<E> iterator();//迭代器循环
	Object[] toArray();//将list直接转为Object[] 数组;
	<T> T[] toArray(T[] a);//将list转化为你所需要类型的数组,当然我们用的时候会转化为与list内容相同的类型。
	boolean add(E e);//像集合中添加数据
    boolean remove(Object o);//删除所传入的值
    boolean containsAll(Collection<?> c);//判断集合中是否存在所传入集合中的元素
    boolean addAll(Collection<? extends E> c);//像本集合中添加集合
	boolean removeAll(Collection<?> c);//删除存在于指定集合中的动态数组元素。
    default boolean removeIf(Predicate<? super E> filter) {//按照一定规则过滤集合中的元素
        Objects.requireNonNull(filter);
        boolean removed = false;
        final Iterator<E> each = iterator();
        while (each.hasNext()) {
            if (filter.test(each.next())) {
                each.remove();
                removed = true;
            }
        }
        return removed;
    }
    boolean retainAll(Collection<?> c);//删除指定集合中不存在的那些元素。
	void clear();//清空集合
	boolean equals(Object o);//比较
	int hashCode();//获取当前对象的hash值
	@Override
    default Spliterator<E> spliterator() {//作用是为并行提供一个可切割的spliterator,然后可以并行处理
        return Spliterators.spliterator(this, 0);
    }

    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }

 
    default Stream<E> parallelStream() {
        return StreamSupport.stream(spliterator(), true);
    }
}

我们可以发现 Collection下的集合很多 常用的有 List Set Map 这三个集合

List

├——-List 接口:元素按进入先后有序保存,可重复
│—————-├ LinkedList: 接口实现类, 链表, 插入删除, 没有同步, 线程不安全
│—————-├ ArrayList: 接口实现类, 数组, 随机访问, 没有同步, 线程不安全
│—————-└ Vector: 接口实现类 数组, 同步, 线程安全
│ ———————-└ Stack: 是Vector类的实现类

LinkedList
LinkedList是以链表实现的,插入、删除时只需要改变前后两个节点指针指向即可
ArrayList
ArrayList就是动态数组,用MSDN中的说法,就是Array的复杂版本,它提供了动态
	 的增加和减少元素,实现了ICollection和IList接口,灵活的设置数组的大小等好处
Vector
Vector是跟ArrayList一样的 只是线程安全,所以 执行起来是比ArrayList 慢
	Vector下还有一个Stack实现类 它是一个底层的栈 里边也有一些执行的方法
看一下List集合的方法
package java.util;

import java.util.function.UnaryOperator;

/**
 * @see Collection
 * @see Set
 * @see ArrayList     数组形式,随机访问,没有同步,线程不安全
 * @see LinkedList   链表形式, 插入删除, 没有同步, 线程不安全 
 * @see Vector         数组形式, 同步, 线程安全 
 */

public interface List<E> extends Collection<E> {

    int size();//获取List集合大小

    boolean isEmpty();//判断集合是否为空

    boolean contains(Object o);//判断这个集合中是否存在这个数据 存在返回true 不存在则 false

    Iterator<E> iterator();迭代器循环输出

    Object[] toArray();//将list直接转为Object[] 数组;

    <T> T[] toArray(T[] a);//将list转化为你所需要类型的数组,当然我们用的时候会转化为与list内容相同的类型。

    boolean add(E e);//向集合中添加数据

    boolean remove(Object o);//删除集合中存在的传入值

    boolean containsAll(Collection<?> c);//判断集合中是否存在所传入集合中的元素

    boolean addAll(Collection<? extends E> c);//向集合中添加集合

    boolean addAll(int index, Collection<? extends E> c);//向集合中添加集合 第一个值是 需要插入的地方 从第几个数据开始插入

    boolean removeAll(Collection<?> c);//删除跟传入集合中的值相同的元素

    boolean retainAll(Collection<?> c);//删除指定集合中不存在的那些元素。

    default void replaceAll(UnaryOperator<E> operator) {
        Objects.requireNonNull(operator);
        final ListIterator<E> li = this.listIterator();
        while (li.hasNext()) {
            li.set(operator.apply(li.next()));
        }
    }

    @SuppressWarnings({"unchecked", "rawtypes"})
    default void sort(Comparator<? super E> c) { //排序
        Object[] a = this.toArray();
        Arrays.sort(a, (Comparator) c);
        ListIterator<E> i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);
        }
    }

    void clear();

    boolean equals(Object o);

    int hashCode();//获取集合的hash值

    E get(int index);//获取集合中第几个值

    E set(int index, E element);//向集合中存入数据 第一个值是 插入的地方 第二个是插入的值

    void add(int index, E element);//向集合中插入数据 第一个值 是插入的地方,第二个是插入的数据

    E remove(int index);//删除集合中指定的第几个值 int

    int indexOf(Object o);//从头开始 获取固定元素

    int lastIndexOf(Object o);//从尾部开始

    ListIterator<E> listIterator();//遍历
//注意获取listIterator迭代器之后,必须调用next()方法,才算进入到list的第一个元素。
//代码中 iter,next(),就是为了让迭代器只向list的第一个元素。所以,可以理解成,直接获取
//迭代器后,迭代器的对象指向的是一个head节点,它的下一个才是开始遍历的元素。


    ListIterator<E> listIterator(int index);


    List<E> subList(int fromIndex, int toIndex);//获取 规定的值 之间的 元素 第一个 从哪里开始获取(包含),第二个值是 到哪结束 (不包含)

  
    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.ORDERED);
    }
}

Set

└——-Set 接口: 仅接收一次,不可重复,并做内部排序
├—————-└HashSet 使用hash表(数组)存储元素
│————————└ LinkedHashSet 链表维护元素的插入次序
└ —————-TreeSet 底层实现为二叉树,元素排好序

set接口下还有两个集合 分别问 HashSet 和TreeSet

HashSet:
HashSet是Java集合Set的一个实现类,Set是一个接口
	对于 HashSet 而言,它是基于 HashMap 实现的,底层采用 HashMap 来保存元素。
	HashSet 下 还有 一个LinkedHashSet 实现
		LinkedHashSet:
			具有set集合不重复的特点,同时具有可预测的迭代顺序,也就是我们插入的顺序。
			并且linkedHashSet是一个非线程安全的集合。如果有多个线程同时访问当前linked
			hashset集合容器,并且有一个线程对当前容器中的元素做了修改,那么必须要在外
			部实现同步保证数据的冥等性。
TreeSet:
TreeSet是一个有序的集合,它的作用是提供有序的Set集合。它继承了AbstractSet抽象类,
	实现了NavigableSet<E>,Cloneable,Serializable接口。TreeSet是基于TreeMap实现的,
	TreeSet的元素支持2种排序方式:自然排序或者根据提供的Comparator进行排序。
Set集合都有哪些方法:
package java.util;


 /* @see Collection
 * @see List
 * @see SortedSet
 * @see HashSet   使用hash表(数组)存储元素 
 * @see TreeSet  底层实现为二叉树,元素排好序
 * @see AbstractSet
 * @see Collections#singleton(java.lang.Object)
 * @see Collections#EMPTY_SET
 */

public interface Set<E> extends Collection<E> {
 
    int size();//获取集合大小

    boolean isEmpty();//判断集合是否为空

    boolean contains(Object o);//判断集合中是否拥有这个数据
    Iterator<E> iterator();//迭代器循环输出

    Object[] toArray();//将list直接转为Object[] 数组;

    <T> T[] toArray(T[] a);//将list转化为你所需要类型的数组,当然我们用的时候会转化为与list内容相同的类型。

    boolean add(E e);//向集合中添加数据

    boolean remove(Object o);//删除指定跟传入数据相同的元素

    boolean containsAll(Collection<?> c);//删除包含传入集合数据的元素

    boolean addAll(Collection<? extends E> c);//添加集合

    boolean retainAll(Collection<?> c);//删除指定集合中不存在的那些元素。

    boolean removeAll(Collection<?> c);//删除跟传入集合中的值相同的元素

    void clear();//清空集合中的数据

    boolean equals(Object o);//比较哦

    int hashCode();//获取hash值

    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.DISTINCT);
    }
}

Map

Map 接口 键值对的集合 (双列集合)
├———Hashtable 接口实现类, 同步, 线程安全
├———HashMap 接口实现类 ,没有同步, 线程不安全-
│—————–├ LinkedHashMap 双向链表和哈希表实现
│—————–└ WeakHashMap
├ ——–TreeMap 红黑树对所有的key进行排序
└———IdentifyHashMap

Hashtable
Hashtable是基于哈希表实现的,每个元素是一个key-value对,其内部是通过单链表解决冲突问题,
容量不足(超过了阀值)时,同样会自动增长。
  Hashtable是JDK1.0引入的类,是线程安全的,能用于多线程环境中。
  Hashtable实现了Serializable接口,它支持序列化,实现了Cloneable接口,能被克隆。
HashMap
HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,
 容量不足(超过了阀值)时,同样会自动增长。
 	HashMap中还包含了 LinkedHashMap  和 WeakHashMap 
 	LinkedHashMap:
 		它通过维护一个运行于所有条目的双向链表,LinkedHashMap保证了元素迭代的顺序。
 		该迭代顺序可以是插入顺序或者是访问顺序。
 	WeakHashMap :
 		它是一个散列表,它存储的内容也是键值对(key-value)映射,而且键和值都可以是null。
		不过WeakHashMap的键是“弱键”。在 WeakHashMap 中,当某个键不再正常使用时,
		会被从	WeakHashMap中被自动移除。更精确地说,对于一个给定的键,其映射的存在并
		不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。某
		个键被终止时,它对应的键值对也就从映射中有效地移除了。
TreeMap
TreeMap存储K-V键值对,通过红黑树(R-B tree)实现;
TreeMap继承了NavigableMap接口,NavigableMap接口继承了SortedMap接口,可支持一系列的
导航定位以及导航操作的方法,当然只是提供了接口,需要TreeMap自己去实现;
TreeMap实现了Cloneable接口,可被克隆,实现了Serializable接口,可序列化;
TreeMap因为是通过红黑树实现,红黑树结构天然支持排序,默认情况下通过Key值的自然顺序进行排序;
Map中的方法
package java.util;

import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.io.Serializable;

/**
 * @author  Josh Bloch
 * @see HashMap
 * @see TreeMap
 * @see Hashtable
 * @see SortedMap
 * @see Collection
 * @see Set
 * @since 1.2
 */
public interface Map<K,V> {

    int size();//获取集合的大小

    boolean isEmpty();//判断集合是否为null

    boolean containsKey(Object key);//判断集合中是否拥有传入的key值

    boolean containsValue(Object value);//判断集合中是否拥有传入的value值

    V get(Object key);//获取集合中的数据

    V put(K key, V value);//向集合中添加数据(key/value的键值对形式)

    V remove(Object key);//删除指定的key

    void putAll(Map<? extends K, ? extends V> m);//向集合中添加map集合

    void clear();//清空集合

    Set<K> keySet();//返回此映射中包含的键的 Set 视图
                   // 将map中所有的键存入到Set集合,因为set具备迭代器,所有迭代方式取出所有的键
                  //再根据get()方法  ,获取每一个键对应的值

    Collection<V> values();//获取集合中的所有的value值;

    Set<Map.Entry<K, V>> entrySet();//返回此映射中包含的映射关系的 Set 视图。 Map.Entry表示映射关系。
  								   //entrySet():迭代后可以e.getKey(),e.getValue()取key和value。返回的是Entry接口 。

    interface Entry<K,V> {//使用Entry对象遍历 每个Map集合创建的时候就会创建一个Entry对象用来记录键与值(键值对对象,键与值得映射关系)

        K getKey();

        V getValue();

        V setValue(V value);

        boolean equals(Object o);

        int hashCode();

        public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {
            return (Comparator<Map.Entry<K, V>> & Serializable)
                (c1, c2) -> c1.getKey().compareTo(c2.getKey());
        }

        public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() {
            return (Comparator<Map.Entry<K, V>> & Serializable)
                (c1, c2) -> c1.getValue().compareTo(c2.getValue());
        }

        public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) {
            Objects.requireNonNull(cmp);
            return (Comparator<Map.Entry<K, V>> & Serializable)
                (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
        }

        public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
            Objects.requireNonNull(cmp);
            return (Comparator<Map.Entry<K, V>> & Serializable)
                (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
        }
    }
    
    boolean equals(Object o);//比较

    int hashCode();//获取map集合的hash值

    default V getOrDefault(Object key, V defaultValue) {//集合中如果没有传入的key值 那么就是用默认的 传入的defaultValue值 ,如果有就返回对应的value值

        V v;
        return (((v = get(key)) != null) || containsKey(key))
            ? v
            : defaultValue;
    }

    default void forEach(BiConsumer<? super K, ? super V> action) {//循环
        Objects.requireNonNull(action);
        for (Map.Entry<K, V> entry : entrySet()) {
            K k;
            V v;
            try {
                k = entry.getKey();
                v = entry.getValue();
            } catch(IllegalStateException ise) {
                // this usually means the entry is no longer in the map.
                throw new ConcurrentModificationException(ise);
            }
            action.accept(k, v);
        }
    }

    default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {//将 hashMap 中的所有映射关系替换成给定的函数所执行的结果。
        Objects.requireNonNull(function);
        for (Map.Entry<K, V> entry : entrySet()) {
            K k;
            V v;
            try {
                k = entry.getKey();
                v = entry.getValue();
            } catch(IllegalStateException ise) {
                // this usually means the entry is no longer in the map.
                throw new ConcurrentModificationException(ise);
            }

            // ise thrown from function is not a cme.
            v = function.apply(k, v);

            try {
                entry.setValue(v);
            } catch(IllegalStateException ise) {
                // this usually means the entry is no longer in the map.
                throw new ConcurrentModificationException(ise);
            }
        }
    }

    default V putIfAbsent(K key, V value) {//putIfAbsent方法,只有在key不存在或者key为null的时候,value值才会被覆盖

        V v = get(key);
        if (v == null) {
            v = put(key, value);
        }

        return v;
    }

    default boolean remove(Object key, Object value) {//删除指定的key/value
        Object curValue = get(key);
        if (!Objects.equals(curValue, value) ||
            (curValue == null && !containsKey(key))) {
            return false;
        }
        remove(key);
        return true;
    }

    default boolean replace(K key, V oldValue, V newValue) {//替换 hashMap 中是指定的 key 对应的 value。
        Object curValue = get(key);
        if (!Objects.equals(curValue, oldValue) ||
            (curValue == null && !containsKey(key))) {
            return false;
        }
        put(key, newValue);
        return true;
    }

    default V replace(K key, V value) {//替换 hashMap 中是指定的 key 对应的 value。
        V curValue;
        if (((curValue = get(key)) != null) || containsKey(key)) {
            curValue = put(key, value);
        }
        return curValue;
    }

    default V computeIfAbsent(K key,
            Function<? super K, ? extends V> mappingFunction) {//和putIfAbsent类似但是,在返回值上不一样,value值不存在的时候,返回的是新的value值,同时可以通过自定义一些条件进行过滤。

        Objects.requireNonNull(mappingFunction);
        V v;
        if ((v = get(key)) == null) {
            V newValue;
            if ((newValue = mappingFunction.apply(key)) != null) {
                put(key, newValue);
                return newValue;
            }
        }

        return v;
    }

    default V computeIfPresent(K key,
            BiFunction<? super K, ? super V, ? extends V> remappingFunction) {//只有当key存在的时候才执行操作
        Objects.requireNonNull(remappingFunction);
        V oldValue;
        if ((oldValue = get(key)) != null) {
            V newValue = remappingFunction.apply(key, oldValue);
            if (newValue != null) {
                put(key, newValue);
                return newValue;
            } else {
                remove(key);
                return null;
            }
        } else {
            return null;
        }
    }

    default V compute(K key,
            BiFunction<? super K, ? super V, ? extends V> remappingFunction) {//传入的值如果集合中有 那么就替换 如果没有 就他添加进去
        Objects.requireNonNull(remappingFunction);
        V oldValue = get(key);

        V newValue = remappingFunction.apply(key, oldValue);
        if (newValue == null) {
            // delete mapping
            if (oldValue != null || containsKey(key)) {
                // something to remove
                remove(key);
                return null;
            } else {
                // nothing to do. Leave things as they were.
                return null;
            }
        } else {
            // add or replace old mapping
            put(key, newValue);
            return newValue;
        }
    }

    default V merge(K key, V value,
            BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
//1.  如果value不为空,进行merge处理。为空直接赋值newValue。实际上就是一个put操作。 
//    然后将key对应的oldValue和newValue 根据传来的function进行处理。
//2   当处理后的value值为空,map会移除当前key 
        Objects.requireNonNull(remappingFunction);
        Objects.requireNonNull(value);
        V oldValue = get(key);
        V newValue = (oldValue == null) ? value :
                   remappingFunction.apply(oldValue, value);
        if(newValue == null) {
            remove(key);
        } else {
            put(key, newValue);
        }
        return newValue;
    }
}