阿里深资架构师花了一个晚上整理出Java集合框架

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

什么是集合

通俗来讲集合就是用来存放数据的容器。Java的集合中只能存储对象的引用(即引用类型),在集合中每一个元素都是一个引用变量,实际内容是存放在堆内或方法区里的;不能存储Java中8种基本数据类型,因为基本数据类型是在栈内存上分配空间的,而栈上的数据随时会被收回,但是因为8种基本数据类型都有对应的包装类(对象),所以当我们将基本数据类型的数据存入集合中,Java会将基本数据类型自动装箱为对应的包装类(如int变为Integer),然后再将引用类型存入到集合中。

集合和数组的区别

  • 数组存放的类型只能是基本数据类型或引用数据类型,集合中存放的数据类型只能是引用数据类型。

  • 数组是静态的,一个数组实例具有固定的大小,一旦创建了不能改变容量。而集合是可以动态扩展容量,可以根据需要动态改变大小。

  • 初始化数组时需要声明存放在数组中的数据类型,而集合可以声明或不声明,当不声明时默认为Object类型,Object是Java中的超类,这就意味着一个集合中可以存放混合类型的数据(既存放String类型的数据又存放Integer类型的数据)

Collection和Collections的区别

  • java.util.Collection 是一个集合接口(集合类的一个顶级接口)。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。

  • Collections则是集合类的一个工具类/帮助类,其中提供了一系列静态方法,用于对集合中元素进行排序、搜索以及线程安全等各种操作。

Java集合框架的基础接口

  • Collection,Collection是集合框架的基础接口之一,在Java中不提供该接口的任何直接实现。
  • Map,Map是一个将key映射到value的对象,一个Map不能包含重复的key,每个key最多映射到一个value。
  • List,List是一个可以包含重复元素的集合
  • Set,Set是一个不能包含重复元素的集合
  • Queue,Queue接口是数据结构中队列结构的实现
  • Iterable,Iterable接口的实现类可以对集合进行遍历(如Iterator)

Collection接口相关类图

image.png

Map接口相关类图

image.png

Java集合框架常用集合类

image.png

List接口

实现List接口的集合是有序的,List接口主要有四个实现类: 分别是ArrayList、Vector、LinkedList和CopyOnWriteArrayList

如何遍历一个List集合

  • for循环遍历
for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}
复制代码
  • Iterator迭代器遍历
//获取迭代器
Iterator iterator = list.iterator();
//判断是否还有元素
while(iterator.hasNext()){
   System.out.println(iterator.next());
}
复制代码
  • forEach循环遍历。forEach内部也是采用Iterator迭代器实现集合遍历的,在使用时无需显式地声明Iterator迭代器,但是使用forEach遍历List集合时,不允许在遍历的过程中对集合元素进行删除或者修改。
for (Object o : list) {
    System.out.println(o);
}
复制代码

最佳实践

  • 在Java集合中提供了一个RandomAccess(随机存取)接口,如果一个集合实现了该接口,那么该集合就支持随机快速存取,例如ArrayList就实现了该接口,那么它就支持随机快速存取,其底层遍历集合元素时采用的是for循环,遍历或者查询速度都非常快。
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
复制代码
  • 在集合工具类Collections中,binarySearch()二分查找方法,就运用到这一点,在采用该方法进行元素查找是,会先判断集合是否实现了RandomAccess接口从而判断是使用indexedBinarySearch()[索引] 方法还是iteratorBinarySearch()[迭代器] 方法。
public class Collections {
    public static <T>
    int binarySearch(List<? extends Comparable<? super T>> list, T key) {
        if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
            return Collections.indexedBinarySearch(list, key);
        else
            return Collections.iteratorBinarySearch(list, key);
    }
}
复制代码

Iterator与ListIterator的区别

ArrayList使用迭代器遍历集合时,获取迭代器的iterator()方法是List接口中的 iterator()方法,调用该方法返回的是 Iterator对象,而LinkedList获取迭代器的iterator()方法是AbstractSequentialList抽象类中的 iterator()方法,在该方法中又调用了AbstractList抽象类中的listIterator()方法返回一个ListIterator对象

Iterator和ListIterator区别

  • Iterator可以遍历 Set 和 List 集合,而ListIterator只能用于遍历List。
  • Iterator和ListIterator都可实现删除元素,但是ListIterator可以实现遍历时对元素的修改,用set()方法实现。Iterator仅能遍历,不能修改。
  • Iterator只能单向遍历 [ hasNext()、next()方法)],而ListIterator可以双向遍历(向前/后遍历)[ 从后往前 hasPrevious()、previous()方法 ]
  • ListIterator接口继承于Iterator接口,然后添加了一些额外的功能,比如添加一个元素、替换一个元素、获取前面或后面元素的索引位置。
  • 获取ListIterator方式:List.listIterator()、List.listIterator(int index),index为指定游标的所在的位置。
  • 获取Iterator方式:List.iterator()

ListIterator继承Iterator接口后,自己新增的方法

  • void hasPrevious() 判断游标前面是否有元素;
  • Object previous() 返回游标前面的元素,同时游标向前移动一位。
  • int nextIndex() 返回游标后边元素的索引位置,初始为 0,遍历 N 个元素结束时为 N;
  • int previousIndex() 返回游标前面元素的位置,初始时为 -1。
  • void add(E) 在游标前面插入一个元素
  • void set(E) 更新迭代器最后一次操作的元素为 E,也就是更新最后一次调用 next() 或者 previous() 返回的元素。
  • void remove()删除迭代器最后一次操作的元素
//ListIterator实现从前向后、从后向前遍历
List<Integer> list = Arrays.asList(1,2,3,4);

ListIterator<Integer> listItr = list.listIterator();

System.out.print("从前向后:");
while(listItr.hasNext())
    System.out.print(listItr.next()+ "");

System.out.print("从后向前:");
while(listItr.hasPrevious())
    System.out.print(listItr.previous());
复制代码

fast-fail(快速失败)迭代器

Iterator就是一种fast-fail迭代器,当一个线程通过迭代器遍历List中的元素时,另一个线程修改或删除List中的元素是不允许的(),迭代器会通ConcurrentModificationException异常阻止这种情况发生,这种迭代器就叫做fast-fail迭代器。

使用forEach循环边遍历边移除元素出现异常

ArrayList<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(3);
    for (Integer ele : list) {
        list.remove(ele);
    }
    System.out.println(list.size());
    
//抛异常
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911)
	at java.util.ArrayList$Itr.next(ArrayList.java:861)
	at com.gjy.demo.collection.list.main(list.java:47)  
  
复制代码

编译后如下:

//编译后:
ArrayList<Integer> list = new ArrayList();
    list.add(1);
    list.add(2);
    list.add(3);
    Iterator var2 = list.iterator();

    while(var2.hasNext()) {
        Integer ele = (Integer)var2.next();
        list.remove(ele);
    }

    System.out.println(list.size());
复制代码

从编译后的代码中可以看出,当我们使用forEach循环一边遍历一边移除元素时,底层其实是用iterator迭代器来遍历的,而移除元素用的却是ArrayList的remove方法,这样迭代器无法感知ArrayList中元素的变化,所以,当用ArrayList的remove()方法移除掉一个元素后,下一次迭代器调用next()方法时会调用checkForComodification()方法用于检测迭代器执行过程中是否有并发修改 (判断modCount 和 expectedModCount是否相等 [集合遍历过程中会使用一个modCount变量。集合在被遍历期间如果内容发生变化,就会改变modCount的值 ] ),如果有则抛出ConcurrentModificationException异常,阻止并发修改ArrayList对象。因此,正确的边遍历边移除元素应该使用Iterator迭代器来实现。

Set接口

实现Set接口的集合主要用于存储无序(存入和取出的顺序不一定相同)元素,值不能重复。对象的相等本质是根据对象的 hashCode值 ( 在没有重写 hashCode()方法时,调用Object的 hashCode()方法是依据对象的内存地址计算进行计算的 ) 判断的,如果想要让两个不同的对象视为相等的,就必须重写 Object的 hashCode()方法和 equals()方法。

hashCode()与equals()

  • 如果两个对象相等,则hashcode一定也是相同的,Object类中的hashCode默认是根据对象的内存地址计算算出来的int类型的数值。
  • 两个对象相等,对两个equals方法返回true
  • 两个对象有相同的hashcode值,它们也不一定是相等的
  • 综上,equals方法被覆盖过,则hashCode方法也必须被覆盖
  • hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)。

Set和List的区别

  • List , Set 都是继承自Collection 接口。
  • List 特点:一个有序(元素存入集合的顺序和取出的顺序一致)容器,元素可以重复,可以插入多个null元素,元素都有索引。常用的实现类有 ArrayList、LinkedList 和 Vector。
  • Set 特点:一个无序(存入和取出顺序有可能不一致)容器,不可以存储重复元素,只允许存入一个null元素,必须保证元素唯一性。Set 接口常用实现类是 HashSet、LinkedHashSet 以及TreeSet。List 支持for循环,也就是通过下标来遍历,也可以用迭代器,但是set只能用迭代,因为它是无序,无法用下标来取得想要的值
  • Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
  • List:和数组类似,List可以动态增长(自动扩容),查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变(如ArrayList、Vector)。

Map接口

Map接口与List和Set接口不同,没有继承Collection,是一个双列集合,它是由一系列键值对组成的集合,提供了key到Value的映射。在Map接口中保证了key与value之间的一一对应关系,即一个key对应一个value,它不能存在相同的key值(唯一)且不要求key是有序的,但是value值是可以相同的。常用的Map实现类有HashMap、HashTable、ConcurrentHashMap.

需要相关java资料的可以扫一扫  备注【java】

代号OneNET02 STM32+ESP8266 WIFI系列-第2节-STM32单片机通过ESP8266连接WIFI访问OneNET OTA服务器实现SOTA远程程序升级 第2节-STM32单片机通过ESP8266连接WIFI访问OneNET OTA服务器实现SOTA远程程序升级,这一节主要是实现通过OneNET OTA服务器将需要更新的程序远程下载到STM32单片机,这一节主要是引导程序和应用程序的讲解。 阅读详情

相关推荐

分辨率太小 / Retina 模糊 / 全屏异常:一篇解决 VMware Fusion + Kali 显示问题(Xfce & GNOME 通用)

本文提供了在Mac(尤其是Retina屏)上运行Kali Linux时常见显示问题的完整解决方案。主要解决三类问题:分辨率太小、Retina屏模糊和全屏异常。核心思路是先安装open-vm-tools-desktop并重启,这是90%问题的根源。然后根据不同问题分别处理:调整DPI/Scale解决字体大小,避免双重缩放导致的模糊,以及通过窗口拉伸和重启解决全屏异常。文章还给了针对Xfce和GNOME的最佳配置建议,并强调调试完成后应创建快照以便快速恢复。最后提供了速查表,方便用户快速参考关键步骤。

致力于分享在各类技术领域的学习与实践经验,涵盖编程、虚拟化、开源工具、网络安全等。 819

2020年最新最全20年架构师给200W程序员(小白到架构师都可以学)的重大福利:架构解密,从分布式到微服务最新文档,赶紧低头学习吧!

前言 本文凝聚了作者多年架构经验,内容覆盖网络、分布式、微服务、存储、计算等。 入浅地讲解了云原生、Kubernetes和Service Mesh等热门技术,并详细剖析其原理,值得每个IT人士阅读。 不论你是有十几年研发经验及架构经验的IT老手,还是刚入门系统架构的IT新手,本文都能对你理解分布式架构和微服务架构大有助益。 希望大家能够仔仔细细的阅读,不断地品读文中的精华,把它慢慢吸收掉,转化为自己的东西,并且能够灵活运用到工作中去,不断地提升自己的技术度和宽度,希望本文能够得到大家.

程序员高级码农 711

Mac 安装neo4j(解压版)最新版本教程

本文介绍了在Mac M系列操作系统上安装Neo4j图数据库的具体步骤。内容包括:从官网下载解压版Neo4j社区版压缩包;通过终端命令将其解压到/opt目录并重命名;配置环境变量以便全局访问;以及常用命令如启动/停止服务、重置密码等。安装完成后,用户可通过浏览器访问http://localhost:7474,使用默认账号neo4j/neo4j登录并根据提示重置密码。该教程简洁明了地指导用户完成Neo4j在Mac上的安装配置过程。

猿小白的博客 820

阿里架构师整理分享60道全套Java核心技术面试题及答案

声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建 abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法接口(interface)是抽象类的变体。

ch98000的博客 355

阿里架构师整理2021年最新Java核心技术全套60道面试题

大家想不想进入一线大厂来进行自我提升、涨薪跳槽呢? 今天就给大家分享一波阿里架构师整理分享的60道必备的Java核心技术面试题及答案,希望大家能够喜欢!文末还有大量面试题分享,不止这60道!! 60道必备Java核心技术面试题及答案 1、作用域 public,private,protected,以及不写时的区别 答:区别如下: 作用域 当前类 同一 package 子孙类 其他 package public √ √ √ √ protected √ √ √ × friendly √ √

weixin_50666791的博客 1032

29个阿里架构师必会的核心实战知识点整理清单

29个阿里架构师必会的核心实战知识点整理清单 Java高级架构n2019-06-24 09:00:00 由于每篇的细节内容实在太多啦,所以只把部分知识点截图来粗略的介绍,每个小节点里面都有各种细化讲解内容! JVM JVM 是可运行 Java 代码的假想计算机 ,包括一套字节码指令集、一组寄存器、一个栈、 一个垃圾回收,堆 和 一个存储方法域。JVM 是运行在操作系统之上的,它与硬件没...

u013322876的博客 1310

架构师整理分享60道全套Java核心技术面试题及答案

大家想不想进入一线大厂来进行自我提升、涨薪跳槽呢? 今天就给大家分享一波阿里架构师整理分享的60道必备的Java核心技术面试题及答案,希望大家能够喜欢!文末还有大量面试题分享,不止这60道!! 60道必备Java核心技术面试题及答案 1、作用域 public,private,protected,以及不写时的区别 **答:**区别如下: 作用域 当前类 同一 package 子孙类 其他 package public √ √ √ √ protected √ √ √ × friendly √ √ × ×

java364100的博客 863

在家面试阿里、蚂蚁、京东、美团后 了一段时间整理一份283页Java核心面试宝典

本文整理了一些面试时面试官必问的知识点,其中包括了有基础知识、Java集合、JVM、多线程并发、spring原理、微服务、Netty 与RPC 、Kafka、日记、设计模式、Java算法、数据库、Zookeeper、分布式缓存、数据结构等等。由于知识点比较全面,内容比较多,所以我将这些Java面试中的核心知识点汇总整理成了一份文档。文档已经上传到了百度云网盘,文末提供获取方式~以下是文档涉及的主要内容:​JVM线程JVM内存区域JVM运行时内存垃圾回收与算法JAVA 四种引用类型。

qq_24428851的博客 630

京东T9架构师手把手教你怎么写年薪50万的java简历,java面试题集合

给大家送一个小福利附高清脑图,高清知识点讲解教程,以及一些面试真题及答案解析。送给需要的提升技术、准备面试跳槽、自身职业规划迷茫的朋友们。网上学习料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再入研究,那么很难做到真正的技术提升。需要这份系统化的料的朋友,可以添加V获取:vip1024b (备注Java一个人可以走的很快,但一群人才能走的更远!

2401_84439458的博客 771

滴滴架构师被裁后,熬夜整理17W字面试手册,逆风翻盘!再斩阿里offer

引言 当下,正面临着近几年来的最严重的互联网寒冬,听得最多的一句话便是:相见于江湖。缩减 HC、裁员不绝于耳,大家都是人心惶惶,年前如此,年后想必肯定又是一场更为惨烈的江湖厮杀。但笔者始终相信,寒冬之中,人才更是尤为珍贵。只要有过硬的操作和装备,在逆风局下,同样也能来一波收割翻盘。 小编也是年前经历了一番厮杀,最终拿到多家大厂的 offer。在闭关修炼的过程中,整理了一套面试秘籍供自己反复研究,后来给了多位有需要的兄台,均表示相当靠谱,理应在这寒冬之中回报于社会。于是决定点精力整理成文,让大家能比较

m0_59083374的博客 314

阿里一线架构师技术图谱!java集合框架

前言 毫不夸张地说,JVM是现代软件工程最成功的案例之一。因为它自带GC,又有无数可以微调的参数,且运行极其稳定可靠,所以,许多厂商的核心业务系统,才敢放心地用Java编写,运行在JVM之上。 近几年入学习JVM调优的人越来越多,因为互联网一线大厂的Java高级开发工程师JD中都明确要求了“JVM调优”的能力。JVM调优是跳槽大厂必备的技能,但是由于JVM知识体系过于庞大,非系统学习难以学透,并且即使掌握了全部理论,没有实操,依然无法应对面试! 今天,特将腾讯大佬疯狂加持的“千万级”JVM 笔记分享给你们

m0_56252652的博客 223

阿里架构师汇总了45个牛逼的Java技术点

作为一个程序员想要在技术耕,一定要在技术上不断的下功夫。 Java程序员一定要学好重点的技术,如下面这些: 1.架构师基础专题 2.微服务框架技术 3.开源源码分析 4.高性能框架分享 5.团队协作开发 6.B2C商城项目实战 7.搜索引擎 8.容器化技术专题 Java程序员一定要学好重点的技术,如下面这些 并发包:理解 ConcurrentHashMap原理,线程池,异步并发,锁。 集合类,线...

weixin_44195108的博客 358

java架构师_阿里架构师汇总了45个牛逼的Java技术点

作为一个程序员想要在技术耕,一定要在技术上不断的下功夫。Java程序员一定要学好重点的技术,如下面这些:Java程序员一定要学好重点的技术,如下面这些并发包:理解 ConcurrentHashMap原理,线程池,异步并发,锁。集合类,线程类。http请求。json,xml读写。常用api。前端模块javascript、css,熟悉一个前端框架。常用框架、常见的设计模式、面向对象。加薪...

weixin_39805195的博客 262

已拿5个offer,阿里架构师的万字面试手册,实在是太顶了

当下,正面临着近几年来的最严重的互联网寒冬,听得最多的一句话便是:相见于江湖。缩减 HC、裁员不绝于耳,大家都是人心惶惶,年前如此,年后想必肯定又是一场更为惨烈的江湖厮杀。但笔者始终相信,寒冬之中,人才更是尤为珍贵。只要有过硬的操作和装备,在逆风局下,同样也能来一波收割翻盘。小编也是年前经历了一番厮杀,最终拿到多家大厂的 offer。在闭关修炼的过程中,整理了一套面试秘籍供自己反复研究,后来给了多位有需要的兄台,均表示相当靠谱,理应在这寒冬之中回报于社会。

m0_71777195的博客 89

阿里P8架构师面试一个月程序员后,针对漏洞整理这份283页Java核心面试宝典

本文整理了一些面试时面试官必问的知识点,其中包括了有基础知识、Java集合、JVM、多线程并发、spring原理、微服务、Netty 与RPC 、Kafka、日记、设计模式、Java算法、数据库、Zookeeper、分布式缓存、数据结构等等。 由于知识点比较全面,内容比较多,所以我将这些Java面试中的核心知识点汇总整理成了一份文档。文档已经上传到了百度云网盘,文末提供获取方式~ 以下是文档涉及的主要内容: JVM 线程 JVM内存区域 JVM运行时内存 垃圾回收与算法 JAVA 四种引用类

文章中资料均可获取,有需要请添加yunduoa2019即可 173

45天啃透这本阿里P8架构师整理Java核心,连收7个Offer

一个明显的感受:今年的面试,无论一面还是二面,都很考验Java程序员的技术功底。而我比较幸运,有幸获得了来自阿里P8架构师分享的Java核心学习笔记,一个半月的时间学习,之后面试信心满满,陆续拿到了京东,美团,阿里等大厂的七个Offer。在此把笔记分享来,希望能帮到更多爱学习的人,也助更多的人能在面试当中顺利拿到Offer,进自己所钟意的大厂,做更好的自己。某些时候就是需要我们用心去发现突破点,然后顺势而上,抓住机遇,那么你将会走向另外一条大道,成就另外一个全新的自我。

m0_57042151的博客 123

阿里P8架构师半年整理java核心笔记,理论到实战全搞定!

你要是吃透这些知识笔记了,你至少可以去阿里面试p7岗了,面试成功与否不重要,重要的是你至少努力过对不对!以上所有料现全部整理打包存放网盘,有需要的朋友可以点击下方的名片自取!

m0_73311735的博客 377

45天啃透这本阿里P8架构师整理Java核心学习笔记,连收7个Offer

一个明显的感受:今年的面试,无论一面还是二面,都很考验Java程序员的技术功底。而我比较幸运,有幸获得了来自阿里P8架构师分享的Java核心学习笔记,一个半月的时间学习,之后面试信心满满,陆续拿到了京东,美团,阿里等大厂的七个Offer。在此把笔记分享来,希望能帮到更多爱学习的人,也助更多的人能在面试当中顺利拿到Offer,进自己所钟意的大厂,做更好的自己。某些时候就是需要我们用心去发现突破点,然后顺势而上,抓住机遇,那么你将会走向另外一条大道,成就另外一个全新的自我。

jcc4261的博客 947

Java全面学习视频书籍,阿里架构师看到都觉得好,Java集合类中绝对占有一席之地的List

针对最近很多人都在面试,我这边也整理了相当多的面试专题料,也有其他大厂的面经。希望可以帮助到大家。下面的面试题答案都整理成文档笔记。也还整理了一些面试料&最新2021收集的一些大厂的面试真题(都整理成文档,小部分截图)最新整理电子书[外链图片转存中…(img-WXytu9rj-1711139425457)]最新整理电子书[外链图片转存中…(img-vUoMpKFs-1711139425458)]本文已被。

m0_57540655的博客 939
上一篇: 大佬们不会告诉你的史上最全的Java进阶书籍推荐
下一篇: 今天大佬告诉你B站崩溃的背后,b站高可用架构到底是怎么样的
不想敲代码的小码农
博客等级 码龄5年 28粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值