java路线------集合

1、类集设置的目的

对象数组有那些问题?普通的对象数组的最大问题在于数组中的元素个数是固定的,不能动态的扩充大小,所以最早的时候可以通过链表实现一个动态对象数组。但是这样做毕竟太复杂了,所以在 Java 中为了方便用户操作各个数据结构,
所以引入了类集的概念,有时候就可以把类集称为 java 对数据结构的实现。
类集是java对数据结构成熟的实现。
在整个类集中的,这个概念是从 JDK 1.2(Java 2)之后才正式引入的,最早也提供了很多的操作类,但是并没有完整的提出类集的完整概念。
类集中最大的几个操作接口:Collection、Map、Iterator,这三个接口为以后要使用的最重点的接口。所有的类集操作的接口或类都在 java.util

1.1Java 类集结构图

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

1.2Collection 接口

Collection 接口是在整个 Java 类集中保存单值的最大操作父接口,里面每次操作的时候都只能保存一个对象的数据。
此接口定义在 java.util 包中。
此接口定义如下:
public interface Collection extends Iterable
此接口使用了泛型技术,在 JDK 1.5 之后为了使类集操作的更加安全,所以引入了泛型。
此接口的常用方法如下所示:
在这里插入图片描述
本接口中一共定义了 15 个方法,那么此接口的全部子类或子接口就将全部继承以上接口中的方法。但是,在开发中不会直接使用 Collection 接口。而使用其操作的子接口:List、Set。

1.3List 接口

在整个集合中 List 是 Collection 的子接口,里面的所有内容都是允许重复的。
List 子接口的定义:
public interface List extends Collection 此接口上依然使用了泛型技术。此接口对于 Collection 接口来讲有如下的扩充方法:
在这里插入图片描述
在 List 接口中有以上 10 个方法是对已有的 Collection 接口进行的扩充。
所以,证明,List 接口拥有比 Collection 接口更多的操作方法。
了解了 List 接口之后,那么该如何使用该接口呢?需要找到此接口的实现类,常用的实现类有如下几个:
· ArrayList(95%)、Vector(4%)、LinkedList(1%) Vector是ArrayList的早期实现,Vector是线程安全的。而ArrayList是线程不安全的

2 ArrayList

使用的是数组结构,增加删除慢,查找快
ArrayList 是最常用的 List 实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要将已经有数组的数据复制到新的存储空间中。当从 ArrayList 的中间位置插入或者删除元素时,需要对数组进行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。
在这里插入图片描述

package org.listdemo.arraylistdemo;
import java.util.ArrayList;
import java.util.List;
public class ArrayListDemo01 {
    
    
public static void main(String[] args) {
    
    
List<String> all = new ArrayList<String>(); // 实例化List对象,并指定泛型类型
all.add("hello "); // 增加内容,此方法从Collection接口继承而来
all.add(0, "LAMP ");// 增加内容,此方法是List接口单独定义的
all.add("world"); // 增加内容,此方法从Collection接口继承而来
System.out.println(all); // 打印all对象调用toString()方法
}
}

以上的操作向集合中增加了三个元素,其中在指定位置增加的操作是 List 接口单独定义的。随后进行输出的时候,实际上调用的是 toString()方法完成输出的。
可以发现,此时的对象数组并没有长度的限制,长度可以任意长,只要是内存够大就行

ArrayList源码剖析
在这里插入图片描述
刚创建的时候数组的长度为0,当开始存入的时候要进行扩容。
在这里插入图片描述
在这里插入图片描述
s是当前有效数组的长度。
在这里插入图片描述
第一次调用 grow里的参数为 0+1=1
在这里插入图片描述
所以里边传入的参数minCapacity为1,此时利用copyOf函数将新数组复制给旧数组。

在这里插入图片描述
第一次添加数据的时候进入第一个if判断长度是否为0,如果为0的话就执行默认长度为10 的那个方法,如下图
这里默认长度是10
在这里插入图片描述
为什么出现扩容1.5倍还存不下的情况呢?
旧长度为0, 0+0.50=0 1+0.51=1。
那么不走上面的那个if说明扩容以后的内存够用就会执行return方法
在这里插入图片描述
如果扩容的新长度 --允许扩容的最大长度小于0,那么久返回新长度,否则执行下边的那个方法
在这里插入图片描述
先判断需要的内存大小是否小于0,小于0那么就是超范围溢出了,否则如果minCapacity>MAX_ARRAY_SIZE(这个最大值就是int的最大值-8),那么他就是介于int的最大值-8到int之间的,返回这个值,
不然就返回那个最大值(MAX_ARRAY_SIZE 也就是int最大值-8)

3Vector

Vector 与 ArrayList 一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写 Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问 ArrayList 慢。

4LinkedList

使用双向链表实现,增加删除快,查找慢
在这里插入图片描述

5 Iterator &&ListIterator

前者可以迭代Collection下的所有集合,后者只能迭代List下的集合
在这里插入图片描述
迭代器判断next在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6 Set集合

set是一个不包含重复元素的集合

6.1HashSet

它是一个散列存放的,是一个无序存放的,输出也不是按序的
在这里插入图片描述
如果存储重复的值会返回false。
在这里插入图片描述

6.2 TreeSet

采用有序的二叉树存储
按照数据的顺序进行存储,可以看到输出的数据是顺序的
在这里插入图片描述
但是存储自定义的数据类型时出错了,因为系统不知道该怎么给你进行排序,此时必须实现Comparable接口
在这里插入图片描述
修改后
在这里插入图片描述
在这里插入图片描述
如果有两个数据是相同的,例如本例中年龄相同,那么后面的那个数据就不会存入了。

7Map集合

collection是单值存储,而Map是键值对存储,键不可以重复。set集合在使用map的键存储,从而使它的内容不重复

8 哈希表

在这里插入图片描述

哈希表的基本结构如图:
在这里插入图片描述
当表中存储的数据达到一定量,达到75%时。那么就会对桶进行扩容,扩容的大小就是原来的两倍,此时取余的数字也变成原来的两倍。

8.1 HashMap的源码分析

存储值先计算哈希值,然后进入到putVal里边
在这里插入图片描述
接下来的流程大概是下图这样的:
在这里插入图片描述

8.2 Map的使用案例

在这里插入图片描述
这三个类都可以实现存储
在这里插入图片描述
但是他们存储的顺序不一样,根据输出结果也可以看出来
如果使用TreeMap的话,排序的对象时我们自定义的则需要实现排序接口
上图的这四行都可以实现Map集合

8.3 map集合各子类区别分析

HashMap 效率高,但是线程不安全,下图三个线程同时操作,那么效率很高,但是由于每条线程分别对数据进行更新,因此可能会造成了数据不一致,所以是线程不安全的。
在这里插入图片描述
HashTable是线程安全的,效率变慢
在这里插入图片描述
ConcurrentHashMap 采用分段锁机制保证线程安全效率也比较高
原理是只要几个线程操作的不是同一个哈希桶,那么就不需要排队,如果操作的是同一个哈希桶则前一个线程会上锁。

TreeMap是一个有序的存储(不保证存储顺序只不过是在排序),根据键在排序
LInkedHashMap在存储到HashMap的时候还会存储到一个双向链表中

8.4 散列表散列操作详解

初始表的容量要给的合理,避免系统重复的进行散列扩容浪费计算机的性能
散列因子给的太大太小都不合适,太大了存储效率高查询效率低
太小了存储效率低,查询效率高

8.5存储自定义的对象

之前存储了“金苹果”,所以哈希表中存储了金苹果的hashcode,此处改变的时候,系统重新计算book1的hashcode发现桶中没有。于是返回null
在这里插入图片描述
下面又发生了一个问题
,当存储的数据达到可以发生散列的程度的时候,此时会重新把所有数据存储一遍,此时book1对象的name则改变成了铜苹果,但是当初我们以为的是金苹果存入的,这时按照金苹果查找已经找不到了,所以发生了数据错乱
所以就不要把容易发生改变信息的存到键的位置
9JDK 9出现的新特性
只有List,Set,Map都有这种方法,它的子类是没有的
在这里插入图片描述
实例:
在这里插入图片描述
关于更多面试题的内容关注公众号 小小李童鞋获取,
在这里插入图片描述

Guess you like

Origin blog.csdn.net/delete_bug/article/details/119102437