轻松解读源码系列之Java集合接口ampampamp抽象类(
大家好,我是程序员xiao熊,本篇内容将为大家分享Java集合的主要接口和抽象类;这些接口和抽象类是Java集合框架的基础,为具体的子类实现提供了规范以及基础实现,降低了子类实现的成本;
Java集合的底层接口主要分为两个:Map和Collection;其对应的继承结构图如下所示;本篇内容主要是对Map、Collection、Iterable这三个接口以及其中的部分默认方法进行讲解,其他的接口和抽象类将在后续的文章中进行讲解,会按照Map和Collection体系分别讲解,并且尽量按照图中的层次从上至下,一层层讲解;
Collection体系继承结构图
Map体系继承结构图1、Iterable接口
Iterable接口相对简单,实现这个接口的对象,可以使用foreach循环语句,也可以通过iterator遍历元素1。1方法说明
defaultvoidforEach(Consumerlt;?superTaction)
对Iterable对象的每个元素执行指定的操作(action),直到所有元素都处理完毕或操作(action)抛出异常(异常抛给调用者)
Iteratoriterator()
返回类型为T的元素的迭代器,T是集合元素的类型
defaultSpliteratorspliterator()
返回Spliterator对象2、Collection接口
集合是一组对象,对象就是集合里面的元素;在JDK中,Collection是集合对应的实现,是集合框架结构中的根接口,它提供了集合应该具备的操作规范(方法);在集合的具体实现类中,有些集合允许重复元素,有些则不允许,有些是有序的,有些是无序的,具体取决于实现类。JDK中的具体实现类并没有直接实现这个接口,因为JDK根据场景提供了更具体的子接口,如Set和List。实现类都是实现这些具体的接口或者对应的抽象方法。Collection这个接口通常用于传递集合,并在需要最大通用性的情况下对集合进行操作。
集合规范中提到,Collection的实现类一般可以提供两个构造函数
1。无参构造函数:创建一个空的集合
2。入参类型是Collection的构造函数:目的是创建一个包含入参集合元素的集合(即复制入参集合)
Collection的具体实现类根据场景,在实现Collection接口的方法时,会抛出一些异常,具体如下:
1。如果collection的实现类不支持的操作,则实现类在方法体中需要抛出UnsupportedOperationException异常
2。Collection的不同实现类对元素类型可能会有限制,例如不能null,或者只接受指定的元素类型;因此可能会抛出非检查异常,例如:NullPointerException或ClassCastException;添加不符合的元素时,可能抛出异常,可能执行成功(只是方法执行成功),但是元素并不会进入到集合中;对于查询不符合条件的元素,会直接返回false
3。Collection默认不支持同步控制,实现类可以自行指定具体使用的同步控制策略;
4。默认方法实现(继承的或其他方式)没有使用任何同步协议。如果集合的实现类需要使用同步协议,那么它必须覆盖默认方法的实现以使用同步协议。
使用的注意事项:
集合的元素需要注意,如果元素直接或者间接包含了自身引用,则某些对集合执行递归遍历的操作可能会失败(抛出异常),例如clone()、equals()、hashCode()和toString()方法。具体示例如下:集合元素publicclassSelfRef{SelfRefselfRef;publicSelfRefgetSelfRef(){returnselfRef;}publicvoidsetSelfRef(SelfRefselfRef){this。selfRefselfRef;}OverridepublicStringtoString(){returnselfRef。toString();}}集合操作示例代码ArrayListSelfRefselfRefListnewArrayList();SelfRefselfRefnewSelfRef();selfRef。setSelfRef(selfRef);selfRefList。add(selfRef);selfRef。toString();抛出异常2。1、方法说明booleanadd(Ee)
添加元素到集合中booleanaddAll(Collectionlt;?extendsEc)
添加一个集合中的元素到当前集合中voidclear()
清除集合中的元素booleancontains(Objecto)
判断集合是否包含指定的对象booleancontainsAll(Collectionlt;?c)
判断是否包含指定集合中所有的元素booleanequals(Objecto)
判断是否与指定的对象相等inthashCode()
返回集合的hash码booleanisEmpty()
判断集合是否为空Iteratoriterator()
返回包含元素的iterator对象defaultStreamparallelStream()
返回并发执行的流对象(这是默认方法,已有具体逻辑)booleanremove(Objecto)
删除指定的元素booleanremoveAll(Collectionlt;?c)
删除存在于指定集合中所有的元素defaultbooleanremoveIf(Predicatelt;?superEfilter)
根据谓词对象删除符合条件的元素(这是默认方法,已有逻辑)booleanretainAll(Collectionlt;?c)
保留存在于指定集合中的所有元素intsize()
返回返回集合中元素的数量defaultSpliteratorspliterator()
返回包含元素的spliterator对象(这是默认方法,已有逻辑)defaultStreamstream()
返回包含元素的流对象(这是默认方法,已有逻辑)Object〔〕toArray()
将元素以Object数组形式返回,返回的数组与集合互不影响
T〔〕toArray(T〔〕a)
返回指定类型的数组,返回的数组与集合互不影响2。2、方法解析
对于Collection接口,本小节对removeIf方法进行分析说明,该方法是删除集合中符合谓词表达式的元素;其业务逻辑过程如下
1。谓词对象非空校验
2。获取迭代器iterator
3。利用while循环和iterator遍历链表的中的元素
4。利用谓词对象的test方法验证元素是否符合谓词表达式,符合,则利用iterator删除该元素,然后返回步骤3,进行下一轮循环;
removeIf方法具体代码如下:defaultbooleanremoveIf(Predicatelt;?superEfilter){1。谓词对象非空校验Objects。requireNonNull(filter);booleanremovedfalse;2。获取迭代器iteratofinalIteratorEeachiterator();3。利用while循环和iterator遍历链表的中的元素while(each。hasNext()){4。利用谓词对象的test方法验证元素是否符合谓词表达式,符合,则利用iterator删除该元素,然后返回步骤3,进行下一轮循环if(filter。test(each。next())){each。remove();removedtrue;}}returnremoved;}3、Map
Map是将key和value进行映射的对象;一个Map对象不能包含重复的key值,一个key最多只能映射到一个value,即key与value是一一对应的;Map接口的出现是对抽象类Dictionary的替代;
Map接口提供了三个视图:key的集合视图,value的集合视图,keyvalue映射关系的集合视图;Map的顺序是指Map集合视图中迭代器返回元素的顺序。有些Map接口的实现类会明确指定元素的顺序,比如TreeMap类;其他实现类则不一定能够保证元素的顺序是固定的,如HashMap类。
集合规范中提到,Map实现类一般可以提供两个构造函数:
1。无参构造函数,用于创建一个空的Map;
2。只有一个Map类型的参数的构造函数:用于创建一个新的Map,其keyvalue的映射关系与参数Mapd对象相同。实际上是允许用户复制任何Map,生成一个等效的Map。
Map的实现类根据不同的场景使用不同的实现策略,总体原则如下:
1。如果不支持修改Map的方法,则在操作修改Map的方法时,会抛出UnsupportedOperationException异常。
2。有些Map的实现对包含的key和value有限制。例如,有些实现类禁止空的key和空value,有些实现类对key的类型有限制。尝试插入不符合条件的key或value会抛出未检异常,通常是NullPointerException或ClassCastException。查询不符合条件的key或value可能会抛出异常,也可能直接返回false。更一般地说,如果对不符合条件的key或value进行操作,而操作可能会抛出异常,也可能会成功,这取决于实现方式;但操作无论成功还是失败都不会导致不符合条件的元素插入到Map中,则这种异常在此接口的规范中标记为可选。
使用中的注意事项:
1。如果使用可变对象作为Map的键,则必须要注意。因为如果一个对象的值发生了改变(这个会影响equals方法的比较结果),而该对象是Map中的key,那么Map的行为将会变得不确定。还有一个特殊情况是,不允许Map将自身作为key。虽然Map允许将自身包含为一个value,但我们要特别小心:equals和hashCode方法的定义已经不适用这样的Map了。
2。一些对Map进行递归遍历的操作可能会失败,当map直接或间接包含自己时,会出现自引用实例的异常。其中包括clone()、equals()、hashCode()和toString()方法。具体如下:元素publicclassSelfRef{SelfRefselfRef;publicSelfRefgetSelfRef(){returnselfRef;}publicvoidsetSelfRef(SelfRefselfRef){this。selfRefselfRef;}OverridepublicStringtoString(){returnselfRef。toString();}}示例代码MapString,SelfRefselfRefMapnewHashMap();selfRefMap。put(selfRef,selfRef);selfRefMap。toString();抛出异常3。1、方法说明voidclear()
清除Map中的元素defaultVcompute(Kkey,BiFunctionlt;?superK,?superV,?extendsVremappingFunction)
尝试为指定的key及其当前的value(如果key不在Map中则value为空)计算新的value值;如果key在Map中,并且新的value不为空,则更新value值,否则删除key对应元素
如果Key不在Map中,新的value不为空,则将key和新的value加入到Map中,如果新的value为空,则Map保持不变defaultVcomputeIfAbsent(Kkey,Functionlt;?superK,?extendsVmappingFunction)
为指定的key计算新的value值;如果key不在Map中,或则映射到null,并且新的value不为null,则加入Map;否则Map保持不变defaultVcomputeIfPresent(Kkey,BiFunctionlt;?superK,?superV,?extendsVremappingFunction)
为指定的key计算新的value值;如果key在Map中,并且对应的value不为空;在新的value不为null时,则Map中key对应的value;否则删除Map中的keybooleancontainsKey(Objectkey)
判断是否包含指定的keybooleancontainsValue(Objectvalue)
判断是否包含指定的valueSetMap。EntryK,VentrySet()
返回keyvalue对象的集合视图booleanequals(Objecto)
判断当前Map是否等于指定的对象defaultvoidforEach(BiConsumerlt;?superK,?superVaction)
循环对元素执行指定的操作actionVget(Objectkey)
获取指定key对应的value,如果key不存在,则返回nulldefaultVgetOrDefault(Objectkey,VdefaultValue)
获取指定key对应的value,如果key不存在,则返回指定的默认值defaultValueinthashCode()
返回Map的hashcodebooleanisEmpty()
判断Map是否为空,但map为null,则会抛出异常
SetkeySet()
返回Key对象的集合视图
defaultVmerge(Kkey,Vvalue,BiFunctionlt;?superV,?superV,?extendsVremappingFunction)
计算key对应的value值,如果原的value为null或者key不存在,则将参数的value作为key的新value;如果key对应的原value不为空,则通过remappingFunction重新计算新的value值,如果新的value值不为空,则更新key的value值或者将key添加至集合中,如果新的value为空,则删除key对应的元素
Vput(Kkey,Vvalue)
将Key与value进行关联
VoidputAll(Maplt;?extendsK,?extendsVm)
将入参Map中keyvalue对象复制到当前的Map中
defaultVputIfAbsent(Kkey,Vvalue)
为当前存在于Map中的key关联新的value值
Vremove(Objectkey)
删除指定的key对应的元素
defaultBooleanremove(Objectkey,Objectvalue)
删除Map中key和value与指定的key和value匹配的元素
defaultVreplace(Kkey,Vvalue)
替换key对应的value,如果key不存在,则不操作
defaultBooleanreplace(Kkey,VoldValue,VnewValue)
如果key的原value与入参oldvalue匹配,则替换key的value为newValue,如果不满足,则不操作
defaultvoidreplaceAll(BiFunctionlt;?superK,?superV,?extendsVfunction)
将Map中所有的key的value进行更新,新的value由入参指定的函数确定
Intsize()
返回Map中元素刷领
Collectionvalues()
返回value的集合视图3。2、方法解析
jdk1。8开始,接口允许默认方法有方法,本小节针对以下几个默认方法进行讲解分析:
1。compute()
2。computeIfAbsent()
3。computeIfPresent()
4。merge()3。2。1、Compute方法
Compute方法是根据当前的key以及对应value,利用remappingFunction对象计算新的value值,具体业务逻辑如下:
1。remappingFunction对象的非空校验,remappingFunction对象是用于计算新的value的值
2。根据key获取对应的value
3。根据key、原有的value(oldValue),通过remappingFunction的apply方法计算新的value值
4。新的value值(newValue)等于null,
4。1。如果key存在于Map中,则需要删除key对应的元素,返回null;
4。2。如果key不在Map中,则不处理,Map保持不变,返回null;
5。新的value值不等于null,则将key和新的value值存入Map中,返回新的value值
代码如下:defaultVcompute(Kkey,BiFunctionlt;?superK,?superV,?extendsVremappingFunction){1。remappingFunction对象的非空校验,remappingFunction对象是用于计算新的value的值Objects。requireNonNull(remappingFunction);2。根据key获取对应的valueVoldValueget(key);3。根据key、原有的value(oldValue),通过remappingFunction的apply方法计算新的value值VnewValueremappingFunction。apply(key,oldValue);4。新的value值(newValue)等于nullif(newValuenull){4。1如果key存在于Map中,则需要删除key对应的元素,返回null;if(oldValue!nullcontainsKey(key)){somethingtoremoveremove(key);returnnull;}else{4。2如果key不在Map中,则不处理,Map保持不变,返回null。returnnull;}}else{5。新的value值不等于null,则将key和新的value值存入Map中,返回新的value值addorreplaceoldmappingput(key,newValue);returnnewValue;}}3。2。2、computeIfAbsent
computeIfAbsent与Compute类似,在新的value值不为null的前提下,只有在key不存在Map中,或者key对应的原value为null时,才会更新key的value值为新的值;具体业务逻辑如下:
1。mappingFunction对象的非空校验,mappingFunction对象是用于计算新的value的值
2。根据key获取对应的value
3。如果value为null(表示key不存在,或者对应的value为null),则根据key,通过mappingFunction的apply方法计算新的value值
4。新的value值(newValue)不等于null,则将key和新的value值存入Map中,返回新的value值
代码如下:defaultVcomputeIfAbsent(Kkey,Functionlt;?superK,?extendsVmappingFunction){1。mappingFunction对象的非空校验Objects。requireNonNull(mappingFunction);Vv;2。根据key获取对应的valueif((vget(key))null){VnewValue;3。如果value为null(表示key不存在,或者对应的value为null),则根据key,通过mappingFunction的apply方法计算新的value值if((newValuemappingFunction。apply(key))!null){4。新的value值(newValue)不等于null,则将key和新的value值存入Map中,返回新的value值put(key,newValue);returnnewValue;}}returnv;}3。2。3、computeIfPresent
computeIfPresent与Compute类似,在key存在Map中的前提下,新的value不为null时,才会更新key的value值为新的值,新的value为null时,删除key对应的元素;具体业务逻辑如下:
1。remappingFunction对象的非空校验,remappingFunction对象是用于计算新的value的值
2。根据key获取对应的value
3。如果原有的value不为null,才处理新的值
3。1。根据key、原有的value(oldValue),通过remappingFunction的apply方法计算新的value值
3。2。新的value值不等于null,则将key和新的value值存入Map中,返回新的value值
3。3。新的value值(newValue)等于null,则需要删除key对应的元素,返回null;
4。如果原有的value为null,或者key不存在,则不做任何操作,直接返回nulldefaultVcomputeIfPresent(Kkey,BiFunctionlt;?superK,?superV,?extendsVremappingFunction){1remappingFunction对象的非空校验Objects。requireNonNull(remappingFunction);VoldValue;2根据key获取对应的value3如果原有的value不为null,才处理新的值if((oldValueget(key))!null){3。1根据key、原有的value(oldValue),通过remappingFunction的apply方法计算新的value值VnewValueremappingFunction。apply(key,oldValue);3。2新的value值不等于null,则将key和新的value值存入Map中,返回新的value值if(newValue!null){put(key,newValue);returnnewValue;}else{3。3新的value值(newValue)等于null,则需要删除key对应的元素,返回null;remove(key);returnnull;}}else{4如果原有的value为null,或者key不存在,则不做任何操作,直接返回nullreturnnull;}}3。2。4、merge
merge方法生成value的方式比之前的所有类似;计算新的value由两种方式将入参的第二个参数作为新的value值根据第二个参数value和原value,利用remappingFunction对象计算新的value的值
具体业务逻辑过程如下:
1。remappingFunction对象的非空校验
2。方法的value对象(第二个参数)的非空校验
3。根据key获取对应的原value
4。如果原value为null,则取入参的第二个参数value作为新的值;如果原有的value不为null,则使用原有的value、入参的value(第二个参数),通过remappingFunction计算新的value
5。如果新的value为null,将key从Map中删除,返回新的value值(为null)
6。如果新的value不为null,将key和新的value值存入Map中,返回新的value值
具体代码如下:defaultVmerge(Kkey,Vvalue,BiFunctionlt;?superV,?superV,?extendsVremappingFunction){1remappingFunction对象的非空校验Objects。requireNonNull(remappingFunction);2方法的value对象(第二个参数)的非空校验Objects。requireNonNull(value);3根据key获取对应的原valueVoldValueget(key);4如果原value为null,则取入参的第二个参数value作为新的值;如果原有的value不为null,则使用原有的value、入参的value(第二个参数),通过remappingFunction计算新的valueVnewValue(oldValuenull)?value:remappingFunction。apply(oldValue,value);5。如果新的value为null,将key从Map中删除,返回新的新的value值if(newValuenull){remove(key);}else{6。如果新的value不为null,将key和新的value值存入Map中,返回新的value值put(key,newValue);}returnnewValue;}
欢迎大家关注【程序员xiao熊】,今天的分享就到这里,欢迎大家在评论区进行交流
人生悟语知多知少知足难,治偷治赌难治贪。古今多少贵与贱,以身犯法赴黄泉。荣华富贵似云烟,金山银山岂能搬。洞彻世间谙真谛,淡泊名利方身安。俗话说知足常乐,看似简单的四个字,但自古以来有多少人
今生,你是我最美的遇见今生,你是我最美的相遇文理想那个芦花飞絮的日子不经意间,我遇见你你那唯美浪漫的诗情画意让我深深沉醉喜欢你的纯净爱的表达,毫无功利浅笑嫣然,诗意流淌爱的挥洒,情不自已驰骋赛场,何等霸
战胜自己就赢得了半个世纪内心自卑的人都没脾气,遇到问题,别人一生气就不知道南北,因为他们内心自卑,这就是一个很大的弱点,低头并不能换来什么,没有任何人会为你的懦弱,发出怜悯。唯有燃烧心中的心火,才能站稳脚
人世间寻找小组生活家人世间文心安于勤佛说一花一世界,一草一天堂,一叶一如来,一砂一极乐,一方一净土,一笑一尘缘,一念一清净。图片来源于网络,侵权删之人生,每个人的起点相同,都是从一开始,
你说他对我很好在情感咨询中经常会遇到来访,抱怨对象对自己的种种伤人伤心之事,表现出非常痛苦的表情,但尽管如此,自己还乐此不疲的跟这样的人在一起,问她为什么不离开这段感情?回答是因为他对我还是很好
家里放了几年的红茶绿茶普洱茶,还能不能拿来喝?导语对于古代人来说,茶叶其实就是灵感的来源,在古代是特别注重诗词创作的,大家也会经常以诗会友,以茶会友。茶叶飘香四溢,让人的心情都变得宁静安静下来,而古代文人之间也总是有着一些说不
宠妻!巨富老公问王楠生日要啥惊喜,楠姐啥都不缺,让我暴打你一顿10月23日消息,23日是国乒大满贯王楠的生日,亿万巨富老公郭斌一大早起床就问老婆想要什么礼物,结果王楠说生日都不想过,还调侃要暴打老公一顿,十分逗比!王楠老公名叫郭斌,1970年
hinova10参数配置hinova10详情介绍我在头条搞创作第二期中邮通信发布了最新手机产品Hinova10,其延续前一代的星耀环设计,拥有四款颜色,分别是10号色曜金黑绮境森林和普罗旺斯。接下来就让我们详细看看这款手机的具体
微信按下发送键那0。1秒,消息都经历了什么?微信这个app相信各位朋友对它非常了解了吧?你手机没电了或者丢了,第一时间想到的肯定是没法联系微信的好友了吧。现如今在我们的日常生活中,微信成为了用户最常用的,而且是用户最依赖的应
博士茶馆元宇宙时代新商业生态一我们博士茶馆平台做什么?立足创业孵化免费公益服务平台,携手更多中国茶企品牌产业走向互联网市场。弘扬茶业文化和健康养生,传播元宇宙互联网思维,从中国茶经典高端人脉商务社交与健康一起
你心中的宇宙是什么?地球与月球做为宇宙中最基本的星体单位,相当于人类发现的最小的物质跨克,由众多跨克物质,组成了太阳系物质中子体。由众多太阳系物质中子体,组成了相当于原子物质体银河系。由众多银河系原子