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.rhkb.cn/news/299472.html

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

相关文章

【Python】免费的图片/图标网站

专栏文章索引&#xff1a;Python 有问题可私聊&#xff1a;QQ&#xff1a;3375119339 这里是我收集的几个免费的图片/图标网站&#xff1a; iconfont-阿里巴巴矢量图标库icon&#xff08;.ico&#xff09;INCONFINDER&#xff08;.ico&#xff09;

Web3:数字化社会的下一步

随着技术的不断进步和互联网的发展&#xff0c;我们正逐渐迈入一个全新的数字化社会阶段。在这个新的时代&#xff0c;Web3作为数字化社会的重要组成部分&#xff0c;将发挥着举足轻重的作用。本文将探讨Web3在数字化社会中的意义、特点以及对未来发展的影响。 1. 重新定义数字…

计算机网络 实验指导 实验9

实验9 三层交换机综合实验 1.实验拓扑图 名称相连的接口IP地址网关PC1F0/3172.1.1.2/28172.1.1.1/28PC2F0/4172.1.1.18/28172.1.1.17/28PC3F0/5172.1.1.34/28172.1.1.33/28PC4F0/3172.1.1.3/28172.1.1.1/28PC5F0/4172.1.1.19/28172.1.1.17/28PC6F0/5172.1.1.35/28172.1.1.33/2…

【数据结构】考研真题攻克与重点知识点剖析 - 第 4 篇:串

前言 本文基础知识部分来自于b站&#xff1a;分享笔记的好人儿的思维导图与王道考研课程&#xff0c;感谢大佬的开源精神&#xff0c;习题来自老师划的重点以及考研真题。此前我尝试了完全使用Python或是结合大语言模型对考研真题进行数据清洗与可视化分析&#xff0c;本人技术…

完全二叉树的层序遍历c++

借鉴的文章 利用完全二叉树的遍历确定完全二叉树 题目 输入样例&#xff1a; 8 91 71 2 34 10 15 55 18输出样例&#xff1a; 18 34 55 71 2 10 15 91 思路 完全二叉树具有这样的性质&#xff1a; 该图来源的文章&#xff1a;天梯赛 L2-3 完全二叉树的层序遍历 - a-shy-cod…

安全的通信协议HTTPS被攻击改采用什么防护方案

随着互联网的发展&#xff0c;保护用户在网上交换的敏感信息的安全性变得至关重要。HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;作为一种安全的通信协议&#xff0c;通过加密数据传输&#xff0c;保护用户的隐私和数据安全。然而&#xff0c;尽管HTTPS提…

SpringMVC框架简介

前言 现在由于功能以及业务的复杂性&#xff0c;大部分系统从技术上就拆分开为前后端分离&#xff0c;单体应用我都很少没接触了&#xff0c;导致现在对springMVC那套都忘记了很多东西&#xff0c;因此这篇文章在来回忆一下SpringMVC这个框架&#xff1b;很多时候因为业务的需…

【Android】图解View的工作流程原理

文章目录 入口DecorView如何加载到Window中MeasureSpec MeasureView的测量ViewGroup的测量 LayoutView的layout() Draw1、绘制背景3、绘制View内容4、绘制子View6、绘制装饰 入口 DecorView如何加载到Window中 MeasureSpec 该类是View的内部类&#xff0c;封装View的规格尺寸…

876.链表的中间结点 143.重排链表

给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[3,4,5] 解释&#xff1a;链表只有一个中间结点&#xff0c;值为 3 。示…

文献学习-28-Endora: 用于内镜仿真的视频生成模型

Endora : Video Generation Models as Endoscopy Simulators Authors: Chenxin Li, Hengyu Liu, Yifan Liu, Brandon Y. Feng, Wuyang Li, Xinyu Liu, Zhen Chen, Jing Shao, Yixuan Yuan Keywords: Medical Generative AI Video Generation Endoscopy Abstract 生成模型有…

【C++】红黑树讲解及实现

前言&#xff1a; AVL树与红黑树相似&#xff0c;都是一种平衡二叉搜索树&#xff0c;但是AVL树的平衡要求太严格&#xff0c;如果要对AVL树做一些结构修改的操作性能会非常低下&#xff0c;比如&#xff1a;插入时要维护其绝对平衡&#xff0c;旋转的次数比较多&#xff0c;更…

33. UE5 RPG使用增强输入激活GameplayAbility(三)

在前面的文章&#xff0c;我们实现了使用GameplayTag和InputAction的对应绑定的数据&#xff0c;并且添加到了增强输入映射的上下文中&#xff0c;实现了通过按键打印对应的GameplayTag&#xff0c;这只是我们基础需要制作的。目的主要是为了实现在GameplayAblity上面设置对应的…

深入浅出 -- 系统架构之分布式多形态的存储型集群

一、多形态的存储型集群 在上阶段&#xff0c;我们简单聊了下集群的基本知识&#xff0c;以及快速过了一下逻辑处理型集群的内容&#xff0c;下面重点来看看存储型集群&#xff0c;毕竟这块才是重头戏&#xff0c;集群的形态在其中有着多种多样的变化。 逻辑处理型的应用&…

【.Net】DotNetty

文章目录 概述NIO和BIO、AIODotNetty适用场景DotNetty的整体架构和模块DotNetty的使用示例来源 概述 本系列文章主要讲述由微软Azure团队研发的.net的版本的netty&#xff0c;Dotnetty。所有的开发都将基于.net core 3.1版本进行开发。 Dotnetty是什么&#xff0c;原本Netty是…

蓝桥真题--路径之谜DFS解法

路径之谜 思路 前置知识&#xff1a;深度搜索模板搜索所有可以找的路径&#xff0c;将走过的靶子减去一走到最后一个格子的时候&#xff0c;直接去判断所有的靶子只有除最后一个位置的靶子&#xff0c;其余靶子都归零的时候&#xff0c;判断一个最后一个位置横坐标和纵坐标的靶…

PTA C 1050 螺旋矩阵(思路与优化)

本题要求将给定的 N 个正整数按非递增的顺序&#xff0c;填入“螺旋矩阵”。所谓“螺旋矩阵”&#xff0c;是指从左上角第 1 个格子开始&#xff0c;按顺时针螺旋方向填充。要求矩阵的规模为 m 行 n 列&#xff0c;满足条件&#xff1a;mn 等于 N&#xff1b;m≥n&#xff1b;且…

Bayes-RF,基于贝叶斯Bayes优化算法优化随机森林RF分类预测(二分类及多分类皆可)-附代码

Bayesian Optimization&#xff08;贝叶斯优化&#xff09;是一种用于超参数调优的技术&#xff0c;对于类似随机森林&#xff08;Random Forest&#xff0c;简称RF&#xff09;的机器学习算法非常重要。随机森林是一种集成学习方法&#xff0c;它在训练过程中构建多个决策树&a…

漂亮国的无人餐厅的机器人骚操作

导语 大家好&#xff0c;我是智能仓储物流技术研习社的社长&#xff0c;你的老朋友&#xff0c;老K。行业群 新书《智能物流系统构成与技术实践》 知名企业 读者福利&#xff1a; &#x1f449;抄底-仓储机器人-即买即用-免调试 智能制造-话题精读 1、西门子、ABB、汇川&#x…

详解 Redis 在 Centos 系统上的安装

文章目录 详解 Redis 在 Centos 系统上的安装1. 使用 yum 安装 Redis 52. 创建符号链接3. 修改配置文件4. 启动和停止 Redis 详解 Redis 在 Centos 系统上的安装 1. 使用 yum 安装 Redis 5 如果是Centos8&#xff0c;yum 仓库中默认的 redis 版本就是5&#xff0c;直接 yum i…

Premiere Pro 2024:赋予创意翅膀,让你的视频飞翔 mac/win版

Premiere Pro 2024&#xff0c;作为Adobe旗下的旗舰视频编辑软件&#xff0c;自推出以来&#xff0c;一直在视频制作领域占据着重要的地位。随着技术的不断进步和创新&#xff0c;Premiere Pro 2024为用户带来了前所未有的编辑体验&#xff0c;重新定义了视频制作的标准。 Pre…