24、Java 集合
十一章:Java 集合
一、集合框架的概述
1、集合:就像一个容器,可以动态的把多个对象的引用放入容器中。简称 Java 容器
说明:此时的存储,主要指的是内存层面的存储,不涉及到持续化的存储(.txt, .jpg, avi,数据库中)
2、数组在存储多个数据方面的特点:
>一旦初始化之后,长度就确定了
>一旦定义好,其元素的类型就确定了。我们只能操作指定类型的数据。比如: String[] arr; int[] arr1;
数组在存储多个数据方面的缺点:
>一旦初始化,其长度就不可修改
>数组中提供的方法非常有限,对于添加、删除、插入数据等操作非常不便,效率也不高
>获取数据中实际元素个数的需求,数据没有线程的属性或方法可用
>数组存储数据的特点:有序、可重复。对于无序的、不可重复的需求,无法满足
二、集合框架:Collection 与 Map
List ---->“动态”数组
Set----->高中讲的“集合”
Map---->高中函数: y=f(x) 可以 key 多对一 value 不可以 key 一对多 value
三、Collection 接口中的 方法的使用
像 Collection 接口的实现类中的对象中添加数据 obj 时,要求 obj 所在类要重写 equals
package com.java.kcw1;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**集合元素的遍历操作,使用 Iterator
* @author Jackson_kcw
* @Time 2025-03-01 PM1:52
*/
public class InteratorTest {
@Test
public void test1() {
Collection coll1=new ArrayList();
coll1.add("a");
coll1.add("b");
coll1.add("c");
coll1.add(false);
Iterator iterator = coll1.iterator();
// System.out.println(iterator.next());
// System.out.println(iterator.next());
// System.out.println(iterator.next());
// System.out.println(iterator.next());
//遍历操作
while(iterator.hasNext()) {
//next(): 指针下移;将下移以后集合位置上的元素返回
System.out.println(iterator.next());
}
}
}
集合对象每次调用 iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前
内部定义了 remove(),可以在遍历的时候,删除集合中的元素。此方法不同于直接嗲用 remove
For-each
package com.java.kcw1;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
/**JDK5.0新增 foreach 循环,用于
* @author Jackson_kcw
* @Time 2025-03-01 PM2:19
*/
public class ForTest {
@Test
public void test() {
Collection coll=new ArrayList();
coll.add("AA");
coll.add("BB");
coll.add(11); //自动装箱
System.out.println(coll.size());
//for( 集合元素的类型 局部变量:集合对象)
for(Object obj:coll){
System.out.println(obj);
}
}
}
List 接口概述:List 集合了类元素有序、可重复
面试题目:ArrayList\LinkedList\Vector 三者的异同
同:三个类都实现了 List 接口,存储数据的特点相同:元素有序、可重复
异:
ArrayList::作为 List 接口的主要实现类,线程不安全,效率高
LinkedList:对于频繁的插入和删除操作,使用效率比 ArrayList 高,底层使用双向链表存储
Vector:作为 List 接口的古老实现类;线程安全,效率低
List 接口中的常用方法
总结常用方法:
增:add(Object obj)
删:remove(int index) / remove(Object obj)
改:set(int index,Object ele)
查:get(int index)
插:add(int index,Object ele)
长度:size()
遍历:一、Iterator 迭代器方式 二、for each 三、普通的循环
Set接口:存储无序的、不可重复的数据 —>高中讲的集合
HashSet: 作为 Set 接口的主要实现类;线程不安全;可以存储 null 值
LinkedHashSet:作为 HashSet 子类;遍历其内部数据时,可以按照添加的顺序遍历
TreeSet:可以按照添加对象的指定属性,进行排序
Set 接口没有额外一些方法,使用的都是 Collection 里面声明的方法
Set
以 HashSet 为例:
1、无序性:不等于随机性。存储的数据在底层数组中并非按照数据所以你的顺序添加,而是根据数据的 hash 值来确定的
2、不可重复性:保证添加的元素按照 equals()方法判断时,不能返回 true.即相同的元素只能添加一个
二、添加元素的过程:以 HashSet 为例:
我们向 HashSet 添加元素 a,首先调用元素a 所在类的 hashCode()方法,计算 a 的哈希值,此哈希值接着通过某种算法计算出在 HashSet 底层数组中的存放完位置(即为:索引位置),判断数组在此位置是否已经有元素:
如果此位置上没有其他元素,则元素 a 添加成功
如果此位置有元素 b,则比较元素 a 与元素 b 的 哈希值:
如果 hash 值不同,则元素 a 添加成功
如果 hash 值相同,贼需要调用元素 a 所在类的 equals()方法:equals()返回 true,元素 a 添加失败
equals()返回 false,则元素 a 添加成功
向 TreeSet 里面添加的数据,要求是相同类的对象,不能添加不同类的对象
五、Map 接口
5-1、|—Map:双列数据,存储 key-value 的值 ---------类似高中的函数 :y=f(x)
|—HashMap:作为 Map 的主要实现类;线程不安全,效率高;可以存储 null 的 key 和 value
|----LinkedHashMap:保证在遍历 map 元素时,可以按照添加的顺序实现遍历
|—TreeMap:保证按照添加的 key-value 对 进行排序,实现排序遍历。此时考虑 key 的自然排序或定制排序
| —Hashtable:作为古老的实现类;线程安全,效率低;不可存储 null 的 key 和 value
|—Properties:常用来处理配置文件。key 和 value 都是 String 类型
HashMap 的底层: 数组+链表(jdk7 及之前)
数组+链表+红黑树(jdk8)
5-2 Map 结构的理解
5-3 HashMap 的底层实现原理
以 jdk7 为例说明:
HashMap map= new HashMap();
在实例化以后,底层创建了长度为 16 的一维数组 Entry[] table
…可能已经执行过多次 put…
map.put(key1,value1):
首先,调用 key1 所在类的 hashCode()计算 key1 哈希值,此哈希值经过某种算法计算以后,得到在 Entry 数组中的存放位置
如果此位置上的数据为空,此时的 key1-value1 添加成功
如果此位置的数据不为空,(意味着此位置上存在一个或多个数据(以链表形式存在)),比较 key1 和已经存在的一个或多个数据的哈希值:
如果 key1 的哈希值与已经存在的数据的哈希值都不相同,此时的 key1-value1 添加成功
如果 key1 的哈希值和已经存在的某一个数据(key2-value2)的哈希值相同,继续比较:调用 key1 所在类的 equals()方法,比较:
如果 equals()返回 false:此时的 key1-value1 添加成功
如果 equals()返回 true: 使用 value1 替换value2
JDK8 相较于 7 在底层实现方面的不同:
1、new HashMap():底层没有创建一个长度为 16 的数组
2、jdk8 底层的数组是:Node[],而非 Entry[]
3、首次调用 put 方法时,底层创建长度为 16 的数组
4、jdk7 底层结构只有数组加链表 jdk8 底层结构:数据+链表+红黑树
当数组的某一个索引位置上的元素以链表形式存在的数据个数>8 且当前数组的长度>64,此时索引位置上的所有数据改为使用红黑树存储
这里面跳过了 hashMap 底层实现原理,这一部分讲的比较复杂和抽象,本人因为时间原因跳过了,但是建议再找文档或视频看看
5-4 Map接口中常用的方法
工具类 Collections:操作 Collection、Map 的工具类
面试题:Collections 与 Collection 的区别
对比项 | Collection | Collections |
---|---|---|
定义 | Collection 是 java 的接口 | Collections 是 Java 提供的工具类 |
作用 | 定义了 Java 集合的基本操作,如 List、Set等的父接口 | 提供集合操作的工具方法,如排序、搜索、线程安全包装等 |
子类/实现方式 | List\Set\Queue 等结合框架的接口 | 不能被继承,只能直接调用其静态方法 |
常见方法 | add()、remove()、size()等 | sort()、shuffle()、synchronizedList()等 |