Java基础14-集合

概述

集合框架被设计成要满足以下几个目标:

  • 该框架必须是高性能的。
    基本集合(动态数组,链表,树,哈希表)的实现也必须是高效的。
  • 该框架允许不同类型的集合,以类似的方式工作,具有高度的互操作性。
  • 对一个集合的扩展和适应必须是简单的。

为此,整个集合框架就围绕一组标准接口而设计。你可以直接使用这些接口的标准实现,诸如: LinkedList, HashSet, 和 TreeSet 等,除此之外你也可以通过这些接口实现自己的集合。



从上面的集合框架图可以看到,Java 集合框架主要包括两种类型的容器:

  • 一种是集合(Collection),存储一个元素集合
  • 另一种是图(Map),存储键/值对映射

Collection 接口又有 3 种子类型,List、Set 和 Queue,再下面是一些抽象类,最后是具体实现类,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap 等等。


Collection

单列集合的顶层接口 , java.util包下 , 继承了Iterable接口:
public interface Collection<E> extends Iterable<E>

List

List接口是一个有序的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。
List 接口存储一组不唯一,有序(插入顺序)的对象。

特点:
1.元素有序(有序指的是存取有序)
2.可重复
3.允许多个null值

其常见实现子类有: ArrayList / LinkedList / Vector:

  • ArrayList:底层实现是数组,增删慢 , 查询快

该类实现了List接口,实现了可变大小的数组,随机访问和遍历元素时,提供更好的性能
该类是非同步的
(1)ArrayList内部使用数组存储元素,默认初识容量为10,当数组长度不够时进行扩容,每次加一半的空间,ArrayList不会进行缩容;
(2)ArrayList支持随机访问,通过索引访问元素极快,时间复杂度为O(1);
(3)ArrayList添加元素到尾部极快,平均时间复杂度为O(1);
(4)ArrayList添加元素到中间比较慢,因为要搬移元素,平均时间复杂度为O(n);
(5)ArrayList从尾部删除元素极快,时间复杂度为O(1);
(6)ArrayList从中间删除元素比较慢,因为要搬移元素,平均时间复杂度为O(n);
(7)ArrayList支持求并集,调用addAll(Collection<? extends E> c)方法即可;
(8)ArrayList支持求交集,调用retainAll(Collection<? extends E> c)方法即可;
(9)ArrayList支持求单向差集,调用removeAll(Collection<? extends E> c)方法即可;

  • LinkedList:底层实现是双向链表,增删快、查询慢
    该类实现了List接口,允许有null(空)元素
    该类是非同步的


    LinkedList添加元素示意图

    在队列首尾添加元素很高效,时间复杂度为O(1)。
    在中间添加元素比较低效,首先要先找到插入位置的节点,再修改前后节点的指针,时间复杂度为O(n)。
    LinkedList删除元素示意图

    在队列首尾删除元素很高效,时间复杂度为O(1)。
    在中间删除元素比较低效,首先要找到删除位置的节点,再修改前后指针,时间复杂度为O(n)。

  • Vector:底层实现是数组,它ArrayList基本相同,主要区别是它的线程是同步的(安全的),而ArrayList和LinkedList是非同步的(实际开发中如果使用了多线程一般方法就已经使用同步机制了,例如同步锁,所以不推荐使用Vectoer)

常用API

返回值 方法 描述
boolean add(E e) 向列表的尾部添加指定的元素(可选操作)
void add(int index, E element) 在列表的指定位置插入指定元素(可选操作)
boolean addAll(Collection<? extends E> c) 添加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序(可选操作)
boolean addAll(int index, Collection<? extends E> c) 将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)
void clear() 从列表中移除所有元素(可选操作)
boolean contains(Object o) 如果列表包含指定的元素,则返回true
boolean containsAll(Collection<?> c) 如果列表包含指定 collection 的所有元素,则返回true
boolean equals(Object o) 比较指定的对象与列表是否相等
E get(int index) 返回列表中指定位置的元素。
int hashCode() 返回列表的哈希码值
int indexOf(Object o) 返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1
boolean isEmpty() 如果列表不包含元素,则返回true
Iterator<E> iterator() 返回按适当顺序在列表的元素上进行迭代的迭代器
int lastIndexOf(Object o) 返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1
ListIterator<E> listIterator() 返回此列表元素的列表迭代器(按适当顺序)
ListIterator<E> listIterator(int index) 返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始
E remove(int index) 移除列表中指定位置的元素(可选操作)。
boolean remove(Object o) 从此列表中移除第一次出现的指定元素(如果存在)(可选操作)
boolean removeAll(Collection<?> c) 从列表中移除指定 collection 中包含的其所有元素(可选操作)
boolean retainAll(Collection<?> c) 仅在列表中保留指定 collection 中所包含的元素(可选操作)
E set(int index, E element) 用指定元素替换列表中指定位置的元素(可选操作)
int size() 返回列表中的元素数
List<E> subList(int fromIndex, int toIndex) 返回列表中指定的fromIndex(包括 )和toIndex(不包括)之间的部分视图
Object[] toArray() 返回按适当顺序包含列表中的所有元素的数组(从第一个元素到最后一个元素)

Set

Set 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素。
Set 接口存储一组唯一,无序的对象

特点:
1.元素无序且不可重复(无序指的是存取无序)
2.无角标
3.最多允许1个null值

常用实现子类有: HashSet / TreeSet / LinkedHashSet:

  • HashSet:底层数据结构是HashMap , 通过复写hashCode()方法和equals()方法来保证元素的唯一性(非同步)

(1)HashSet内部使用HashMap的key存储元素,以此来保证元素不重复;
(2)HashSet是无序的,因为HashMap的key是无序的;
(3)HashSet中允许有一个null元素,因为HashMap允许key为null;
(4)HashSet是非线程安全的;
(5)HashSet是没有get()方法的;

  • TreeSet:底层数据结构是NavigableMap , 通过Compareable接口的compareTo()方法来保证元素的唯一性(非同步)

(1)TreeSet底层使用NavigableMap存储元素;
(2)TreeSet是有序的;
(3)TreeSet是非线程安全的;
(4)TreeSet实现了NavigableSet接口,而NavigableSet继承自SortedSet接口;
(5)TreeSet实现了SortedSet接口;

  • LinkedHashSet:具有可预知迭代顺序的Set 接口的哈希表和链接列表实现(非同步),底层是LinkedHashMap,很少使用

常用API

返回值 方法 描述
boolean add(E e) 如果set中尚未存在指定的元素,则添加此元素(可选操作)
boolean addAll(Collection<? extends E> c) 如果 set 中没有指定 collection 中的所有元素,则将其添加到此set中(可选操作)
void clear() 移除此 set 中的所有元素(可选操作)
boolean contains(Object o) 如果 set 包含指定的元素,则返回true
boolean containsAll(Collection<?> c) 如果此 set 包含指定 collection 的所有元素,则返回true
boolean equals(Object o) 比较指定对象与此 set 的相等性
int hashCode() 返回 set 的哈希码值
boolean isEmpty() 如果 set 不包含元素,则返回true
Iterator<E> iterator() 返回在此 set 中的元素上进行迭代的迭代器
boolean remove(Object o) 如果 set 中存在指定的元素,则将其移除(可选操作)
boolean removeAll(Collection<?> c) 移除 set 中那些包含在指定 collection 中的元素(可选操作)
boolean retainAll(Collection<?> c) 仅保留 set 中那些包含在指定 collection 中的元素(可选操作)
int size() 返回 set 中的元素数(其容量)
Object[] toArray() 返回一个包含 set 中所有元素的数组

Map

双列集合的顶层接口,将键映射到值的对象。
一个映射不能包含重复的键;每个键最多只能映射一个值

HashMap(允许1个null键、多个null值)

HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
它的底层实现实际是:数组+单向链表+红黑树


该类实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步。


常用API

返回值 方法 描述
void clear() 从此映射中移除所有映射关系
Object clone() 返回此HashMap实例的浅表副本:并不复制键和值本身
boolean containsKey(Object key) 如果此映射包含对于指定键的映射关系,则返回true
boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true
Set<Map.Entry<K,V>> entrySet() 返回此映射所包含的映射关系的 Set 视图
V get(Object key) 返回指定键所映射的值;如果对于该键来说,此映射不包含任何映射关系,则返回 null
boolean isEmpty() 如果此映射不包含键-值映射关系,则返回 true
Set<K> keySet() 返回此映射中所包含的键的 Set 视图
V put(K key, V value) 在此映射中关联指定值与指定键
void putAll(Map<? extends K,? extends V> m) 将指定映射的所有映射关系复制到此映射中,这些映射关系将替换此映射目前针对指定映射中所有键的所有映射关系
V remove(Object key) 从此映射中移除指定键的映射关系(如果存在)
int size() 返回此映射中的键-值映射关系数
Collection<V> values() 返回此映射所包含的值的 Collection 视图

(1)HashMap是一种散列表,采用(数组 + 链表 + 红黑树)的存储结构;
(2)HashMap的默认初始容量为16(1<<4),默认装载因子为0.75f,容量总是2的n次方
负载因子越小查找的性能就会越高,但同时额外占用的内存就会越多,如果没有特殊需要不建议修改默认值。
(3)HashMap扩容时每次容量变为原来的两倍;
(4)当桶的数量小于64时不会进行树化,只会扩容;
(5)当桶的数量大于64且单个桶中元素的数量大于8时,进行树化;
(6)当单个桶中元素数量小于6时,进行反树化;
(7)HashMap是非线程安全的容器;
(8)HashMap查找添加元素的时间复杂度都为O(1);
使用HashMap时还需要注意一点,它不会动态地进行缩容,也就是说,你不应该保留一个已经删除过大量Entry的HashMap(如果不打算继续添加元素的话),此时它的buckets数组经过多次扩容已经变得非常大了,这会占用非常多的无用内存,不过一般也不会出现这种情况,如果遇见了,请毫不犹豫地丢掉它,或者把数据转移到一个新的HashMap。

HashTable(不允许null键和null值):

Hashtable是线程安全的
其实现方式是在对应的方法上加上synchronized关键字
效率不高,推荐使用ConcurrentHashMap
其他和HashMap相同

TreeMap(不允许null键 , 允许null值):

基于红黑树(Red-Black tree)的NavigableMap实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的Comparator进行排序,具体取决于使用的构造方法(非同步)

构造方法 描述
TreeMap() 使用键的自然顺序构造一个新的、空的树映射
TreeMap(Comparator<? super K> comparator) 构造一个新的、空的树映射,该映射根据给定比较器进行排序
TreeMap(Map<? extends K,? extends V> m) 构造一个与给定映射具有相同映射关系的新的树映射,该映射根据其键的自然顺序 进行排序
TreeMap(SortedMap<K,? extends V> m) 构造一个与指定有序映射具有相同映射关系和相同排序顺序的新的树映射

常用API

返回值 方法 描述
Map.Entry<K,V> ceilingEntry(K key) 返回一个键-值映射关系,它与大于等于给定键的最小键关联;如果不存在这样的键,则返回 null
K ceilingKey(K key) 返回大于等于给定键的最小键;如果不存在这样的键,则返回 null
void clear() 从此映射中移除所有映射关系
Object clone() 返回此 <tt>TreeMap</tt> 实例的浅表副本
Comparator<? superK> comparator() 返回对此映射中的键进行排序的比较器;如果此映射使用键的自然顺序,则返回 null
boolean containsKey(Object key) 如果此映射包含指定键的映射关系,则返回true
boolean containsValue(Object value) 如果此映射为指定值映射一个或多个键,则返回 true
NavigableSet<K> descendingKeySet() 返回此映射中所包含键的逆序 NavigableSet 视图
NavigableMap<K,V> descendingMap() 返回此映射中所包含映射关系的逆序视图
Set<Map.Entry<K,V>> entrySet() 返回此映射中包含的映射关系的 Set 视图
Map.Entry<K,V> firstEntry() 返回一个与此映射中的最小键关联的键-值映射关系;如果映射为空,则返回 null
K firstKey() 返回此映射中当前第一个(最低)键
Map.Entry<K,V> floorEntry(K key) 返回一个键-值映射关系,它与小于等于给定键的最大键关联;如果不存在这样的键,则返回 null
K floorKey(K key) 返回小于等于给定键的最大键;如果不存在这样的键,则返回 null
V get(Object key) 返回指定键所映射的值,如果对于该键而言,此映射不包含任何映射关系,则返回 null
SortedMap<K,V> headMap(K toKey) 返回此映射的部分视图,其键值严格小于toKey
NavigableMap<K,V> headMap(K toKey, boolean inclusive) 返回此映射的部分视图,其键小于(或等于,如果 inclusive 为 true)toKey
Map.Entry<K,V> higherEntry(K key) 返回一个键-值映射关系,它与严格大于给定键的最小键关联;如果不存在这样的键,则返回 null
K higherKey(K key) 返回严格大于给定键的最小键;如果不存在这样的键,则返回 null
Set<K> keySet() 返回此映射包含的键的 Set 视图
Map.Entry<K,V> lastEntry() 返回与此映射中的最大键关联的键-值映射关系;如果映射为空,则返回 null
K lastKey() 返回映射中当前最后一个(最高)键
Map.Entry<K,V> lowerEntry(K key) 返回一个键-值映射关系,它与严格小于给定键的最大键关联;如果不存在这样的键,则返回 null
K lowerKey(K key) 返回严格小于给定键的最大键;如果不存在这样的键,则返回 null
NavigableSet<K> navigableKeySet() 返回此映射中所包含键的 NavigableSet 视图。
Map.Entry<K,V> pollFirstEntry() 移除并返回与此映射中的最小键关联的键-值映射关系;如果映射为空,则返回 null
Map.Entry<K,V> pollLastEntry() 移除并返回与此映射中的最大键关联的键-值映射关系;如果映射为空,则返回 null
V put(K key, V value) 将指定值与此映射中的指定键进行关联
void putAll(Map<? extends K,? extends V> map) 将指定映射中的所有映射关系复制到此映射中
V remove(Object key) 如果此 TreeMap 中存在该键的映射关系,则将其删除
int size() 返回此映射中的键-值映射关系数
NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) 返回此映射的部分视图,其键的范围从 fromKeytoKey
SortedMap<K,V> subMap(K fromKey, K toKey) 返回此映射的部分视图,其键值的范围从fromKey(包括)到toKey(不包括)。
SortedMap<K,V> tailMap(K fromKey) 返回此映射的部分视图,其键大于等于fromKey
NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) 返回此映射的部分视图,其键大于(或等于,如果 inclusivetruefromKey
Collection<V> values() 返回此映射包含的值的 Collection 视图
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容

  • 四、集合框架 1:String类:字符串(重点) (1)多个字符组成的一个序列,叫字符串。生活中很多数据的描述都采...
    佘大将军阅读 740评论 0 2
  • 一、基础知识:1、JVM、JRE和JDK的区别:JVM(Java Virtual Machine):java虚拟机...
    杀小贼阅读 2,371评论 0 4
  • Collection ├List │├LinkedList │├ArrayList │└Vector │└Stac...
    AndyZX阅读 871评论 0 1
  • 转载自:Java集合框架实例 1- 介绍 集合是程序和语言的基本思想。应用程序通常都会应用到集合,例如雇员的信息,...
    01_小小鱼_01阅读 392评论 0 1
  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 5,257评论 0 9