Java集合

一、List

1、ArrayList

ArrayList 底层就是⼀个 Object[] 数组

ArrayList 底层数组默认初始化容量为 10

1、jdk1.8 中 ArrayList 底层先创建⼀个⻓度为 0 的数组

2、当第⼀次添加元素(调⽤ add() ⽅法)时,会初始化为⼀个⻓度为 10 的数组

当 ArrayList 中的容量使⽤完之后,则需要对容量进⾏扩容:

1、ArrayList 容量使⽤完后,会“⾃动”创建容量更⼤的数组,并将原数组中所有元素拷⻉过去,这会导致效率降低

2、优化:可以使⽤构造⽅法 ArrayList (int capacity) 或 ensureCapacity(int capacity) 提供⼀个初始化容量,避免刚开始就⼀直扩容,造成效率较低

ArrayList 构造⽅法:

1. ArrayList():创建⼀个初始化容量为 10 的空列表

2. ArrayList(int initialCapacity):创建⼀个指定初始化容量为 initialCapacity 的空列表

3. ArrayList(Collection<? extends E> c):创建⼀个包含指定集合中所有元素的列表

ArrayList 特点:

优点:

        1. 向 ArrayList 末尾添加元素(add() ⽅法)时,效率较⾼

        2. 查询效率⾼

缺点:

        1. 扩容会造成效率较低(可以通过指定初始化容ᰁ,在⼀定程度上对其进⾏改善)

        2. 另外数组⽆法存储⼤数据量(因为很难找到⼀块很⼤的连续的内存空间)

        3. 向 ArrayList 中间添加元素(add(int index)),需要移动元素,效率较低

                1. 但是,向 ArrayList 中国位置增/删元素的情况较少时不影响;

                2. 如果增/删操作较多,可考虑改⽤链表 

2、Linklist

LinkedList 特点

数据结构: LinkedList 底层是⼀个双向链表

优点: 增/删效率⾼

缺点: 查询效率较低

LinkedList 也有下标,但是内存不⼀定是连续的(类似C++᯿载[]符号,将循位置访问模拟为循秩访问)

LinkedList 可以调⽤ get(int index) ⽅法,返回链表中第 index 个元素

但是,每次查找都要从头结点开始遍历

LinkedList 部分源码解读

add()⽅法

 ListIterator 接⼝

1、LinkedList.add ⽅法只能将数据添加到链表的末尾

2、如果要将对象添加到链表的中间位置

则需要使⽤ ListIterator 接⼝的 add ⽅法

        1. ListIterator 是 Iterator 的⼀个⼦接⼝ 

3、Iterator 中 remove ⽅法

        1. 调⽤ next 之后,remove ⽅法删除的是迭代器左侧的元素(类似键盘的 backspace)

        2. 调⽤ previous 之后,remove 删除的是迭代器右侧的元素

4、ListIterator 中 add ⽅法

        1. 调⽤ next 之后,在迭代器左侧添加⼀个元素

        2. 调⽤ previous 之后,add 是在迭代器右侧添加元素 

3、Vector

Vector 底层是数组

初始化容量为 10

扩容: 原容量使⽤完后,会进⾏扩容。新容量扩⼤为原始容量的 2 倍

Vector 是线程安全的(⾥⾯⽅法都带有 synchronized 关键字),效率较低,现在使⽤较少

如何将 ArrayList 变成线程安全的?

调⽤ Collections ⼯具类中的 static List synchronizedList(List list) ⽅法 

二、Set

泛型:

1、jdk 1.5 引⼊,之前都是使⽤ Object[]

2、使⽤ Object[] 的缺点(2个)

        1. 获取⼀个值时必须进⾏强制类型转换

        2. 调⽤⼀个⽅法前必须使⽤ instanceof 判断对象类型

泛型的好处:

1、减少了强制类型转换的次数 获取数据值更⽅便

2、类型安全

调⽤⽅法时更安全

3、泛型只在编译时期起作⽤

运⾏阶段 JVM 看不⻅泛型类型(JVM 只能看⻅对应的原始类型,因为进⾏了类型擦除)

4、带泛型的类型

在使⽤时没有指定泛型类型时,默认使⽤ Object 类型 

5、lambda 表达式 

1、HashSet 

特点:HashSet ⽆序(没有下标),不可重复

2、TreeSet

TreeSet ⽆序(没下标),不可重复,但是可以排序

HashSet 为 HashMap 的 key 部分;TreeSet 为 TreeMap 的 key 部分。

所以,这⾥没有重点讲。重点掌握 HashMap 和 TreeMap。

三、Map

1. Map 和 Collection 没有继承关系

2. Map 以 (key ,value) 的形式存储数据:键值对

         key 和 value 存储的都是对象的内存地址(引⽤)

Map 接⼝常⻅⽅法: 

注意:

Map.Entry<K, V> 是 Map 的⼀个接⼝。接⼝中的内部接⼝默认是 public static 的。 

Map的遍历⽅式

第⼀类⽅法

先获取map 的 keySet,然后取出 key 对应的 value

特点:

效率相对较低。(因为还要根据 key 从哈希表中查找对应的 value)

⽅法1:通过 foreach 遍历 map.keySet(),取出对应的 value 

⽅法2:通过迭代器迭代 map.keySet(),来取出对应的 value 

第⼆类⽅法

调⽤ map.entrySet()⽅法,获取 entrySet,然后直接从 entrySet 中获取 key 和 value。

特点:

        1. 效率较⾼(直接从 node 中获取key,value)

        2. 适⽤于⼤数据量 map 遍历

⽅法3:调⽤ map.entrySet(),然后使⽤ foreach 遍历 entrySet 

⽅法4:调⽤ map.entrySet(),然后使⽤迭代器遍历 entrySet  

1、HashMap 

HashMap 底层是⼀个数组

数组中每个元素是⼀个单向链表(即,采⽤拉链法解决哈希冲突)

        单链表的节点每个节点是 Node<K, V> 类型(见下源码)

同⼀个单链表中所有 Node hash值不⼀定⼀样,但是他们对应的数组下标⼀定⼀样

        数组下标利⽤哈希函数/哈希算法根据 hash值计算得到的

HashMap 是数组和单链表的结合体

        数组查询效率⾼,但是增删元素效率较低

        单链表在随机增删元素⽅⾯效率较⾼,但是查询效率较低

        HashMap 将⼆者结合起来,充分它们各⾃的优点

HashMap 特点

        1. 无序、不可重复

        2. ⽆序:因为不⼀定挂在那个单链表上了

为什么不可重复?

        通过重写 equals ⽅法保证的

HashMap 默认初始化容量: 16

        必须是 2 的次幂,这也是 jdk 官⽅推荐的

        这是因为达到散列均匀,为了提⾼ HashMap 集合的存取效率,所必须的

HashMap 默认加载因⼦:0.75

        数组容量达到 3/4 时,开始扩容

JDK 8 之后,对 HashMap 底层数据结构(单链表)进⾏了改进

        如果单链表元素超过8个,则将单链表转变为红⿊树;

        如果红⿊树节点数量小于6时,会将红⿊树重新变为单链表。

这种方式也是为了提高检索效率,二叉树的检索会再次缩小扫描范围。提高效率。

 

put() 方法原理

先将 key, value 封装到 Node 对象中

底层会调⽤ key hashCode() ⽅法得出 hash

通过哈希函数/哈希算法,将 hash 值转换为数组的下标

        如果下标位置上没有任何元素,就把 Node 添加到这个位置上;

        如果下标位置上有但链表,此时会将当前 Node 中的 key 与链表上每⼀个节点中的 key 进行 equals 比较

                如果所有的 equals 方法返回都是 false,那么这个新节点 Node 将被添加到链表的末尾;

                如果其中有⼀个 equals 返回了 true,那么链表中对应的这个节点的 value 将会被新节点 Node 的 value 覆盖。(保证了不可重复)

注:

1. HashMap 中允许 key value null,但是只能有⼀个(不可重复)!

2. HashTable key value 都不允许为 null

get() 方法原理

先调⽤ key hashCode() 方法得出 hash

通过哈希函数/哈希算法,将 hash 值转换为数组的下标

通过数组下标快速定位到数组中的某个位置:

        如果这个位置上什么也没有(没有链表),则返回 null

        如果这个位置上有单链表,此时会将当前 Node 中的 key 与链表上每⼀个节点中的 key 进⾏ equals 比较

                如果所有的 equals 方法返回都是 false,那么 get 方法返回 null

                如果其中有⼀个 equals 返回了 true,那么这个节点的 value 便是我们要找的 value,此时 get 方法最终返回这个要找的 value

注:

1. 放在 HashMap key 的元素(或者放在 HashSet 中的元素)需要同时重写hashCode() equals() 方法!!!

同时重写 hashCode() equals() ⽅法

重写 hashCode() 方法时要达到散列分布均匀!!!

        如果 hashCode() 方法返回⼀个固定的值,那么 HashMap 底层则变成了⼀个单链表;

        如果 hashCode() 方法所有返回的值都不同,此时 HashMap 底层则变成了⼀个数组。

这两种情况称之为,散列分布不均匀

equals 和 hashCode方法⼀定要同时重写(直接用 eclipse 生成就行)

 

2、HashTable & Properties

HashTable

Properties

Properties key values 都是 String

常⽤⽅法

String getProperty(String key)

Object setProperty(String key, String value)

3、TreeMap

TreeMap 概述

        TreeSet/TreeMap 是自平衡⼆叉树

        TreeSet/TreeMap 迭代器采用的是中序遍历方式

TreeMap 特点

⽆序,不可重复,但是可排序

排序规则

TreeSet/TreeMapkey 可以⾃动对 String 类型或8⼤基本类型的包装类型进行排序

TreeSet ⽆法直接对自定义类型进行排序

直接将⾃定义类型添加到 TreeSet/TreeMapkey 会报错 java.lang.ClassCastException

原因: 是因为⾃定义没有实现 java.lang.Comparable 接口(此时,使用的是 TreeSet 的⽆参构造器)

TreeSet/TreeMap key部分元素,必须要指定排序规则。主要有两种解决⽅案:

方法⼀: 放在集合中的自定义类型实现 java.lang.Comparable 接口,并重写 compareTo ⽅法

方法⼆: 选择 TreeSet/TreeMap 带⽐较器参数的构造器 ,并从写⽐较器中的 compare ⽅法

此时,在传递比较器参数给 TreeSet/TreeMap 构造器时,有 3 种方法:

        定义⼀个 Comparator 接⼝的实现类

        使⽤匿名内部类

        lambda 表达式(Comparator 是函数式接口)

                利⽤ -> 的 lambda表达式 重写 compare 方法

                利⽤ Comparator.comparing ⽅法

两种解决方案如何选择呢?

        当比较规则不会发⽣改变的时候,或者说比较规则只有⼀个的时候,建议实现 Comparable 接口

        当比较规有多个,并且需要在多个比较规则之间频繁切换时,建议使用 Comparator 接口

方法⼀代码:

方法二代码:

 

 

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

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

相关文章

[学习笔记]微信小程序全套开发流程(ing)

https://www.bilibili.com/video/BV1mV4y1o7fu 1.整体概述 2.环境搭建 略 4.纯净版项目 5.快速入门 5.1组件(类似HTML标签) wxml中的标签html中的标签textspanviewdivimageimgiconnavigatora view组件 <view><view class"c0">学生&#xff1a;<…

Flask 是什么?Flask框架详解及实践指南

Flask 是一个轻量级的 Python Web 框架&#xff0c;它被广泛用于构建 Web 应用程序和 API。Flask 简单易用&#xff0c;具有灵活性和可扩展性&#xff0c;是许多开发者喜欢用其构建项目的原因。本文将介绍 Flask 是什么以及如何使用它来构建 Web 应用程序&#xff0c;同时提供一…

链式二叉树统计结点个数的方法和bug

方法一&#xff1a; 分治&#xff1a;分而治之 int BTreeSize1(BTNode* root) {if (root NULL) return 0;else return BTreeSize(root->left)BTreeSize(root->right)1; } 方法二&#xff1a; 遍历计数&#xff1a;设置一个计数器&#xff0c;对二叉树正常访问&#…

OpenCV之信用卡识别实战

文章目录 代码视频讲解模板匹配文件主程序(ocr_template_match.py)myutils.py 代码 链接: https://pan.baidu.com/s/1KjdiqkyYGfHk97wwgF-j3g?pwdhhkf 提取码: hhkf 视频讲解 链接: https://pan.baidu.com/s/1PZ6w5NcSOuKusBTNa3Ng2g?pwd79wr 提取码: 79wr 模板匹配文件 …

Linux下.py文件只读问题以及解决过程

一、问题描述 如图&#xff0c;在Ubuntu Linux系统中使用pycharm管理项目文件时&#xff0c;无法编辑&#xff0c;提示文件为只读&#xff1a; 点击"OK"后仍旧无法清除只读模式&#xff0c;并报错&#xff1a; 二、问题解决 将问题定性为文件权限相关问题&#…

将http协议升级为https协议——域名平台部分的设置

为远程群晖NAS的自定义域名免费申请SSL证书 文章目录 为远程群晖NAS的自定义域名免费申请SSL证书前言1. 向域名平台申请SSL证书1.1 购买“免费证书” 2. 进一步进行创建证书设置2.1 对证书的关联域名进行补充 3. 云解析DNS3.1 进行验证信息 前言 我们可以成功地将自己购买的域…

RN 使用react-navigation写可以滚动的横向导航条(expo项目)

装包&#xff1a; yarn add react-navigation/material-top-tabs react-native-tab-view npx expo install react-native-pager-view import React from react import { View, Text, ScrollView, SafeAreaView } from react-native import { Icon } from ../../../../../compo…

Linux文件属性与权限管理(可读、可写、可执行)

Linux把所有文件和设备都当作文件来管理&#xff0c;这些文件都在根目录下&#xff0c;同时Linux中的文件名区分大小写。 一、文件属性 使用ls -l命令查看文件详情&#xff1a; 1、每行代表一个文件&#xff0c;每行的第一个字符代表文件类型&#xff0c;linux文件类型包括&am…

【redis基础】

目录 一、概述 1.NoSQL 1.1 简述 1.2 类型 1.3 应用场景 1.3.1 缓存 1.3.2 分布式锁 1.3.3 计数器 1.3.4 会话管理 1.3.5 消息队列 2.Redis 2.1 简述 2.2 特性 2.3 监听端口号 2.4 数据类型 二、安装 1.编译安装 2.RPM安装 三、目录结构 1.查看 2.主配置文…

使用toad库进行机器学习评分卡全流程

1 加载数据 导入模块 import pandas as pd from sklearn.metrics import roc_auc_score,roc_curve,auc from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression import numpy as np import math import xgboost as xgb …

心理咨询预约管理系统javaweb医院挂号jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 心理咨询预约管理系统javaweb MVC模式&#xff0c;普…

活动发布会邀请媒体6步走

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 邀请媒体参加活动发布会对信息的传播&#xff0c;企业品牌建设有诸多的好处&#xff0c;今天就与大家分享下邀请媒体参加活动报道的6个步骤&#xff1a; 1. 策划与准备&#xff1a; -明…

构建Docker容器监控系统(Cadvisor +InfluxDB+Grafana)

目录 案例概述 Cadvisor InfluxDBGrafana 1.1、 Cadvisor 1.2、InfluxDB 1.3、Grafana 1.4、监控组件架构 1.5、开始部署 安装docker-ce 阿里云镜像加速器 创建自定义网络 创建influxdb容器 案例概述 Docker作为目前十分出色的容器管理技术&#xff0c;得到大量企业…

基于Java+SpringBoot+Vue的企业客户信息反馈平台设计与实现(源码+LW+部署文档等)

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

STM32 4G学习(二)

特性参数 ATK-IDM750C是正点原子开发的一款高性能4G Cat1 DTU产品&#xff0c;支持移动4G、联通4G和电信4G手机卡。 它以高速率、低延迟和无线数传作为核心功能&#xff0c;可快速解决应用场景下的无线数传方案。 它支持TCP/UDP/HTTP/MQTT/DNS/RNDIS/NTP协议&#xff0c;支持…

Clion开发Stm32之存储模块(W25Q64)驱动编写

前言 涵盖之前文章: Clion开发STM32之HAL库SPI封装(基础库) W25Q64驱动 头文件 #ifndef F1XX_TEMPLATE_MODULE_W25Q64_H #define F1XX_TEMPLATE_MODULE_W25Q64_H#include "sys_core.h" /* Private typedef ---------------------------------------------------…

STM32入门——定时器

内容为江科大STM32标准库学习记录 TIM简介 TIM&#xff08;Timer&#xff09;定时器定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时触发中断16位计数器、预分频器、自动重装寄存器的时基单元&#xff0c;在72MHz计数时钟下可以实现最大59.65s的定时&…

广州VR制作 | 利用VR元宇宙平台开展林地管理培训的优势

在林业领域&#xff0c;实地调查是获取准确数据和深入了解森林生态的重要手段。然而&#xff0c;传统的实地调查方法存在诸多问题&#xff0c;如时间成本高、人力物力投入大、安全风险高等。为了解决这些教学痛点&#xff0c;我们引入了虚拟现实(VR)技术&#xff0c;通过虚拟林…

【JVM】 垃圾回收篇——自问自答(1)

Q什么是垃圾&#xff1a; 运行程序中&#xff0c;没用任何指针指向的对象。 Q为什么需要垃圾回收&#xff1f; 内存只分配&#xff0c;不整理回收&#xff0c;迟早会被消耗完。 内存碎片的整理&#xff0c;为新对象腾出空间 没有GC程序无法正常进行。 Q 哪些区域有GC&#…

react学习

1.react安装 2.react的使用 3.方法说明 4.初始化react脚手架 5.在脚手架中使用react 6.JSX 7.JSX需要注意的点 8.在JSX中使用JS 需要注意的点 9.条件渲染 10.列表渲染 11.样式处理 12.react组件 两种创建方式: 函数创建: 类组件: 13.事件 事件绑定 事件对象 14.有状态组件和…