java之集合

Posted scanner小霸王

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java之集合相关的知识,希望对你有一定的参考价值。

1.集合的体系图

在这里插入图片描述

2.数组vs集合

a)数组:
在这里插入图片描述
b)集合
在这里插入图片描述

3.集合的继承图(主要的一些类)

集合主要两种:单列集合(对象)、双列集合(键值对)
a)collection
在这里插入图片描述
b)Map
在这里插入图片描述

4.collection接口实现类的接口

a)
在这里插入图片描述
b)collection的子类都可以使用Iterator迭代器
在这里插入图片描述
ii)迭代器原理:
可重复;
在这里插入图片描述
ii)增强for循环
在这里插入图片描述

5.List接口

在这里插入图片描述
在这里插入图片描述

6.arrayList

a)可以放任何值,可以加入null,并且多个
b)底层是由数组实现
c)arrayList等同vector,效率高于vector,但是线程不安全
d)创建一个对象分析
在这里插入图片描述
源码分析
ii)无参数
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
ii)指定大小的参数
构造器的差别
在这里插入图片描述

7.vector

扩容机制:
在这里插入图片描述

8.LinkedList

在这里插入图片描述
在这里插入图片描述a)添加的源码分析:

import java.util.LinkedList;

public class LinkList {
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        linkedList.add(1);
        System.out.println("linkedList:"+linkedList);

    }

}

在这里插入图片描述b)删除的源码分析:
linkedList.remove();

在这里插入图片描述
在这里插入图片描述注解:核心方法是unlinkFirst()
个人一开始比较疑惑的是:
if (next == null)
last = null;
else
next.prev = null;
当next为空的时候,证明没有下一个元素了,所以最后一个肯定也为null;
else:不为空的话,作为第一元素的prev也应该指向为空,(至于为啥这里last不用在重新指向呢?是因为add()的时候,last代表最后一个元素,只要元素存在,last值就一定还为发生改变)

两者比较:
两者都是线程不安全
在这里插入图片描述

9.set接口

单向链表
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
a)遍历的二种方式(没有普通for循环,因为没有通过索引获取的方法)
ii)迭代器
在这里插入图片描述
ii)增强for循环
在这里插入图片描述
在这里插入图片描述
b)hashset底层机制(底层是hashMap)
hashMap底层是:数组+链表+红黑树

在这里插入图片描述
在这里插入图片描述
分析:
ii)hashSet底层是hashMap,第一次进来的时候先进行扩容到16,默认加载因为是0.75,即没每次达到当前数组长度的0.75倍时候,扩容到当前数组长度2;
在这里插入图片描述

ii)当根据计算得到新进来的元素在tab的索引的已经存在元素的时候,比较他们之间的hashcode+equal(),倘若符合条件,将对元素进行覆盖;

ii)如果p可能是树,最后一种情况就是链表;
当进行链表的遍历时候,没有相等的话,就加载链表的末端,如果加进来的数量大于等于8-1的时候,将调用树化的方法;
ii)链表循环有两处跳出的判断:一处是成功往链表加入节点;一处是判断元素的hash()+equal()符合条件
在这里插入图片描述

c)源码分析:
在这里插入图片描述
d) hashset地扩容和转换为红黑树机制

e)hashSet比较原理
(hashcode()+equals())

注释:例如一个对象Dog
输出(new Dog(“name”) 其实是new Dog(“name”).toString())

9)linkedHashSet
(可以看成是在HashSet的基础上加上before和after保证元素的插入顺序)
双向链表:确保遍历顺序和插入顺序一样
在这里插入图片描述

在这里插入图片描述
重点:
在这里插入图片描述
为什么hashMap N o d e [ ] 能 存 放 L i n k e d H a s h M a p Node[]能存放LinkedHashMap Node[]LinkedHashMapEntry呢,由源码可以看出,他们是继承关系:
在这里插入图片描述

10.Map主要结构图

在这里插入图片描述
a)jdk8 map 接口特点
在这里插入图片描述
b)map.put存的和取的顺序是不一样的,
得到key的时候,先根据hashcode()计算位置,在根据equals()来判断,这也是key为啥不能重复的原因,倘若放重复的key,将会把之前的k-v替换掉

在这里插入图片描述

c)一个k-v是放在hashMap N o d e 里 面 h a s h M a p Node里面 hashMap NodehashMapNode node = newNode(hash,key,value,null),而node是实现entry;
然后再把一个个newNode放在set里面,方便遍历,事实上set里面的(keySet《set》,values《Collection》)只是简单的指向,并非真正的重新存入一份数据。
在这里插入图片描述

在这里插入图片描述

d)map的遍历
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
e)hashMap底层机制
ii)示意图
在这里插入图片描述
在这里插入图片描述
ii)程序分析
在这里插入图片描述
在这里插入图片描述
ii)第一次进去将进行扩容
在这里插入图片描述
从resize()方法可以看出是个Node<key,value>
在这里插入图片描述
ii)当hash值为null时候,将创建一个newNode加入到Node<k,v>[] tab 数组
在这里插入图片描述
ii)当为重复的时候,将实现覆盖
在这里插入图片描述
ii)当判断是链表的时候,有两种情况跳槽循环:
链表长度大于等于8;链表存在元素相等的情况
在这里插入图片描述
ii)当长度达到8的时候,并不是马上树化,长度不够64的情况会先进行扩容
在这里插入图片描述

11.hashTable

a)基本介绍
在这里插入图片描述
b)扩容
在这里插入图片描述

12.propeties

在这里插入图片描述

13.集合的选择

在这里插入图片描述

14.treeSet

在这里插入图片描述
a)treeSet底层是treeMap
在这里插入图片描述
在这里插入图片描述
b)cpr代表传进去的内部类,进行循环比较
在这里插入图片描述

15.treeMap

(无参构造是没有顺序的,和treeSet类似)
当添加的key相等时候,value是会替换的
在这里插入图片描述

16Conllections工具类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

17.hashSet和treeSet如何实现去重

在这里插入图片描述

18.运行下面代码,将会报错

传入无参构造时候,将会把person转为Comparable,而person并未实现Comparable接口,所以会出现类型异常
在这里插入图片描述
一开始p1和p2能够加入,
当p1.name改变时候
set.remove(p1);由于hashCode发生了改变,无法移除到原来的对象,所以此时还保持着两个元素;
set.add(new Person(1001,“cc”)),计算出来的hashcode不一样,所以会存放进去;
当set.add(new Person(1001,“AA”)),虽然和第一个的hashcode一样,但是此时的内容是不一样的,所以将形成链表挂在第一个的后面

在这里插入图片描述

19.vector和Arraylist的区别

在这里插入图片描述

以上是关于java之集合的主要内容,如果未能解决你的问题,请参考以下文章

Java源代码之集合框架(图)

代码片段 - Golang 实现集合操作

laravel特殊功能代码片段集合

java代码之美---guava之Immutable(不可变)集合

201621123062《java程序设计》第九周作业总结

编写高效的Java代码:常用的优化技巧之并发编程技巧