java源码分析---集合类汇总

集合类汇总

1. 集合的产生
通常,我们的程序需要根据程序运行时才知道创建多少个对象。但若非程序运行,程序开发阶段,我们根本不知道到底需要多少个数量的对象,甚至不知道它的准确类型。为了满足这些常规的编程需要,我们要求能在任何时候,任何地点创建任意数量的对象,而这些对象用什么来容纳呢?我们首先想到了数组,但是数组只能放统一类型的数据,而且其长度是固定的,那怎么办呢?集合便应运而生了!
2. 集合基本概念
2.1 集合与数组
数组:(可以存储基本数据类型)是用来存现对象的一种容器,但是数组的长度固定,不适合在对象数量未知的情况下使用。
集合:(只能存储对象,对象类型可以不一样)的长度可变,可在多数情况下使用。
2.2 集合概念
Java集合类存放于 java.util 包中,是一个用来存放对象的容器。
注意:
①、集合只能存放对象。比如你存一个 int 型数据1放入集合中,其实它是自动转换成 Integer 类后存入的,Java中每一种基本类型都有对应的引用类型。
②、集合存放的是多个对象的引用,对象本身还是放在堆内存中。
③、集合可以存放不同类型,不限数量的数据类型。

3. 集合框架图
《java源码分析---集合类汇总》
此图片来源于:https://img-blog.csdn.net/20160124221843905
图2:
《java源码分析---集合类汇总》
上述所有的集合类,除了 map 系列的集合,即左边集合都实现了 Iterator 接口,这是一个用于遍历集合中元素的接口,主要hashNext(),next(),remove()三种方法。它的一个子接口 ListIterator 在它的基础上又添加了三种方法,分别是 add(),previous(),hasPrevious()。也就是说如果实现 Iterator 接口,那么在遍历集合中元素的时候,只能往后遍历,被遍历后的元素不会再被遍历到,通常无序集合实现的都是这个接口,比如HashSet;而那些元素有序的集合,实现的一般都是 LinkedIterator接口,实现这个接口的集合可以双向遍历,既可以通过next()访问下一个元素,又可以通过previous()访问前一个 元素,比如ArrayList。
  还有一个特点就是抽象类的使用。如果要自己实现一个集合类,去实现那些抽象的接口会非常麻烦,工作量很大。这个时候就可以使用抽象类,这些抽象类中给我们提供了许多现成的实现,我们只需要根据自己的需求重写一些方法或者添加一些方法就可以实现自己需要的集合类,工作量大大降低。
Collection接口是集合类的根接口,Java中没有提供这个接口的直接的实现类。但是却让其被继承产生了两个接口,就是Set和List。Set中不能包含重复的元素。List是一个有序的集合,可以包含重复的元素,提供了按索引访问的方式。
Map是Java.util包中的另一个接口,它和Collection接口没有关系,是相互独立的,但是都属于集合类的一部分。Map包含了key-value对。Map不能包含重复的key,但是可以包含相同的value。
4.集合详解
4.1 Iterator:迭代器
它是Java集合的顶层接口(不包括 map 系列的集合,Map接口 是 map 系列集合的顶层接口)
Object next():返回迭代器刚越过的元素的引用,返回值是 Object,需要强制转换成自己需要的类型
boolean hasNext():判断容器内是否还有可供访问的元素
void remove():删除迭代器刚越过的元素
所以除了 map 系列的集合,我们都能通过迭代器来对集合中的元素进行遍历。
注意:我们可以在源码中追溯到集合的顶层接口,比如 Collection 接口,可以看到它继承的是类 Iterable
我们看下collection源码如下:

public interface Collection<E> extends Iterable<E> 

Collection直接继承了Iterable接口
这里有必要说下Iterator 和 Iterable 的区别,首先看下Iterable源码(存在于 java.lang 包中):

public interface Iterable<T> {
    Iterator<T> iterator();
    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}

通过源码我们可以看到Iterable内部封装了Iterator,所以只要实现了只要实现了Iterable接口的类,就可以使用Iterator迭代器了。
terator :存在于 java.util 包中。核心的方法next(),hasnext(),remove()。
4.2 Collection接口
Collection接口位于java.util包中,是List和Set的父接口。
Set不允许元素重复。HashSet和TreeSet是两个主要的实现类。Set 只能通过游标来取值,并且值是不能重复的。
List有序且允许元素重复。ArrayList、LinkedList和Vector是三个主要的实现类。 ArrayList 是线程不安全的, Vector 是线程安全的,这两个类底层都是由数组实现的 LinkedList 是线程不安全的,底层是由链表实现的
4.3 Set接口
Set集合的几个特点:
1. Set集合不允许出现重复数据
2. 允许包含值为null的元素,但最多只能有一个null元素。
TreeSet
TreeSet的几个特点:
1. TreeSet中不能有重复的元素;
2. TreeSet具有排序功能,缺省是按照自然排序进行排列
TreeSet中的元素必须实现Comparable接口并重写compareTo()方法,TreeSet判断元素是否重复 、以及确定元素的顺序 靠的都是这个方法
HashSet
HashSet的几个特点:
1. HashSet中不能有重复的元素;
2. HashSet是无序的
3. HashSet也是基于HashMap实现
4.4 List接口
Java的List是非常常用的数据类型。List是有序的Collection。Java List一共三个实现类:分别是ArrayList、Vector和LinkedList。
ArrayList:ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要讲已经有数组的数据复制到新的存储空间中。当从ArrayList的中间位置插入或者删除元素时,需要对数组进行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。
Vector:Vector与ArrayList一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问ArrayList慢。
LinkedList:LinkedList是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。另外,他还提供了List接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆栈、队列和双向队列使用。
说明:
ArrayList在内存不够时默认是扩展50% + 1个,Vector是默认扩展1倍。
Vector属于线程安全级别的,但是大多数情况下不使用Vector,因为线程安全需要更大的系统开销。
一般使用ArrayList和LinkedList比较多
对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针
对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据

ArrayList
ArrayList是最常用的List实现类。ArrayList内部是通过数组实现的。所以只适合遍历或者随机查找。
LinkedList
是以链表的结构进行存储对象的,动态新增和删除是很快,但是遍历就很慢,并且不存在get()的操作,不能单个定位。说白了,ArrayList是顺序存储结构,LinkedList是链表存储结构。
4.5 Map接口
Map集合主要有:HashMap,TreeMap,ey-value 的键值对,key 不允许重复,value 可以
  1、严格来说 Map 并不是一个集合,而是两个集合之间 的映射关系。
   2、这两个集合没每一条数据通过映射关系,我们可以看成是一条数据。即 Entry(key,value)。Map 可以看成是由多个 Entry 组成。
   3、因为 Map 集合即没有实现于 Collection 接口,也没有实现 Iterable 接口,所以不能对 Map 集合进行 for-each 遍历。
HashMap
HashMap特点:
(1)HashMap是无序的散列映射表;
(2)HashMap通过Hash 算法来决定存储位置
(3)底层实现是哈希表
TreeMap
TreeMap的特点:
(1)适用于按自然顺序或自定义顺序遍历键(key)。
(2)底层是二叉树
(3)提供compareTo,可以定义排序方法
4.6 Queue
LinkedList就是一个Queue。
常用的Queue有:PriorityQueue、ConcurrentLinkedQueue、ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue

    原文作者:java集合源码分析
    原文地址: https://blog.csdn.net/uftjtt/article/details/79314477
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞