Java集合详解

集合类简述在没有集合类之前,实际上在JAVA语言里已经有一种方法可以存储对象,那就是数组 。数组不仅可以存放基本数据类型也可以容纳属于同一种类型的对象 。数组的操作是高效率的,但也有缺点 。比如数组的长度是不可以变的,数组只能存放同一种类型的对象(或者说对象的引用) 。
为了使程序方便地存储和操纵数目不固定的一组数据,JDK中提供了Java集合类,所有Java集合类都位于Java.util包中,与Java数组不同,Java集合不能存放基本数据类型数据,而只能存放对象的引用 。
集合特点集合类的特点有三个:
第一点,集合类这种框架是高性能的 。对基本类集(动态数组,链接表,树和散列表)的实现是高效率的 。一般人很少去改动这些已经很成熟并且高效的APl;
第二点,集合类允许不同类型的集合以相同的方式和高度互操作方式工作;
【Java集合详解】第三点,集合类容易扩展和修改,程序员可以很容易地稍加改造就能满足自己的数据结构需求 。
集合分类Java中的集合类可以分为两大类:一类是实现Collection接口;另一类是实现Map接口 。
Collection是一个基本的集合接口,Collection中可以容纳一组集合元素(Element) 。
Collection接口中定义了一些操作集合的API:

Java集合详解

文章插图
 
Collection有两个重要的子接口List和Set,它们都有各自经常使用的实现类,关系如下:
Java集合详解

文章插图
 
Map没有继承Collection接口,与Collection是并列关系 。Map提供键(key)到值(value)的映射 。一个Map中不能包含相同的键,每个键只能映射一个值 。
Map中也提供了一些操作Map的API:
Java集合详解

文章插图
 
Map接口的一些常用实现类如下:
Java集合详解

文章插图
 
ListList表达一个有序的集合,List中的每个元素都有索引,使用此接口能够准确的控制每个元素插入的位置 。用户也能够使用索引来访问List中的元素,List类似于Java的数组 。
List接口有两个经常使用的实现类,ArrayList和LinkedList 。还有一个实现类Vector,不过实际开发中很少用 。它们之间的区别为:
  • ArrayList的底层数据结构是一个数组,查询通过数组下标查询,查询速度快,增删慢,线程不安全 。
  • LinkedList的底层数据结构是一个链表,增删元素快,查询慢,线程不安全 。
  • Vector的底层数据结构也是一个数组,查询速度快 。它的方法上加了synchronized关键字,所以它是线程安全的,但也因此,它的效率很低,几乎已经被淘汰了 。
适用场景分析:当需要对数据进行对此访问的情况下选用ArrayList,当需要对数据进行多次增加删除修改时采用LinkedList 。
Java集合详解

文章插图
 
SetSet接口的特点是不能包含重复的元素 。对Set中任意的两个元素element1和element2都有elementl.equals(element2)= false 。另外,Set最多有一个null元素 。
Set接口常用的两个实现类是HashSet和TreeSet,两者的区别如下:
  • HashSet底层数据结构采用哈希表实现,元素无序且唯一,线程不安全,效率高,可以存储null元素,元素的唯一性是靠所存储元素类型是否重写hashCode()和equals()方法来保证的,如果没有重写这两个方法,则无法保证元素的唯一性 。
  • TreeSet底层数据结构采用红黑树来实现,元素唯一且已经排好序;唯一性同样需要重写hashCode和equals()方法,二叉树结构保证了元素的有序性 。根据构造方法不同,分为自然排序(无参构造)和比较器排序(有参构造),自然排序要求元素必须实现Compareable接口,并重写里面的compareTo()方法,元素通过比较返回的int值来判断排序序列,返回0说明两个对象相同,不需要存储;比较器排需要在TreeSet初始化是时候传入一个实现Comparator接口的比较器对象,或者采用匿名内部类的方式new一个Comparator对象,重写里面的compare()方法;
适用场景分析:HashSet是基于Hash算法实现的,其性能通常都优于TreeSet 。为快速查找而设计的Set,我们通常都应该使用HashSet,在我们需要排序的功能时,我们才使用TreeSet 。
此外,还有一种Set类型,LinkedHashSet,它是HashSet的子类,底层数据结构采用链表+哈希表,链表保证元素的添加顺序,哈希表保证元素的唯一性 。


推荐阅读