Java集合——Map、Set和List总结


文章目录

  • 一、Collection
  • 二、Map、Set、List的不同
  • 三、List
    • 1、ArrayList
    • 2、LinkedList
  • 四、Map
    • 1、HashMap
    • 2、LinkedHashMap
    • 3、TreeMap
  • 五、Set


一、Collection

Collection 的常用方法

  • public boolean add(E e):把给定的对象添加到当前集合中 。
  • public void clear():清空集合中所有的元素。
  • public boolean remove(E e):把给定的对象在当前集合中删除。
  • public boolean contains(E e):判断当前集合中是否包含给定的对象。
  • public boolean isEmpty():判断当前集合是否为空。
  • public int size():返回集合中元素的个数。
  • public Object[] toArray():转换为数组。
    当需要数组转换为集合时,使用 Arrays.asList(list)

Collection 的遍历方式

  • 迭代器 iterator():获取当前集合迭代对象,然后调用方法
  1hasNext():当前位置是否有数据2next():返回当前位置,并向后移动Collection<Integer> list = new ArrayList<>();list.add(1);Iterator<Integer> iterator = list.iterator();while (iterator.hasNext()) {System.out.println(iterator.next());}

迭代器遍历注意事项
1、迭代器不可多次获取当前元素,否则会报错,因为每一次获取都会向后移动,你一次判断多次获取,则会越界抛出异常NoSuchElementException
2、迭代器不支持集合自身方法remove(),但支持迭代器对象自身的remove()方法(集合自身的移除方法会导致一些其他元素没有遍历到,到)

        Collection<Integer> list = new ArrayList<>();list.add(1);list.add(2);Iterator<Integer> iterator = list.iterator();while (iterator.hasNext()) {if (iterator.next() == 2){// list.remove(1);  此代码报错,不支持iterator.remove();}}System.out.println(list); 输出 [1]

  • 增强for
    for(数据类型 变量名 :数组或集合){} :支持集合和数组遍历
    查看反编译文件,发现增强for(数据类型 变量名 :数组或集合){} 底层是基于iterator迭代器实现的
    在这里插入图片描述

  • Lambda表达式
    Lambda表达式是简化函数式接口的内部类方法(函数式接口是指接口,仅且只有一个抽象类方法,被@FunctionalInterface修饰)
    forEach(匿名内部类的Lambda的简化表达式)
    在这里插入图片描述

Collection不支持普通for()遍历


二、Map、Set、List的不同


  • Collection是单列集合顶级父类接口
  • Map是双列集合顶级父类接口
MapSetList
HashMapHashSetArrayList
TreeMapTreeSetLinkedList
LinkedHashMapLinkedHaspSet
键值对存储数据存取无序 不重复 无索引存取有序 可重复 有索引

三、List

  • List:有序、可重复、有索引
  • 常用特有方法

add(int index , E e)
remove(int index)
set(int index , E e)
get(int index)

  • 支持的遍历方式:迭代器遍历、增强for遍历、Lambda遍历、普通for遍历

1、ArrayList

  • ArrayList是List接口实现类,存取有序、可以存储重复元素、可以使用下标操作元素,因为底层是基于数组实现的,在内存中是连续的
  • 支持重复数据的插入
  • 适合快速查询,但是不适合中间插入和删除操作
  • ArrayList实例化后,当你插入第一个数据开始,它的数组大小会变为10;当你插入的数据超过这个数组大小,ArrayList会动态的对数组实现扩容:新数组大小 = 旧数组大小 × 1.5
默认大小
private static final int DEFAULT_CAPACITY = 10;
....
扩容方法
private void grow(int minCapacity) {int oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity >> 1); 扩容至原来的1.5if (newCapacity - minCapacity < 0)  新的容量小于指定容量的最小值newCapacity = minCapacity;      扩容至指定容量的最小值(第一次就是10if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity);  将数组复制到一个新数组中,长度为 newCapacity
}

>> 相当于除2,而 << 相当于乘2

  • 常用方法
方法名作用
list.add(“a”)直接添加数据
list.add(1, “b”)根据索引位置,添加数据
list.contains(“a”)判断是否包含数据
list.get(1)根据索引位置获取数据
list.indexOf(“a”)根据数据本身返回索引位置
list.set(1, “c”)根据索引修改数据
list.remove(“a”)根据数据本身直接移除数据
list.remove(1)根据索引移除数据

2、LinkedList

  • LinkedList 实现接口 List,存取有序、支持索引操作,底层由双向链表实现,只能从一端开始遍历,查询效率低,在内存中不是连续的
  • 因为链表结构,LinkedList 更适合删除插入操作,只需要修改前结点和后一个结点引用指向即可
  • 可以插入重复数据

基于添加add(),分析一下源码

1、定义一个集合,并添加数据,看看内部实现

    public static void main(String args[]) {LinkedList<Object> list = new LinkedList<>();list.add("a");list.add(1,"b");System.out.println(list);}

2、查看根据索引添加数据的内部实现

    public void add(int index, E element) {checkPositionIndex(index);  //检查索引是否越界if (index == size) //添加位置在最后一个节点linkLast(element); elselinkBefore(element, node(index));   //任意结点前插入数据}
  • 1、如果索引越界则抛出异常 IndexOutOfBoundsException
  • 2、索引不越界时,判断是否添加位置是否在最后一个,是则添加,不是则调用 linkBefore() 方法

3、我们看 linkBefore() 中的**node(index)**方法,

    Node<E> node(int index) {// assert isElementIndex(index);if (index < (size >> 1)) {  //索引在链表左边Node<E> x = first;    //获取第一个结点for (int i = 0; i < index; i++)  //遍历,并返回index处结点x = x.next;return x;} else {  //索引在链表右边Node<E> x = last;for (int i = size - 1; i > index; i--) //遍历,并返回index处结点x = x.prev;return x;}}

看到返回值和内部代码实现,可知主要作用即返回指定元素索引处的节点。现在返回 linkBefore(element, node(index))

    void linkBefore(E e, Node<E> succ) {// assert succ != null;final Node<E> pred = succ.prev;  获取索引处前一结点final Node<E> newNode = new Node<>(pred, e, succ); 新建一个新的结点succ.prev = newNode;  索引处的前指针指向新结点if (pred == null)  如果前结点为空,则新结点变为头节点first = newNode;elsepred.next = newNode;  否则,前结点的向后指针指向新结点size++;  长度加一modCount++; 表示修改次数加一}

看了上面代码,大致应该知道添加内部代码实现流程,其他的方法就不一一列举,有兴趣去看看源码即可


四、Map

  • key不支持重复,value可以重复,如果key重复则value会被覆盖
  • 常用方法:

(1)put(K key, V value)
(2)get(Object key)
(3)size()
(4)clear()
(5)isEmpty ()
(6)remove(Object key)
(7)values():获取全部值
(8)keySet() :获取全部键
(9)containsKey():是否包含键
(10)containsValue():是否包含值
(11)putAll():把一个map添加进另一个map
(12)entrySet():获取全部集合内所有对象数据

  • 遍历方式:
1、键遍历获取值:可以根据keySet()获取全部键,使用增强for()遍历
2、键值对遍历获取值:可以根据entrySet()获取一个set集合数据,再使用增强for()遍历,getKey()可以获取键,getValue()获取值
3、 Lambda遍历:底层其实就是键值对遍历map.forEach((k, v) -> {System.out.println(v);});

1、HashMap

1、 HashMap 底层由哈希表(数组、链表、红黑树)实现
2、HashMap 初始默认大小是16,负载因子是0.75,当填充元素达到扩容要求时,HashMap会自动扩容,每次扩容是旧数组的两倍
3、HashMap实现接口Map,所有是无序的、不支持重复、无索引

HashMap细节:

1、HashMap添加数据,如果此时数组大小正好插满了12(16×0.75)个时,如果当前发生冲突则数组扩容,如果没有发生冲突则不扩容
2、当数组大小大于或者等于64时,才会把链表大于8的转换为红黑树


2、LinkedHashMap

LinkedHashMap:有序、不重复、无索引,底层由哈希表(数组、链表、红黑树)实现,并且维护了一个双向链表机制


3、TreeMap

按照key的大小升序排序,不重复、无索引,底层基于红黑树实现


五、Set

Set:无序、不可重复、无索引

  • 常用方法:几乎都是Collection的方法

  • HashSet:存取无序、不可重复、无索引操作,底层由哈希表(数组、链表、红黑树)实现
  • 如果自定义对象,需要重写hashCod()和equal()方法,实现不可重复

  • LinkedHashSet:存取有序、不可重复、无索引操作,底层由哈希表(数组、链表、红黑树)实现,并且维护了一个双向链表机制

  • TreeSet:内部升序排序、不可重复、无索引操作,基于红黑树实现
  1. 数值包装类型和字符串这两种对象可以升序排序

  2. 其他对象不可以排序,但是可以自定义排序规则

  3. 排序规则

  • 实现接口 Comparable,自定义compareTo()方法
  • 调用有参构造器,设置Comparator对象,实现compare()方法
  • 如果两则都实现了,则选择就近原则,选择Comparator对象比较

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/795896.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用C/C++加Easyx实现俄罗斯方块游戏(爆肝4万字,完全免费)

前言 相信大家一定玩过俄罗斯方块这款小游戏&#xff0c;简单容易上手是老少皆宜的小游戏&#xff0c;今天大家就跟着我来实现这个小游戏吧&#xff01;让自己学的C语言有用武之地。 为了让俄罗斯方块的开发更为简单些&#xff0c;图像更为丰富&#xff0c;在这里就利用了Easyx…

LOOP循环

Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 循环语句和条件语句一样都可以控制程序的执行顺序&#xff0c;而循环语句是指一段程序可以重复执行&#xff0c;PL/SQL 语言主要支持 3 种类型的循环&#xff1a;LOOP 循环、…

最优乘车

题目描述 H 城是一个旅游胜地&#xff0c;每年都有成千上万的人前来观光。为方便游客&#xff0c;巴士公司在各个旅游景点及宾馆&#xff0c;饭店等地都设置了巴士站并开通了一些单程巴上线路。每条单程巴士线路从某个巴士站出发&#xff0c;依次途经若干个巴士站&#xff0c;…

42. 接雨水(Java)

目录 题目描述:输入&#xff1a;输出&#xff1a;代码实现&#xff1a; 题目描述: 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 输入&#xff1a; height [0,1,0,2,1,0,1,3,2,1,2,1]输出&#xff1…

JavaEE 初阶篇-生产者与消费者模型(线程通信)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 生产者与消费者模型概述 2.0 在生产者与消费者模型中涉及的关键概念 2.1 缓冲区 2.2 生产者 2.3 消费者 2.4 同步机制 2.5 线程间通信 3.0 实现生产者与消费者模…

【ArcGIS微课1000例】0107:ArcGIS加载在线历史影像服务WMTS

文章目录 一、WMTS历史影像介绍二、ArcGIS加载WMTS服务三、Globalmapper加载WMTS服务一、WMTS历史影像介绍 通过访问历史影响WMTS服务,可以将全球范围内历史影像加载进来,如下所示: WMTS服务: https://wayback.maptiles.arcgis.com/arcgis/rest/services/World_Imagery/WM…

二叉树中所有距离为k的节点

题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 从目标节点的左孩子&#xff0c;右孩子&#xff0c;父亲节点出发去找&#xff0c;左孩子 右孩子 做法简单 &#xff0c; 主要是父亲节点 &#xff0c;因此我们需要知道每个节点的父亲节点&am…

【学习笔记】Elsevier的Latex模板文件(附网址)

注&#xff1a;这是一篇没有技术含量的水文&#xff0c;主要是看有人下载下来&#xff0c;居然当成资源需要积分才能下载。我觉得不行&#xff0c;故提供原始下载地址供查阅使用。 链接: 上述图片所示网址&#xff1a;链接直达

Redis(性能管理、主从复制、哨兵模式)概述及部署

目录 一、性能管理 1、查看Redis内存使用 2、内存碎片率 3、跟踪内存碎片率 4、内存使用率 5、内回收key 二、Redis集群有三种模式 三、Redis主从复制 1、主从复制的概念 2、主从复制的作用 3、主从复制的流程 4、搭建Redis主从复制 1.环境准备 2.安装Redis&#…

并查集学习(836. 合并集合 + 837. 连通块中点的数量)

//得先加集合个数再合并&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 核心代码&#xff1a; int find(int x){//返回父节点if(x ! p[x]) {p[x] find(p[x]);//路径压缩 } //孩子不等于爸爸&#xff0c;就…

先进电气技术 —— “控制”与“估计”

一、背景 在当今科技日新月异的时代&#xff0c;先进电气技术正在全球范围内以前所未有的速度发展&#xff0c;尤其是在“控制”与“估计”两大核心技术领域的突破&#xff0c;对电力系统、工业自动化、智能电网、电动汽车等诸多领域产生了深远影响。本文将探讨这两项核心技术…

基于微信小程序的生活日用品交易平台 的设计与实现

一、项目背景介绍&#xff1a; 随着计算机互联网技术的不断进步&#xff0c;也推动了计算机技术的进步&#xff0c;推动了社会的智能化&#xff0c;使科技与人们的日常需求紧密的联系到了一起&#xff0c;诞生人们追求更加便利的生活模式。计算机技术是社会前进的主力军&#x…

面试题——JVM老年代空间担保机制(我的想法)

这里借用一下人家的图&#xff0c;来说一下我的想法&#xff0c;嘻嘻。。。。 原文链接&#xff1a;一道面试题&#xff1a;JVM老年代空间担保机制-CSDN博客? 嗯&#xff0c;我觉得老年代担保机制的主要作用就是避免频繁触发FULL GC&#xff0c;这其实也是因为年轻代Minor GC…

前端:注册页面(后端php实现)

效果 代码 Regist.php <!-- 内部员工注册 --> <?php require_once get_db_conn.php; $conn db_connect();?> <?php //设置变量的默认值 if (!isset($_POST[UserID])) {$_POST[UserID] ; } if (!isset($_POST[Password])) {$_POST[Password] ; } if (!i…

实战:Solaris系统下Oracle 12.2 在线扩容ASM磁盘组操作记录

这篇文章主要是为了记录一下操作&#xff0c;这个假期又要给这套RAC扩容磁盘。 我这套Solaris的小机我还不总操作这玩意&#xff0c;和LINUX有点小差别&#xff0c;整理记录一下&#xff0c;要不每次都是现翻。 存储端划LUN映射到主机 登录到3PAR存储控制台&#xff0c;创建…

数据生成 | Matlab实现基于DE差分进化算法的数据生成

数据生成 | Matlab实现基于DE差分进化算法的数据生成 目录 数据生成 | Matlab实现基于DE差分进化算法的数据生成生成效果基本描述模型描述程序设计参考资料 生成效果 基本描述 1.Matlab实现基于DE差分进化算法的数据生成&#xff0c;运行环境Matlab2021b及以上&#xff1b; 2.计…

SSL/TLS:网络安全中的基石

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Vue3_2024_8天【vue2中的标签ref和vue3中的标签ref的区别】

第一&#xff1a;Vue 2 中的 ref 在 Vue 2 中&#xff0c;ref 主要用于在模板中注册引用信息。它可以用在html标签上或&#xff08;子&#xff09;组件上。一旦标签元素或组件被渲染&#xff0c;你就可以通过 this.$refs 来访问它。 <template> <div ref"myDiv&…

HUD抬头显示器阳光倒灌实验一般步骤

概述 汽车HUD&#xff08;Head-Up Display&#xff0c;即抬头显示器&#xff09;阳光倒灌实验是一种用于评估汽车抬头显示器在阳光直射条件下显示效果的测试。该实验的目的是确保HUD系统在强烈的阳光下依然能够清晰地显示信息&#xff0c;不影响驾驶员的视线和驾驶安全。 一般…

FJSP:小龙虾优化算法(Crayfsh optimization algorithm,COA)求解柔性作业车间调度问题(FJSP),提供MATLAB代码

一、柔性作业车间调度问题 柔性作业车间调度问题&#xff08;Flexible Job Shop Scheduling Problem&#xff0c;FJSP&#xff09;&#xff0c;是一种经典的组合优化问题。在FJSP问题中&#xff0c;有多个作业需要在多个机器上进行加工&#xff0c;每个作业由一系列工序组成&a…