Java基础系列(三十八):集合总览

前言

在我们日常的开发中,集合占据着举足轻重的地位。在不同的情况下,我们会去选择性能更佳(或更安全的)集合类作为一个容器去存储数据。在接下来的几节中,我会带着大家对于集合的知识进行一次系统的深入梳理,相信梳理过后,面试或日常开发再遇到有关集合的问题对我们来说都不会是问题了。

总览图

首先我们先以一个耳熟能详的集合鸟瞰图开始说起。


通过这个图,我们可以获得哪些有用的信息呢?

这个图由Map指向CollectionProduces并不是说MapCollection的一个子类(子接口),这里的意思是指MapKeySet获取到的一个视图是Collection的子接口(视图是什么,我们后面会讲到)。
我们可以看到集合有两个基本接口:MapCollection。但是我个人认为Map并不能说是一个集合,称之为映射或许更为合适,因为它的KeySet视图是一个Set类型的键集,所以我们姑且把它也当做集合。
Collection继承了Iterator接口,而Iterator的作用是给我们提供一个只能向后遍历集合元素的迭代器,也就是说所有实现Collection的类都可以使用Iterator遍历器去遍历。
每种接口都有一个Abstr act开头的抽象子类,这个子类中包括了一些默认的实现,我们在自定义类的时候都需要去继承这个抽象类,然后根据我们不同的需求,对于其中的方法进行重写。
从容器角度上来说,只有四种容器:MapQueueSetList

简单介绍:

下面我们对基本的分类进行一个简单的介绍和了解,后续我们会从数据结构和用法等方面去详细学习。

ArrayList: 一种可以动态增长和缩减的的索引序列
LinkedList:一种可以在任何位置进行高效地插入和删除操作的有序序列
ArrayDeque:一种用循环数组实现的双端队列
HashSet:一种没有重复元素的无序集合
TreeSet:一种有序集
EnumSet:一种包含枚举类型值的集
LinkedHashSet:一种可以记住元素插入次序的集
PriorityQueue:一种允许高效删除最小元素的集合
HashMap:一种存储键/值关联的数据结构
TreeMap:一种键值有序排列的映射表
EnumMap:一种键值属于枚举类型的映射表
LinkedHashMap:一种可以记住键/值项添加次序的映射表
WeakHashMap:一种其值无用武之地后可以被垃圾回收期回收的映射表
IdentityHashMap:一种用==而不是用equals比较键值的映射表
Vector:目前使用较少,因为设计理念的陈旧和性能的问题被ArrayList所取代
Hashtable:线程非同步可以使用HashMap来替代,同步的话可以使用ConcurrentHashMap来替代

Iterator

我们接下来聊一下迭代器,从鸟瞰图中我们可以看到,所有实现Collection的子类都继承了Iterable接口。这个接口提供了一个iterator()方法可以构造一个Iterator接口对象。然后我们可以使用这个迭代器对象依次访问集合中的元素
迭代器一般使用方法是这样的:

Collection<String> c = ...;
Iterator<String> iter = c.iterator();
while (iter.hasNext()) {
    String s = iter.next();
    System.out.println(s);
}

或者是这样的:

//适用于JDK1.8以后的版本
iter.forEachRemaining(element -> System.out.println(element));

我们接下来看一下Iterator的源码(Base jdk1.8):

package java.util;

import java.util.function.Consumer;

public interface Iterator<E> {
    
    boolean hasNext();

    E next();

    default void remove() {
        throw new UnsupportedOperationException("remove");
    }

    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

迭代器的next()工作原理是这样的:

可以看出,迭代器是位于两个集合元素之间的位置,当我们调用next()方法的时候迭代器指针就会越过一个元素,并且返回刚刚越过的元素,所以,当我们迭代器的指针在最后一个元素的时候,就会抛出会抛出一个NoSuchElementException的异常。所以,在调用next()之前需要调用hasNext()去判断这个集合的迭代器是否走到了最后一个元素。

通过调用next()方法可以逐个的去访问集合中的每个元素,而访问元素的顺序跟该容器的数据结构有关,比如ArrayList就是按照索引值开始,每次迭代都会使索引值加1,而对于HashSet这种数据结构是散列表的集合,就会按照某种随机的次序出现。

Iterator的接口中还有一个remove()方法,这个方法实际上删除的是上次调用next()方法返回的元素,下面我来展示一下remove()方法的使用方法

Collection<String> c = ...;
Iterator<String> iter = c.iterator();
iter.next();
iter.remove();

这样就可以删除该集合中的第一个元素,但是需要注意一点,如果我们需要删除两个元素,必须这样做:

iter.remove();
iter.next();
iter.remove();

而不能这么做:

iter.remove();
iter.remove();

因为next()方法和remove()方法之间是有依赖性的,如果调用remove之前没有调用next就会抛出一个IllegalStateException的异常。

PS: 我们日常中用的很多的foreach循环,其实就是一种语法糖,编译器会把foreach编译为带有迭代器的循环。

原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知


公众号

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,639评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,277评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,221评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,474评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,570评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,816评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,957评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,718评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,176评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,511评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,646评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,322评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,934评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,755评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,987评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,358评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,514评论 2 348

推荐阅读更多精彩内容

  • 四、集合框架 1:String类:字符串(重点) (1)多个字符组成的一个序列,叫字符串。生活中很多数据的描述都采...
    佘大将军阅读 738评论 0 2
  • 一、基础知识:1、JVM、JRE和JDK的区别:JVM(Java Virtual Machine):java虚拟机...
    杀小贼阅读 2,369评论 0 4
  • 概述 Java集合框架由Java类库的一系列接口、抽象类以及具体实现类组成。我们这里所说的集合就是把一组对象组织到...
    absfree阅读 1,251评论 0 10
  • 一、集合入门总结 集合框架: Java中的集合框架大类可分为Collection和Map;两者的区别: 1、Col...
    程序员欧阳阅读 11,547评论 2 61
  • 很多时候,我们的孩子出了各种问题,我们第一时间会想到把祂交出去,生病交给医院治病,心理问题找心理咨询师,学习不好请...
    侯君_6ef0阅读 434评论 0 0