Java基础之集合类
- 一、集合的框架
- 1.1、集合概述
- 1.2、集合与数组区别
- 1.3、数组的缺点:
- 1.4、常用集合分类
- 1.5、Collection常用方法
- 二、List集合
- 2.1、ArrayList
- 2.2、LinkedList
- 2.3、Vector
- 2.4、区别
- 三、Set集合
- 3.1、HashSet集合
- 3.2、LinkedHashSet集合
- 3.3、TreeSet集合
- 四、Map集合
- 4.1、HashMap
- 4.2、TreeMap
- 4.3、HashTable
一、集合的框架
1.1、集合概述
所有的集合类和集合接口都在java.util包下。在内存中申请一块空间用来存储数据,在Java中集合就是替换掉定长的数组的一种引用数据类型。
1.2、集合与数组区别
区别 | 集合 | 数组 |
---|---|---|
长度 | 大小可以变,用多少空间拿多少空间。 | 长度固定,定义长了造成内存空间的浪费 定义短了不够用。 |
内容 | 能存储引用数据类型(存储的为对象的内存地址) | 存储基本数据类型和引用数据类型 |
元素 | 可以存储不同类型数据 (一般情况下也只存储同一种类型的数据) | 只能存储同一种类型成员 |
1.3、数组的缺点:
- 数组一旦初始化长度、类型就不能再改变了,只能按照初始化的数据类型和长度进行存储数据了。
- 数组中提供的方法比较有限,对于数据的增删改查操作不方便,并且效率也不太高。
- 可以存储重复的值,并且有序特点单一。
1.4、常用集合分类
Collection 接口的接口 对象的集合(单列集合)
├——-List 接口:元素按进入先后有序保存,可重复
│—————-├ LinkedList 接口实现类, 链表, 插入删除, 没有同步, 线程不安全
│—————-├ ArrayList 接口实现类, 数组, 随机访问, 没有同步, 线程不安全
│—————-└ Vector 接口实现类 数组, 同步, 线程安全
│ ———————-└ Stack 是Vector类的实现类
└——-Set 接口: 仅接收一次,不可重复,并做内部排序
├—————-└HashSet 使用hash表(数组)存储元素
│————————└ LinkedHashSet 链表维护元素的插入次序
└ —————-TreeSet 底层实现为二叉树,元素排好序
Map 接口 键值对的集合 (双列集合)
├———Hashtable 接口实现类, 同步, 线程安全
├———HashMap 接口实现类 ,没有同步, 线程不安全-
│—————–├ LinkedHashMap 双向链表和哈希表实现
│—————–└ WeakHashMap
├ ——–TreeMap 红黑树对所有的key进行排序
└———IdentifyHashMap
注意:
①List接口,用于存储有序的、可重复的数据(可以想象成动态的数组)
②Set接口,存储无序的、不可重复的数据(类似于高中的集合)
//Collection源码如下
public interface Collection<E> extends Iterable<E> {
1.5、Collection常用方法
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;public class CollectionExample {public static void main(String[] args) {// 创建一个ArrayListCollection<String> stringList = new ArrayList<>();// 添加元素stringList.add("Apple");stringList.add("Banana");stringList.add("Orange");// 获取集合大小int size = stringList.size();System.out.println("Size: " + size);// 判断集合是否为空boolean isEmpty = stringList.isEmpty();System.out.println("Is Empty: " + isEmpty);// 判断集合是否包含元素boolean containsBanana = stringList.contains("Banana");System.out.println("Contains Banana: " + containsBanana);// 删除元素boolean removed = stringList.remove("Orange");System.out.println("Removed Orange: " + removed);// 获取集合迭代器并遍历Iterator<String> iterator = stringList.iterator();while (iterator.hasNext()) {String element = iterator.next();System.out.println("Element: " + element);}// 添加多个元素Collection<String> anotherList = new ArrayList<>();anotherList.add("Grapes");anotherList.add("Pineapple");stringList.addAll(anotherList);// 转换为数组Object[] array = stringList.toArray();System.out.println("Array: " + java.util.Arrays.toString(array));// 清空集合stringList.clear();System.out.println("Size after clear: " + stringList.size());}
}
二、List集合
2.1、ArrayList
//ArrayList构造方法
public ArrayList(int initialCapacity)//构造一个具有指定初始容量的空列表。
public ArrayList() //默认构造一个初始容量为10的空列表。
public ArrayList(Collection<? extends E> c)//构造一个包含指定 collection 的元素的列表
代码示例:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class ArrayListExample {public static void main(String[] args) {// 创建 ArrayListList<String> arrayList = new ArrayList<>();// 添加元素arrayList.add("Apple");arrayList.add("Banana");arrayList.add("Orange");// 获取元素String firstElement = arrayList.get(0);System.out.println("First Element: " + firstElement);// 修改元素arrayList.set(1, "Grapes");// 删除元素arrayList.remove("Orange");// 获取 ArrayList 大小int size = arrayList.size();System.out.println("Size: " + size);// 判断是否包含某个元素boolean containsBanana = arrayList.contains("Banana");System.out.println("Contains Banana: " + containsBanana);// 遍历 ArrayList(使用增强 for 循环)System.out.println("Iterating using enhanced for loop:");for (String fruit : arrayList) {System.out.println(fruit);}// 遍历 ArrayList(使用迭代器)System.out.println("Iterating using Iterator:");Iterator<String> iterator = arrayList.iterator();while (iterator.hasNext()) {String fruit = iterator.next();System.out.println(fruit);}// 转换为数组Object[] array = arrayList.toArray();System.out.println("Array: " + java.util.Arrays.toString(array));// 清空 ArrayListarrayList.clear();// 判断是否为空boolean isEmpty = arrayList.isEmpty();System.out.println("Is Empty: " + isEmpty);}
}
2.2、LinkedList
LinkedList
是 Java 集合框架中 List
接口的另一个实现,基于链表实现。相比于 ArrayList
,LinkedList
在插入和删除元素的操作上更为高效,但在随机访问方面较慢。
代码示例:
import java.util.LinkedList;
import java.util.Iterator;
import java.util.List;public class LinkedListExample {public static void main(String[] args) {// 创建 LinkedListList<String> linkedList = new LinkedList<>();// 添加元素linkedList.add("Apple");linkedList.add("Banana");linkedList.add("Orange");// 获取元素String firstElement = linkedList.get(0);System.out.println("First Element: " + firstElement);// 修改元素linkedList.set(1, "Grapes");// 删除元素linkedList.remove("Orange");// 获取 LinkedList 大小int size = linkedList.size();System.out.println("Size: " + size);// 判断是否包含某个元素boolean containsBanana = linkedList.contains("Banana");System.out.println("Contains Banana: " + containsBanana);// 遍历 LinkedList(使用增强 for 循环)System.out.println("Iterating using enhanced for loop:");for (String fruit : linkedList) {System.out.println(fruit);}// 遍历 LinkedList(使用迭代器)System.out.println("Iterating using Iterator:");Iterator<String> iterator = linkedList.iterator();while (iterator.hasNext()) {String fruit = iterator.next();System.out.println(fruit);}// 转换为数组Object[] array = linkedList.toArray();System.out.println("Array: " + java.util.Arrays.toString(array));// 清空 LinkedListlinkedList.clear();// 判断是否为空boolean isEmpty = linkedList.isEmpty();System.out.println("Is Empty: " + isEmpty);}
}
以下情况使用 ArrayList :
- 频繁访问列表中的某一个元素。
- 只需要在列表末尾进行添加和删除元素操作。
以下情况使用 LinkedList :
- 你需要通过循环迭代来访问列表中的某些元素。
- 需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。
2.3、Vector
//构造方法
public Vector()//使用指定的初始容量和等于0的容量增量构造一个空向量。
public Vector(int initialCapacity)//构造一个空向量,使其内部数据数组的大小,其标准容量增量为零。
public Vector(Collection<? extends E> c)//构造一个包含指定 collection 中的元素的向量
public Vector(int initialCapacity,int capacityIncrement)//使用指定的初始容量和容量增量构造一个空的向量
代码示例
import java.util.Vector;
import java.util.Enumeration;public class VectorExample {public static void main(String[] args) {// 创建 VectorVector<String> vector = new Vector<>();// 添加元素vector.add("Apple");vector.add("Banana");vector.add("Orange");// 获取元素String firstElement = vector.get(0);System.out.println("First Element: " + firstElement);// 修改元素vector.set(1, "Grapes");// 删除元素vector.remove("Orange");// 获取 Vector 大小int size = vector.size();System.out.println("Size: " + size);// 判断是否包含某个元素boolean containsBanana = vector.contains("Banana");System.out.println("Contains Banana: " + containsBanana);// 遍历 Vector(使用增强 for 循环)System.out.println("Iterating using enhanced for loop:");for (String fruit : vector) {System.out.println(fruit);}// 遍历 Vector(使用 Enumeration)System.out.println("Iterating using Enumeration:");Enumeration<String> enumeration = vector.elements();while (enumeration.hasMoreElements()) {String fruit = enumeration.nextElement();System.out.println(fruit);}// 转换为数组Object[] array = vector.toArray();System.out.println("Array: " + java.util.Arrays.toString(array));// 清空 Vectorvector.clear();// 判断是否为空boolean isEmpty = vector.isEmpty();System.out.println("Is Empty: " + isEmpty);}
}
2.4、区别
ArrayList | LinkedList | Vector | |
---|---|---|---|
实现方法 | 动态数组 | 双向链表 | 动态数组 |
线程是否安全 | 非线程安全 | 非线程安全 | 线程安全 |
适用场景 | 适用于需要频繁随机访问元素,而且不涉及多线程的场景。 | 适用于需要频繁插入和删除元素的场景,但不涉及多线程。 | 由于线程安全性带来的性能损失,不推荐在单线程环境下使用。 |
(1)ArrayList:底层数据结构是数组,查询快,增删慢,线程不安全,效率高,可以存储重复元素
(2)LinkedList 底层数据结构是链表,查询慢,增删快,线程不安全,效率高,可以存储重复元素
(3)Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率低,可以存储重复元素
在多线程环境下,如果需要线程安全,可以考虑使用 Collections.synchronizedList()
来包装 ArrayList
或 LinkedList
。
三、Set集合
Set
是 Java 集合框架中的一种接口,它代表无序、不允许重复元素的集合。需要实现类来进行操作。
特点:
- 不允许有重复的值
- 没有索引(不能使用普通for循环进行遍历)
3.1、HashSet集合
特点:
- 底层结构为“哈希表”
- 集合对读写顺序不做保证
- 允许有null值
- Set集合内容不允许重复
- 没有索引
HashSet 类位于 java.util 包中,使用前需要引入它,语法格式如下:
import java.util.HashSet; // 引入 HashSet 类
以下实例我们创建一个 HashSet 对象 sites,用于保存字符串元素:
HashSet<String> sites = new HashSet<String>();
代码示例:
import java.util.HashSet;/*** @BelongsProject: Test* @BelongsPackage: PACKAGE_NAME* @Author: Jorya* @CreateTime: 2023-11-22 16:20* @Description: TODO* @Version: 1.0*/
public class HashSetTest {public static void main(String[] args) {HashSet<String> sites = new HashSet<String>();sites.add("Google");sites.add("Jorya");sites.add("Taobao");sites.add("Zhihu");sites.add("Jorya"); // 重复的元素不会被添加System.out.println(sites.size());//计算元素数量System.out.println(sites);System.out.println(sites.contains("Taobao"));//truesites.remove("Taobao"); // 删除元素,删除成功返回 true,否则为 falsesites.clear();//删除集合所有元素}
}
3.2、LinkedHashSet集合
特点:
-
LinkedHashSet是哈希表和链表实现的Set接口,具有可预测的读写顺序。
-
有链表来保证元素有序
-
有哈希表来保证元素的唯一性
import java.util.HashSet;
public class LinkedHashSetTest {public static void main(String[] args) {LinkedHashSet<String> sites = new LinkedHashSet<String>();sites.add("Google");sites.add("Jorya");sites.add("Taobao");sites.add("Zhihu");sites.add("Jorya"); // 重复的元素不会被添加System.out.println(sites);}
}
3.3、TreeSet集合
特点:
- 集合底层是二叉树
- TreeSet集合中的元素,和TreeMap集合中的key部分一样
- 元素是无序不可重复、可以按照大小顺序自动排序
四、Map集合
Map键值对集合,集合中按Key-Value键值对方式存储
4.1、HashMap
特点:
- 无序,key不可重复
- key,value都可以为null, key为null的时候存储在HashMap的第一个位置
- 当key相同时,新的value会覆盖旧的value
4.2、TreeMap
特点:
- 底层是红黑树 ,无序 key不可重复
- 存储映射的关系过程中,需要key使用 自然排序或传递比较器(比较器根据key进行排序)
- key不能为null ,value可以为null
- 添加相同 key 时,新的value会覆盖旧的value(底层:自然排序的compareTo() 或比较器compare()
- 方法返回值为0,调用t.setValue(value),实现新的值覆盖旧的值)
4.3、HashTable
特点:
- 无序、key不可重复
- key,value不可为空