java集合总结

集合

一种装数据的容器,类似于数组,但大小可变

主要用途:

1,提供不同数据结构:java提供了不同类型的集合,每一种集合类的数据结构不同导致其特点和使用场景也不同,开发人员可以通过具体的需求选择合适的数据结构来提高程序的效率和性能.

2,方便的数据操作:java集合提供了丰富的方法和功能,可以方便地进行数据的增删改查,排序,遍历等操作.开发人员可以利用这些方法和功能来简化代码,提高开发效率

1,collection(单列集合)

每个元素(数据)只包含一个值

请添加图片描述

Collection集合的特点:

List系列集合:元素有序,可重复,有索引

eg:ArrayList,LinkedList

Set系列集合:元素无序,不重复,无索引

eg:HashSet:无序,不重复,无索引

LinkedHashSet:有序,不重复,无索引

TreeSet:按照大小默认升序排列,不重复,无索引

Collection集合方法

所有单列集合均直接或间接继承于Collection

public boolean add(E e) //添加元素到集合中public void clear() //清空集合中所有元素public boolean remove(E e)//在集合中删除给定对象public boolean contains(Object obj) //判断集合中是否包含给定的对象public boolean isEmpty() //判断集合是否为空public int size() //返回集合是否为空public Object[] toArray() //把集合中的元素存储到数组中

Collection遍历及应用

1,使用Iterator迭代器:

优点:可以在遍历过程中修改集合的内容,比如删除元素

缺点:代码比较繁琐,需要手动调用hasNext()或者next()方法

2,使用foreach循环:

底层就是使用迭代器

优点:代码简洁,不需要手动调用迭代器的方法

缺点:不能在遍历过程中修改集合的内容

3,普通for循环遍历(针对于有索引的集合List):

优点:可以通过索引更改访问位置,更加灵活

缺点:代码较为繁琐,需要手动管理索引

4,使用Stream流和lambda

优点:代码简洁,提供丰富的操作方法,比如过滤,映射,规约等

缺点:不能在遍历过程中修改集合内容,一旦创建了Stream流就不能再次遍历

Iterator iterator():

返回集合中的迭代器对象,默认指向当前集合的第一个元素

迭代器中的常用方法:
boolean hasNext() //询问当前位置是否存在元素,存在返回true,不存在则返回false
E next() //获取当前位置的元素,并同时将迭代器对象指向下一个元素处Iterator<E> it = c.iterator();
while(it.hasNext()){String s = it.next();sout(s);
}
(增强for循环)for each循环:
for(int i:arr){sout(i);
}

2,双列集合

键值对(entry键值对对象)一一对应

一次添加一对数据,键不能重复,值可以重复

顶层接口:Map接口

1,put(K key,V value)//添加元素2,remove(O key)//根据键删除键值对元素3,clear()//移除所有的键值对元素4,B containsKey(O key)//判断集合是否包含指定键5,B containsValue(O v)//判断集合是否包含指定值6,B isEmpty()//判断集合是否为空7,I size()//返回集合长度

List集合

List集合是一种有序的集合,可以存储重复的元素,是单列集合框架的一员,继承于Collection接口

List集合特点:

1,元素有序:存储顺序和取出顺序一致
2,元素可重复:可以存储重复的元素
3,有索引:增加了和索引相关的增删改查方法

常用List实现类:

1,ArrayList:底层使用数组实现,支持快速随机访问,但增删元素较慢
2,LinkedList:底层使用双向链表实现,增删元素较快,但随机访问元素较慢

List集合特有方法

void add(int index,E element) //在指定位置插入指定的元素
E remove(int index)//删除指定索引处的元素,返回被删除的元素
E set(int index,E element)//修改指定索引处的元素,返回被修改的元素
E get(int index)//返回指定索引处的元素

ArrayList

最常用的一种集合泛型类

泛型<>:规定元素的数据类型

ArrayList底层操作机制源码分析

底层维护了一个Object类型的数组elementData

空参构造:在底层创建一个默认长度为0的数组(jdk7中为10)

如果是指定容量capacity的构造,则初始容量为capacity

添加元素时,会判断是否需要扩容

需要扩容:如果第一次添加先扩容到10,如果还需要扩容,就扩容到1.5倍

如果创建时使用的是指定容量构造,则扩容时直接扩容至1.5倍

增加数据:
list.add(E e);//将元素添加到列表末尾list.add(int index,E e)//将元素添加到指定索引list.get(int index)//获取对应索引的值list.size()//返回集合存储的元素个数list.remove(int index)//删除对应索引的元素,返回被删除的元素值list.remove()//删除元素,返回删除与否的布尔值list.set(int index,元素)//用指定元素替换对应索引的值,返回被修改的元素
使用场景:

需要频繁查询或者数据量不大时增删

在数据量大又需要增删时不建议使用

底层原理

创建对象时,将一个长度为0的Object类型数组赋值给elementData

添加元素时,会判断size是否等于数组的长度,如果相等,会调用grow()方法进行扩容,使用Arrays.copyOf方法将elementData传到新数组中,如果原数组长度为0,会传到一个长度为10的数组中.如果不为0,会传到一个长度等于size+size/2的数组中.


LinkedList

底层使用链表

常用方法

请添加图片描述

存在索引,用以帮助判断遍历时从前向后遍历还是从后向前遍历


Set集合

一种不允许包含重复元素的集合,继承于Collection接口

Set集合特点:

1,元素唯一:添加重复元素会失败

2,无序性:Set集合中的元素没有顺序,存取顺序不一定相同

但是每次打印的顺序是相同的

3,无索引:Set集合中没有带索引的方法

Set集合常用实现类如下:

1,HashSet:

基于哈希表实现,使用哈希算法存储元素

不保证元素的顺序,存取顺序可能不一致

允许存储null值

适用于一切对存储要求没有特殊要求且元素唯一的场景

2,LinkedHashSet:

继承于HashSet,底层使用哈希表和链表实现

保留元素的插入顺序,存取顺序一致

允许存储null值

适用于元素有序且唯一的场景

3,Tree:

基于红黑树实现,可以对元素进行排序

保证元素默认按照升序排列,或者按照指定的Comparator(比较器)进行排序

不允许存储null值

适用于需要对元素进行排序的场景


TreeSet集合应用

属于Set接口的实现类,底层使用红黑树数据结构来存储元素,TreeSet是有序的,不允许有重复元素

特点:

1,对于数值类型:Integer,Double默认按照数值大小进行升序排列

2,对于字符串类型,默认按照首字符的哈希值升序排列

3,对于无法直接排序的自定义对象,需要自己指定排序方式

排序方式:

1,自然排序:

自定义类实现Comparable接口,重写接口中compareTo方法,根据方法返回值进行指定元素位置

如果返回值为负数,表示存入的元素为较小值存在左侧

如果返回值为0,表示当前存入的元素跟集合中的元素重复了,不存

如果返回值为正数,表示存入的元素为较大值存在右侧

2,比较器排序:

TreeSet的带参构造方法使用的是"比较器排序"对元素进行排序的

比较器排序就是让TreeSet集合构造方法接收Comparator接口的实现类对象

重写Comparator接口中的compare(T o1, T o2)方法,指定排序规则

o1代表的是当前往集合中添加的元素,o2代表的是集合中已经存在的元素,排序原理和自然排序相同

两种排序方式都存在时默认使用比较器排序方式

可变参数概述

一种特殊的参数类型,用于表示方法的参数个数可以变化,在方法声明时,使用三个连续的省略号来表示可变参数,

在方法体中,可变参数会被当做数组进行处理,可以通过遍历或直接使用索引访问

可变参数只能作为方法的最后一个参数,一个方法只能有一个可变参数

eg:

public void printNumbers(int...numbers)

HashSet

HashSet原理及应用

底层创建一个hashmap对象,hashset即为一个只有键的hashmap

实现了Set接口,通过哈希表实现了高效的插入,删除和查找操作.可以快速判断一个元素是否存在集合中,并且不允许集合中存在重复的元素,但HashSet的迭代顺序并不确定,所以不保证元素的顺序是否和插入顺序一致

底层原理

数组+链表+红黑树

创建一个默认长度16的数组,默认负载因子为0.75,数组名字table

负载因子:元素个数>=长度*负载因子时会自动扩容

使用元素的哈希值对数组的长度求余计算出应该存入的位置

判断当前位置是否为null,如果为null直接存入

如果不为null比较不相等则存入

当链表长度超过8且数组长度>=64时,自动将链表转成红黑树

红黑树:

自平衡的二叉树

每个节点都有颜色属性(红/黑)

根节点一定为黑

红色节点不能相连

任何一个节点到叶节点经过的黑色节点数量相同

哈希值

一个十进制的整数,用来表示对象的特定标识.哈希值是通过哈希函数对对象的内部状态进行计算得到的

可以通过hashCode()方法来实现,该方法是object类的一个方法,所有java对象都可以调用

同一个对象多次调用hashCode()方法返回的哈希值是相同的,不同的对象,他们的哈希值一般不相同,但也有可能会相同(哈希冲突)

哈希冲突:因为哈希值是有限的,但对象数量是无限的,所以必然会有哈希冲突

使用规则

HashSet集合想要保证元素的唯一性,需要重写hashcode()和equals()方法

LinkedHashSet原理及应用

HashSet的一个子类,继承了HashSet的所有特性,保留了元素的插入顺序,可以理解为LinkedHashSet是一个有快速查找能力的链表,或是一个保留了插入顺序的哈希表

LinkedHashSet的特点:

1,插入顺序被保留

2,允许存储null元素

3,不允许重复元素,与hashset一样也会根据元素的哈希值判断是否为重复元素

集合遍历时,并发修改异常

当使用迭代器遍历时,如果对集合修改(增删),就会抛出ConcurrentModificationExcepiton(并发修改异常)

产生原因:

因为集合在遍历过程中使用了一个内部的标记来检测集合是否被修改,如果发现集合被修改,则会抛出异常,为了保证在多线程环境下,遍历集合的线程能正确地获取集合状态

解决方案;

使用迭代器内部的remove()方法来删除元素,remove()方法会更新内部的标记,避免并发修改异常

需要添加元素时:

可以使用ListIterator(迭代器的子接口列表迭代器)

可以使用其中的hasPrevious()方法倒着遍历

但需要先正向遍历到列表末尾

其中包含add()方法,可以添加元素,会在当前迭代器指向的元素之后添加元素

或者干脆直接使用for循环,一定不会发生并发修改异常


Collections工具类

提供了一系列静态方法用于对集合进行操作和处理,包含了一些操作集合的工具方法,这里我稍微挑几个我觉得有用的记录一下

static boolean addAll(Collection c,T ...elements)//将所有元素全部添加到集合内
static List emptyList() //返回空列表
static void reverse(List list)//反转集合
static void sort()//排序
static void swap(List list,int i,int j)//交换集合中的两个元素

Map集合介绍

双列集合

一种键值对数据结构,提供了一种映射关系,可以将键值进行关联,Map集合以键的唯一性来存储和操作元素(主键?),每个键对应一个值,

键唯一,但值可以相同

Map集合具有以下特点:

1,键的唯一性:map集合中的键是唯一的,不允许重复键存在,如果尝试放入重复键,会将旧值覆盖

2,无序性:map集合中的元素是无序的,即存取顺序和插入顺序无关

3,可以存储null值和null键,map集合可以存储null值和null键,但是需要注意,只能同时存在一个null键

MAP集合常见的使用场景:

1,存储和快速查找:map集合可以用来存储键值对,通过键快速查找对应值,适用于需要频繁查找和操作数据的场景

2,统计和计数:可以用来统计数据频率或者次数,eg将元素作为键,次数作为值

3,配置信息:Map集合可以用来存储配置信息,eg将属性名作为键,属性值作为值,以便于读取和修改配置信息

Map集合常用实现类

1,HashMap:HashMap是最常用的Map实现类,基于哈希表实现,能快速查找和插入操作,不保证元素顺序,允许存储null键和值,但不保证线程安全

无序性,允许空键和空值,高效性,保证键唯一

2,TreeMap:TreeMap是基于红黑树实现的有序Map集合,根据键的自然顺序或者自定义比较器对键进行排序,保证元素按照键顺序排列,不允许存储null键但可以存储null值

有序性,不允许空值,保证键唯一

3,LinkedHashMap:LinkedHashMap是HashMap的一个子类,在HashMap的基础上增加了链表维护键值对的插入顺序,保证了元素的插入顺序,允许存储null键和null值,但不保证线程安全

保持插入顺序:可以按照元素插入的顺序进行排序,也可以按照最近访问的顺序进行排序

允许空键和空值,键唯一

Map集合常用方法

public v put(K key,V value) //添加元素(也可以修改)
//如果put覆盖了元素就返回被覆盖元素的值
public int size() //获取集合的大小
public void clear()//清空集合
public boolean isEmpty()//判断集合是否,为空返回true
public v get(Object key)//根据键获取对应值
public v remove(Object key)//根据键删除整个元素
public boolean containsKey(Object key)//判断是否包含某个键
public boolean containsValue(Object value)//判断是否包含某个值
public Set<K> keySet() //获取全部键的集合
public Collection<V> values()//获取Map集合的全部值
Map的遍历:
方法1:

keySet():返回一个包含所有键的Set集合,可以通过遍历这个集合来获取每个键

for(String key:map.keySet()){Integer value = map.get(key);//再通过获取到的键进行操作
}

get(Object key)根据指定的键获取对应的值

方法2:

Entry为Map的接口的内部接口,要使用

要么使用Map.Entry

要么导包

entrySet():返回一个Set集合,包含Map中所有键值对的集合,每个键值对都是一个Map.Entry对象

getKey():获取当前Map.Entry对象的键

getValue():获取当前Map.Entry对象的值

Map<String,Integer> map = new HashMap<>();
map.put("A",1);
map.put("B",2);
map.put("C",3);
for(Map.Entry<String,Integer> entry : map.entrySet()){String key = entry.getKey();Integer value = entry.getValue();//得到Entry键值对,进行操作
}

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

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

相关文章

Qt判断一个点在多边形内还是外(支持凸边形和凹变形)

Qt判断一个点在多边形内还是外&#xff08;支持凸边形和凹变形&#xff09;_qt 判断点是否在多边形内-CSDN博客 这里实现的方法是转载于https://blog.csdn.net/trj14/article/details/43190653和https://blog.csdn.net/WilliamSun0122/article/details/77994526 来实现的&…

24考研-东南大学916经验贴

文章目录 一、个人情况二、初试备考经验1.政治 67&#xff0c;客观382.英语 60&#xff0c;客观大概40左右3.数学 136&#xff0c;客观应该满分4.专业课 数据结构计网 114小分不清楚 三、复试备考经验笔试&#xff1a;C面试复试流程 附一下成绩单&#xff1a; 一、个人情况 本…

vue 中使 date/time/datetime 类型的 input 支持 placeholder 方法

一般在开发时&#xff0c;设置了 date/time/datetime 等类型的 input 属性 placeholder 提示文本时&#xff0c; 发现实际展示中却并不生效&#xff0c;如图&#xff1a; 处理后效果如图&#xff1a; 处理逻辑 判断表单项未设置值时&#xff0c;则设置其伪类样式&#xff0c;文…

postgresql发布和订阅

一、发布订阅介绍 发布和订阅使用了pg的逻辑复制的功能&#xff0c;通过发布端创建publication与表绑定&#xff0c;订阅端创建subscription同时会在发布端创建逻辑复制槽实现逻辑复制功能 逻辑复制基于 发布&#xff08;Publication&#xff09; 与 订阅&#xff08;Subscri…

低代码平台种草推荐

告别繁琐&#xff0c;拥抱未来&#xff01;只需简单拖拽&#xff0c;Vue代码即刻生成&#xff0c;一键下载&#xff0c;轻松上手。我们的低代码平台&#xff0c;不仅高效便捷&#xff0c;更完全开源&#xff0c;让你自由探索编程的无限可能&#xff01; 下载网址&#xff1a;ht…

three.js零基础入门超全超细的教程整理(一)

事情是这样的&#xff1a; 有一天 我干完活 看技术文章 发现了three.js 诶&#xff01;这玩应挺有意思 盘盘 于是第一天找教程 上官网 初上手 第二天 找案例 渲模型 试VR 第三天 捋文档 然后来活了 没时间捋了 下面是集百家精华教程的整理总结 涉及到教程方面有加源作者和地址…

前端用Scss简化媒体查询

1、演示 2、未优化前的代码 .header {width: 100px;height: 100px;background-color: red; } media (min-width: 320px) and (max-width: 480px) {.header {width: 10px;} } media (min-width: 320px) and (max-width: 480px) {.header {height: 20px;} } media (min-width: 48…

如何做接口测试呢?接口测试有哪些工具!

回想入职测试已经10年时间了&#xff0c;初入职场的我对于接口测试茫然不知。后来因为业务需要&#xff0c;开始慢慢接触接口测试。从最开始使用工具进行接口测试到编写代码实现接口自动化&#xff0c;到最后的测试平台开发。回想这一路走来感触颇深&#xff0c;因此为了避免打…

期货量化交易软件:模式搜索的暴力方法(第六部分)循环优化

概述 考虑到我上一篇文章中的材料&#xff0c;我赫兹量化软件可以说这只是我在算法中引入的所有函数的肤浅描述。它们不仅涉及EA创建的完全自动化&#xff0c;还涉及诸如结果优化和选择的完全自动化以及随后用于自动交易&#xff0c;或者我赫兹量化稍后将展示的更先进的EA的创…

Vscode 中调试Django程序

调试介绍: ​​​​​​​Explore the debugger Debug/调试 可以让我们在特定的代码行上暂停程序的运行。当程序暂停时&#xff0c;我们可以查看变量的数值&#xff0c;在“Debug控制台”中运行代码&#xff0c;或利用“Debug”工具提供的其他功能。启动Debugger/调试器会自动…

LeetCode-热题100:138. 随机链表的复制

题目描述 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成&#xff0c;其中每个新节点的值都设为其对应的原节点的值。…

Golang——方法

一. 方法定义 Golang方法总是绑定对象的实例&#xff0c;并隐式将实例作为第一实参。 只能为当前包内命名类型定义方法参数receiver可以任意命名。如方法中未曾使用&#xff0c;可省略参数名参数receiver类型可以是T或*T。基类型T不能是接口或指针类型(即多级指针)不支持方法重…