list取值_List/Map

List接口

实现类:ArrayList LinkedList Vector

ArrayList 基于数组 Object[] 实现的可扩展的集合。查询速度快。需要一块连续的内存存储

创建:默认初始大小为10(可手动设置),

add:每次增加数组元素,需要判断长度是否足够,如不够用,则创建一个长度为当前数组2倍的新数组,并拷贝原数组数据至新数组,数组扩容最影响效率。

LinkedList 底层实现是双向链表,头结点的前驱是尾节点,尾节点的后继是头结点。插入速度快。在内存中随机分布,不需要连续存储。

节点:指向前一个节点的指针+数据元素+指向后一个节点的指针。

遍历:foreach循环遍历效率高

查询:根据下表查询时,判断下标的位置是更靠近左边还是右边,决定查找的顺序。(双向查找)

Vector:与Arraylist相似,但是Vector是线程安全的,ArrayList是线程不安全的。当多个线程同时修改数组时,modCount值(int型)改变,抛出ConcurrentModificationException异常。涉及到结构体发生变化的操作,modCount都会改变


Map接口

实现类:hashMap TreeMap

HashMap:基于哈希表,哈希值可能存在冲突,使用数组+链表(Jdk1.8之后增加了红黑树结构,当链表长度超过8时,将转换成红黑树)的方式实现,链表用于解决冲突。当一组key的哈希值相同,使用equals比较key值,拿到目标值。查找的key,链表过长,影响效率。

为什么设置成8?(概率问题,泊松分布)

HashMap是线程不安全的,因为在并发执行put操作会造成死循环,因为多线程会导致Entry的链表变成环状的数据结构,那Entry的next()节点就会一直不为空,就会产生死循环获取Entry。

多线程扩容
Java7:数据迁移。在数据迁移过程中,有可能会造成链表成环状,这个取next()一直有值,死循环。
Java8:分类迁移。把要迁移的数据分类,迁移后位置不变的和改变的。

key可以存储空值,add操作是,当key==null,table[0] = null

查找:key--得到-->hash值---通过“数组长度”得到-->key的hash值在数组中的下标--迭代该数组元素的链表。

在jdk1.8(包含)之后,数组的初始容量一定是2的指数次幂,第一是为了减少哈希碰撞,第二是如果数组容量为2的指数次幂,计算地址时的模运算优化成与运算结果一致,与运算的计算速度比模运算快(测试1w条数据大概快了30倍)

加载因子设置为0.75? 在时间和空间上做一个折衷。

TreeMap:红黑树,按照key默认由小到大排序,可以自定义排序方式。

ConcurrentHashMap:线程安全的hash表,并发插入操作可能构成循环链表,导致下一次取值时Entry.next()一直不为null,死循环。那么ConcurrentHashMap是如何保证线程安全的,又是如何实现高性能读写的呢?使用volatile保证线程安全,使用分段锁实现高性能读写


Set

HashSet

能够存储空值;不能存储重复值。

向HashSet集合中传入元素时,HashSet会调用该对象的HashCode方法获取Hash值,然后决定存储位置(无序

LinkedHashSet(HashSet的子类)

能够存储空值;不能存储重复值。

LinkedHashSet是HashSet的子类,不允许重复的值,使用HashCode确定在集合中的位置,使用链表的方式确定位置(有序,按照输入的顺序输出)

TreeSet

不能存储空值,存储null会抛出空指针异常;不能存储重复值,

5c91d24ff7979091866b9dcf6c8cc6a9.png
HashSet

eaf23a8b9c9421ffbafad0c5846980ee.png
linkedHashSet

7e9cf44d80c6b980278bd30d0b857e5d.png
treeSet
stream maplist 取值是指通过使用流(Stream)和map方法,从一个集合中取出特定属性的值。可以通过以下方式来实现: 1. 使用map方法和实体类的getter方法来提取指定属性的值。例如,你可以使用以下代码从一个List<UserInfo>中提取所有的userName属性值: ``` List<String> userNameList = uList.stream() .map(UserInfo::getUserName) .collect(Collectors.toList()); ``` 2. 使用map方法和Lambda表达式来提取指定属性的值。例如,你可以使用以下代码从一个List<UserInfo>中提取所有的mobile属性值: ``` List<String> mobileList = uList.stream() .map(u -> u.getMobile()) .collect(Collectors.toList()); ``` 3. 使用map方法和字符串拼接来提取多个属性拼接后的字符串。例如,你可以使用以下代码从一个List<UserInfo>中提取每个实体的id和userName属性,并将它们拼接成一个字符串: ``` List<String> idNameList = uList.stream() .map(u -> u.getId() + "-" + u.getUserName()) .collect(Collectors.toList()); ``` 总之,通过使用流(Stream)的map方法,我们可以方便地从集合中提取特定属性的值并将它们收集到一个新的集合中。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Java8 stream处理ListMap总结](https://blog.csdn.net/y19910825/article/details/128107210)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值