轻松解读源码系列之Java集合接口ampampamp抽象类(3)ListSetQueue
大家好,我是程序员xiao熊,本篇内容将为大家分享Java集合接口Collection的三大子接口: List、Set、Queue ;这些接口和抽象类是Java集合框架的基础,为具体的子类实现提供了规范以及基础实现,降低了子类实现的成本; 本篇包含内容如下:List接口Set接口Queue接口扩展阅读
Collection的三大子接口1、List接口1.1、List接口介绍
List是一个有序的集合(也称为序列),继承自Collection,Collection是直接父接口;其具备了如下规范和特性:开发者可以很精确的控制在哪个位置插入新元素,同时也可以通过整型索引下标来访问元素,以及查询列表中的元素;List允许元素重复;更正确的说应该是List允许满足e1.equals(e2)的两个元素存在,也允许存在多个null元素(如果实现类允许存在null元素的话);但是也有例外,有的List是不允许元素重复,此时当开发者添加重复的元素时,会抛出异常; List接口除了从Collection继承的规则约束之外,对iterator, add, remove, equals, 以及hashCode方法还有一些约束规则; List接口提供了四个方法用于通过索引访问元素;List与数组一样,下标是从0开始的;需要注意的是,在某些实现中(例如LinkedList类),通过索引访问元素的执行时间与索引值成正比(具体原因参考《轻松解读源码系列之Java集合LinkedList(下)》的总结部分的第3点),性能会随着元素数量增加而降低。 List接口提供了一个特殊的Iterator:ListIterator,ListIterator除了Iterator提供的方法之外,还提供了添加元素、更新元素以及双向访问元素的功能;并且还提供了一个方法用于获取指定了索引位置的ListIterator; List接口提供了两个方法用于快速地在列表的任意位置添加或者删除多个元素;
子类实现接口时需要注意:List的具体实现可能会不允许元素重复,这时添加元素会抛出异常, 我们需要尽量避免这种实现方式,因为这并不太符合List的使用场景; 一些List的实现类对于包含的元素会有一些约束;例如,一些List实现不支持null元素,以及限制了数据元素类型;当添加一个不符合条件的元素,则一般会抛出非检查异常(一般是 NullPointerException 或者ClassCastException); 查询一个不符合规范的元素,也许会抛出异常,也许直接返回false;此外 ,尝试对不符合条件的元素进行操作时,首先操作的完成不会导致不符合条件的元素插入到集合中,但操作可能会抛出异常,也可能会执行成功(不符合条件的元素不会进入集合,只是方法执行成功),具体取决于实现方式。
使用的注意事项:如果调用者不知道所使用的列表的底层原理的话,遍历链表中的元素通常比索引的方式更好一点。 List接口提供了两个方法用于查询特定的对象;从性能的角度来看,这些方法应该谨慎使用。在许多实现中,它们将执行代价高昂的线性搜索。 虽然列表允许包含自己作为元素,但还是要格外小心:equals和hashCode方法已经不适用这样的列表了。 1.2、List接口方法说明
boolean add(E e)
将元素添加至列表尾部
void add(int index, E element)(新增)
在指定位置添加元素
boolean addAll(Collection<? extends E> c)
添加一个集合中的元素到当前集合的尾部
boolean addAll(int index, Collection<? extends E> c) (新增)
在指定位置添加指定集合中的所有元素至当前集合的尾部
void clear()
清除集合元素
boolean contains(Object o)
判断是否包含指定的对象
boolean containsAll(Collection<?> c)
判断是否包含集合中的所有元素
boolean equals(Object o)
判断对象是否与当前集合相等,要求:集合的元素相等、元素顺序相同
E get(int index) (新增)
获取指定索引位置的元素
int hashCode() 返回集合的hashCode;逻辑如下:
int hashCode = 1;
for (E e : list)
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
int indexOf(Object o) (新增)
获取指定对象在列表中的索引位置(从头部开始)
boolean isEmpty()
判断结合是否为空
Iterator iterator()
返回列表的iterator对象
int lastIndexOf(Object o) (新增)
返回指定对象在列表的索引位置(从尾部开始)
ListIterator listIterator()(新增)
返回列表的listiterator
ListIterator listIterator(int index) (新增)
返回定位在指定索引位置处的listiterator
E remove(int index) (新增)
删除指定所以位置处的元素
boolean remove(Object o)
删除指定对象
boolean removeAll(Collection<?> c)
删除存在于指定集合中的元素
default void replaceAll(UnaryOperator operator) (新增)
根据原来的元素计算新的元素,并进行替换
boolean retainAll(Collection<?> c)
保留指定集合中元素
E set(int index, E element) (新增)
更新指定索引位置处的元素
int size()
返回元素数量
default void sort(Comparator<? super E> c) (新增)
按照指定的comparator进行排序
default Spliterator spliterator()
返回List的spliterator
List subList(int fromIndex, int toIndex) (新增) 根据开始和结束下标获取子列表
注意:不包含下标范围,例如: [1, 6)
Object[] toArray()
将元素以Object数组形式返回,返回的数组与集合互不影响
T[] toArray(T[] a)
返回指定类型的数组,返回的数组与集合互不影响2、Set2.1、Set接口介绍
Set接口是对数学上"集合"的抽象,是一个不会包含重复元素的集合,继承自Collection,Collection是其直接父级接口;更准确的说是set集合不会包含两个满足e1.equals(e2)的元素, 并且只有一个null元素;其具备以下规范和特性:除了从Collection继承的规则之外,Set接口对所有的构造函数、add、equals以及hashcode方法还增加了一些约束规则;所以Set接口再次声明了这些方法,而方法上声明的约束规则,仅仅只是针对Set接口的。 Set接口对构造函数增加的约束规则是:所有的构造函数创建的集合是没有重复元素的集合; 一部分Set接口的实现对其中的元素会有一些约束;例如,有一部分Set接口的实现禁止null元素,有一些实现类是对元素类型进行了限制;当尝试添加一个不符合规范的元素,则会抛出未检查异常,一般是NullPointerException 或者ClassCastException; 查询一个不符合规范的元素,也许会抛出异常,也许直接返回false;此外 ,尝试对不符合条件的元素进行操作时,首先操作的完成不会导致不符合条件的元素插入到集合中,但操作可能会抛出异常,也可能会执行成功(不符合条件的元素不会进入集合,只是方法执行成功),这取决于具体的实现策略。
使用的注意事项:
在时如果将可变对象用作set元素,则必须非常小心。如果对象是集合中的一个元素,但其值的改变影响了等值比较,则集合的行为将会是不确定的。还有一个特殊情况是,不允许一个集合包含自己作为一个元素; 2.2、方法说明
Set接口对add、equals以及hashcode有一些新增的规则约束,具体的方法如红色字体部分
boolean add(E e)
添加元素,如果元素已存在,则返回false,集合保持不变;否则元素添加成功
boolean addAll(Collection<? extends E> c)
添加集合中的元素至当前集合,如果元素已存在,不添加;最终的结果就是两个set集合的并集;需要注意的是,如果在add过程中,入参集合c发生了变化,则addAll操作的结果是不确定的
boolean equals(Object o)
比较指定对象与此集合是否相等。如果指定对象也是一个集合,两个集合的大小相同,并且指定集合的每个成员都包含在这个集合中(或者等价地说,这个集合的每个成员都包含在指定集合中),返回true;这个定义确保了equals方法的逻辑在set接口的不同实现中都是正确的;
int hashCode()
返回此集合的哈希码值。集合的哈希码定义为集合中元素的哈希码之和,其中null元素的哈希码定义为零。这确保了对于任意两个集合s1和s2, s1.equals(s2)意味着s1. hashcode ()==s2. hashcode(),这符合Object.hashCode()的一般约定。
void clear()
清除集合中的元素
boolean contains(Object o)
判断是否包含某个元素
boolean containsAll(Collection<?> c)
判断是否包含指定集合中的所有元素
boolean isEmpty()
判断当前集合是否是空集合
Iterator iterator()
返回当前集合的iterator对象
boolean remove(Object o)
删除指定的元素对象,如果元素存在,则返回true;否则返回false;
boolean removeAll(Collection<?> c)
删除当前集合中存在于指定集合中的元素;如果当前集合于指定的集合有交集,则返回true(说明当前集合会发生变化);否则返回false;
boolean retainAll(Collection<?> c)
保留存在于指定集合中的所有元素
int size()
返回集合中元素的数量
default Spliterator spliterator()
返回集合的spliterator对象
Object[] toArray()
将元素以Object数组形式返回,返回的数组与集合互不影响
T[] toArray(T[] a)
返回指定类型的数组,返回的数组与集合互不影响3、Queue3.1、Queue接口介绍
队列是在队头删除/获取元素,在队尾添加元素的线性表,在JDK中对应的接口是Queue;Queue继承自Collection接口,Collection是其直接父接口。除了基本的集合操作,Queue还提供了插入、获取(删除)和检索元素的操作。每类方法都有两种形式:一种在操作失败时抛出异常,另一种返回特殊值(null或false,取决于操作)。其中,insert操作返回特殊值的形式专门设计用于有容量限制的队列实现。在其他大多数实现中,insert操作不会失败。
队列方法总结
抛出异常
返回固定的值
Insert操作
add(e)
offer(e)
Remove操作
remove()
poll()
Examine操作(检索元素)
element()
peek()
元素顺序规则:
队列一般是按照FIFO的规则存放元素;但是在队列的实现类中,也有例外,例如PriorityQueue,它是按照元素的comparator的结果决定元素顺序,或者是元素本身的顺序。LIFO队列(或者是栈)也是例外,它是按照LIFO(后进先出)的规则存放元素。不管以什么排序规则存储元素,队列的头结点(第一个元素)是remove()或者poll()方法在被调用时需要删除的元素。在一个FIFO队列中,所有新加入的元素都会被添加到对列表尾部;其他类型的队列具体实现,可能会使用不同的存放元素的规则;对于队列的实现类来说,必须要指定存放元素排序规则;
实现队列的注意事项: Queue接口并没有定义阻塞队列(blocking queue)的方法,阻塞队列通常用在并发编程中/并发环境中;阻塞队列的方法会阻塞等待队列中有元素,或者队列中有空间存储元素;阻塞队列的直接父级接口是Queue; 队列的实现通常不会定义基于元素的版本的equals和hashCode方法,而是从Object类继承基于identity(身份/标识)的版本,因为元素相同但顺序属性不同的队列,基于元素的相等的规则并不是很好定义;
队列使用注意事项:
Queue的实现类通常不允许插入null值,不过也有例外的实现类:LinkedList;LinkedList是可以接收null值;但是即使实现类设计为可以接收null值,也最好不要把null值存入队列中,因为null值在某些场景下是有用的,例如poll方法通过返回null值,表示队列为空, 3.2、方法说明
由于Queue了继承了Collection, 也会拥有Collection的方法,约束和实现规范与Collection保持一致,具体参考Collection的说明;此外,Queue作为队列的实现,还提供了队列专用的方法,具体如下:
boolean add(E e)
在队列尾部添加元素,如果添加成功,则返回true,如果添加失败,则抛出异常
E element()
获取队列头结点元素,但不会删除;如果队列为空,会抛出异常
boolean offer(E e)
在队列尾部添加元素,如果添加成功,则返回true,如果添加失败,则返回false(这是与add()的区别)
E peek()
获取队列头结点元素,但不会删除;如果队列为空,则会返回null
E poll()
获取队列头结点元素,并删除;如果队列为空,则会返回null
E remove()
获取队列头结点元素,并删除;如果队列为空,则会抛出异常4、扩展阅读
更多关于Java集合的内容,可参考以下文章:轻松解读源码系列之Java集合接口&抽象类(1)—Map和Collection轻松解读源码系列之Java集合接口&抽象类(2)—AbstractCollection轻松解读源码系列之Java集合ArrayList(上)轻松解读源码系列之Java集合ArrayList(下)轻松解读源码系列之Java集合LinkedList(上)轻松解读源码系列之Java集合LinkedList(中)轻松解读源码系列之Java集合LinkedList(下)轻松解读源码系列之ArrayList和LinkedList总结
欢迎关注【程序员xiao熊】,今天的分享就到这里,欢迎大家在评论区进行交流
唐山打人事件最新,法医鉴定最终结果出炉,恐引众怒,能判几年?唐山打人事件最新,法医鉴定最终结果出炉,恐引众怒,能判几年?千呼万唤之下,就算是胡锡进,也只是委婉地提醒了一句。唐山烤肉店殴打妇女事件发生11天后,河北省公安厅首次发布了事故通报。
上将军赋国之荩臣,民之大幸,盖世豪杰,谓上将军细柳旌旗,怯薛骅骝黑甲锋锐,虎贲骠骑。治御万众,如臂指使奋起当先,所向无敌。顺不妄喜,逆不惶馁安不奢逸,危不惊惧。坚毅如钢,百战淬火。纵横天下,无坚不摧。胸有惊雷,面如平湖运筹帷幄
教育黑板报丨一周教育信创热点关注(06。06本周最热以推进信息技术应用为抓手!教育部党组人民日报撰文筑牢教育强国建设之基6月9日,教育部党组在人民日报刊发文章筑牢教育强国建设之基。文章指出,以推进信息技术应用为抓手,进一步推
高陵区首批西安菜园子农产品区域公用品牌包装箱免费发放视频加载中近日,首批由西安市高陵区农业农村和林业局印制的西安菜园子农产品区域公用品牌系列农产品包装箱免费向已授权的10家优质名特优果蔬生产销售的农业经营主体发放,本次发放的特色农产
女子发现大家都不坐长椅,好奇地她坐了上去,顿时被烫到跳起来在夏天,有时接触到刚刚经历过暴晒的沙子石材等等,往往会感觉到发烫,相信大家或多或少都有类似的经历。这也成为很多人夏天难以忘怀的记忆。不过,很多时候,这些物体表面的温度是很难用肉眼看
张哲张翼张熙张敏张哲(13351420年),字子玄,秦州西关(今甘肃天水秦州区西关)人。明洪武五年(1372年)中举入仕,授户部主事,擢升员外郎。张哲为官清正,处事无忤,同朝融融。父卒丁忧,产业丰
墨菲如果埃里克森和B费搭档中场,曼联在下赛季的表现会更糟糕直播吧6月21日讯近日,前英格兰国脚丹尼墨菲接受了TalkSport的采访,在采访中他表示并不认为埃里克森是适合曼联的选择。墨菲表示,如果曼联签下埃里克森,并让他和B费搭档中场,那
皮肤瘙痒可能存在的原因?皮肤瘙痒患者要明确病因,可能是天气干燥等生理因素引起,也可能是湿疹体癣接触性皮炎荨麻疹等疾病引起,可以通过一般治疗药物治疗等方式止痒。1。生理因素由于天气干燥,人体水分流失较多,可
日常搞笑段子1。小时候,我妈不止一次跟我说,亲嘴会怀孕,亲嘴会怀孕,结果我家猫跳起来抢肉吃的时候好死不死亲到了我的嘴,过了几个月它还生下了三只小猫出于责任感,有我一口肉吃,我就不会让那三只小猫
搞笑日常辅导员这个语气是不是生气了搞笑一刻本文有16条内容,预计阅读时长3分钟,望能博君一笑,笑口常开好彩自然来老师这个语气,是不是生气了是不是应该这个语气,老师好的呢猪猪,路上注意安全,吃饱饱穿暖暖哒,一定要照顾
120万一针抗癌药,上海首位患者治疗成功!一个月肿瘤消失,值吗120万元打一针,就能让癌细胞消失?说起癌症,几乎人人都怕,作为一种致死率高治疗难度大的疾病,癌症在更多时候意味着绝症。伴随着科技的进步,人类对癌症的探索也进入了新的阶段,如今的癌