Java的集合之Collection接口

本文深入解析Java集合类的原理和应用,包括List、Set、Queue和Map的不同特性及其实现方式,探讨它们如何帮助开发者高效地存储和操作大量对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为什么出现集合类?
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就要对对象进行存储,集合就是存储对象最常用的一种方式。
数组和集合类同是容器,有何不同?
数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储任意数据类型,集合只能存储对象。
集合类的特点:
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
Java集合类是一种特别有用的工具类,可用于存储数量不等的对象,并可以实现常用的数据结构,如栈、队列等。除此之外,Java集合还可用于保存具有映射关系的关联数组。Java集合大致可分为List、Set、Queue和Map四种体系,其中List代表有序、重复的集合;Set代表无序、不可重复的集合;而Map则代表具有映射关系的集合,Java5又增加了Queue体系集合,代表一种队列集合实现。
为了保存数量不确定的数据,以及保存具有映射关系的数据(也被称为关联数组), Java提供了集合类。集合类主要负责保存、盛装其他数据,因此集合类也被称为容器类,所有的集合类都位于 java.util包下。 集合类和数组不一样,数组元素既可以是基本类型的值,也可以是对象(实际上保存 的是对象的引用变量);而集合里只能保存对象(实际上只是保存对象的引用变量,但通常习惯上认为集合里保存的是对象)。 Java的集合类主要由两个接口派生而出: Collection和Map, Collection和Map是Java 集合框架的根接口,这两个接口又包含了一些子接口或实现类。
如下所示是 Java集合 简单结构图:
在这里插入图片描述
两大接口:Java 集合类主要由两个接口派生出来:
1、Collection
List:可存放重复对象,有序;Set:不能存放重复对象;Queue:队列;SortedSet:可对集合数据排序;
2、Map
SortedMap :可对集合数据排序
(1)List集合/接口(元素可以重复)
List是 Collection 子接口,是有序的集合,集合中每个元素都有对应的顺序序列。List 集合可使用重复元素,可以通过索引来访问指定位置的集合元素(顺序索引从 0 开始),List 集合默认按元素的添加顺序设置元素的索引,比如第一个元素的索引就是 0,好似数组。
示例代码(以ArrayList为例):

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class ListDemo {
	public static void main(String[] args) {
		List<Integer> l = new ArrayList<Integer>();
		l.add(12);
		l.add(24);
		l.add(36);
		l.add(23);
		l.add(37);
		System.out.println(l);
		ListIterator<Integer> it = l.listIterator();
		while (it.hasNext()) {
			System.out.println("正序:" + it.next());
		}
		System.out.println("==================================");
		// 使用向前迭代前必须将游标(指针)移动到后边!
		while (it.hasPrevious()) {
			System.out.println("逆序:" + it.previous());
		}
	}
}  

结果截图:
在这里插入图片描述
List 接口中常用类:
Vector:线程安全,但速度慢,已被 ArrayList 替代。 ArrayList:线程不安全,查询速度快。 LinkedList:链表结构,增删速度快。取出 List 集合中元素的方式: get(int index):通过脚标获取元素。 iterator():通过迭代方法获取迭代器对象。 ArrayList 和 Vector 类都是基于数组实现的 List 类,Vector 比较古老,被 ArrayList 取代了;ArrayList 是线程不安全的,而 Vector 是线程安全的,但是即使这样,也不推荐使用 Vector。因为 Collections 有方法可以得到线程安全的 ArrayList 对象; Collections 类::static List synchronizedList(List list) 返回指定列表支持的同步(线程安全的)列表。
(2)Set集合/接口(元素不可以重复)
Set 是 Collection 子接口; Set 和 Collection 基本上一样,一点除外:Set 无法记住添加的顺序,不允许包含重复的元素。 当试图添加两个相同元素进 Set 集合,添加操作失败,add()方法返回 false。 Set 判断两个对象是否相等用 equals,而不是使用==。 也就是说两个对象 equals 比较返回 true,Set 集合是不会接受这个两个对象的。常用子类:HashSet:散列存放;TreeSet:有序存放。
hashCode 方法对于 HashSet 的作用:
HashSet 类是 Set 接口最常用的实现类,采用 hash 算法存储数据,具有良好的存储和查找功能。散列存储:不记录添加顺序;排列顺序时,顺序有可能发生变化;线程不安全的,多个线程访问一个 HashSet 要使用同步代码;HashSet 集合元素值允许是 null,但是最多只能有一个;因为 Set 集合就不可以装重复的对象! hash(翻译为哈希,或散列)算法的功能:保证通过一个对象快速找到另一个对象;其算法价值体现在速度,可以保证查询快速执行;当从 HashSet 中访问元素时,HashSet 先计算该元素的 hashCode(也就是该对象的 hashCode 方法返回值),然后直接到该 HashCode 对应的位置取出该元素;在这里对象的 hashCode 就好比是数组里的索引,但是不是索引;
HashSet 元素添加
当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode()方法来得到该对象的 hashCode 值,判断已经存储在集合中的对象的 hashCode 值是否与添加的对象的 hashCode 值一致;若不一致,直接添加进去;若一致,再进行 equals 方法比较,equals 方法如果返回 true,表明对象已经添加进去了,就不会再添加新的对象了,否则添加进去;如果我们重写了 equals 方法,也要重写 hashCode 方法,反之亦然。 HashSet 集合判断两个元素相等的标准是两个对象通过 equals 方法比较相等,并且两个对象的 hashCode 方法返回值也相等。如果需要某个类的对象保存到 HashSet 集合中,覆写该类的 equals()和 hashCode()方法,应该尽量保证两个对象通过 equals 比较返回 true 时,他们的 hashCode 返回也相等。
示例代码1:

import java.util.HashSet;
import java.util.Iterator;

public class SetDemo {
	public static void main(String[] args) {
		HashSet<String> set = new HashSet<>();
		System.out.println("==========添加元素===========");	
		set.add("A");
		set.add("B");
		set.add("C");
		set.add("A");
		set.add(null);// 可以放入null,但只能放入一个null
		System.out.println(set.toString());
		System.out.println("==========移除元素===========");		
		set.remove("A");
		System.out.println(set.toString());
		System.out.println("==========迭代器遍历===========");		
		Iterator<String> iterator = set.iterator();
		while (iterator.hasNext()) {
			System.out.print(iterator.next() + ",");
		}
		System.out.println();
		System.out.println("==========获取元素个数===========");		
		System.out.println(set.size());
		System.out.println("==========是否包含某个元素===========");	
		System.out.println(set.contains("B"));
		System.out.println("==========清空元素===========");		
		set.clear();
		System.out.println(set.isEmpty());
	}
}

结果截图:
在这里插入图片描述
示例代码2:

public class PersonDemo {
	private String name;
	public PersonDemo(String name) {
		super();
		this.name = name;
	}
	@Override
	public String toString() {
		return "name=" + name;
	}
	// 没有重写hashcode和equals方法前,显示三次(一样的)。重写后,只剩下一个了!说明重写后方法起作用了,重复的输入不进去!
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		PersonDemo other = (PersonDemo) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
}

没有重写hashcode和equals方法前结果截图:显示三次(一样的)。
在这里插入图片描述
重写后结果截图,只剩下一个了!说明重写后方法起作用了,重复的输入不进去!
在这里插入图片描述
(3)Queue队列/接口
Queue:基本上,一个队列就是一个先入先出(FIFO)的数据结构;Queue接口与List、Set同一级别,都是继承了Collection接口。LinkedList实现了 Deque接口
示例代码:

import java.util.LinkedList;
import java.util.Queue;

public class QueueDemo {
	public static void main(String[] args) {
		Queue<String> queue = new LinkedList<String>();
		// 添加元素// add()和remove()方法在失败的时候会抛出异常(不推荐使用)
		queue.offer("同学A");
		queue.offer("同学B");
		queue.offer("同学C");
		System.out.println("======遍历队列======");
		for (String q : queue) {
			System.out.print(q + ",");
		}
		System.out.println();
		System.out.println("======poll返回第一个元素,并在队列中删除======");
		System.out.println("poll=" + queue.poll());
		System.out.println(queue);
		System.out.println("======element返回第一个元素======");
		System.out.println("element=" + queue.element());
		System.out.println(queue);
		System.out.println("======peek返回第一个元素======");
		System.out.println("peek=" + queue.peek());
		System.out.println(queue);
	}
}

结果截图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序yang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值