Java核心技术 卷1-总结-11

Java核心技术 卷1-总结-11

  • Java 集合框架
    • 将集合的接口与实现分离
    • Collection接口
    • 迭代器
    • 泛型实用方法
    • 集合框架中的接口

Java 集合框架

将集合的接口与实现分离

Java集合类库将接口(interface)与实现(implementation)分离。

例如队列(queue):队列接口指出可以在队列的尾部添加元素,在队列的头部删除元素,并且可以查找队列中元素的个数。当需要收集对象,并按照“先进先出”的规则检索对象时就可以使用队列。队列接口的最简形式类似下面这样:

public interface Queue<E> {// a simplifiedform of the interface in the standard library 
	void add(E element);
	E remove();
	int size();
}

这个接口并没有说明队列是如何实现的。队列通常有两种实现方式:一种是使用循环数组;另一种是使用链表。
在这里插入图片描述
每一个实现都可以通过一个实现了Queue接口的类表示。

public class CircularArrayQueue<E> implements Queue<E>  { // not an actual library class 
	private int head;
	private int tail;
	
	CircularArrayQueue(int capacity) {...}
	public void add(E element) {...}
	public E remove() {...}
	public int size() {...}
	private E[] elements;
}

public class LinkedListQueue<E> implements Queue<E> { // not an actual library class 
	private Link head;
	private Link tail;
	
	LinkedListQueue() {...}
	public void add(E element) {...}
	public E remove() {...}
	public int size() {...}

CircularArrayQueue和LinkedListQueue类。只是以这些类作为示例,实际上Java中并没有这两个类。如果需要一个循环数组队列,就可以使用ArrayDeque类。如果需要一个链表队列,就直接使用LinkedList 类,这个类实现了Queue接口。

当在程序中使用队列时,一旦构建了集合就不需要知道究竟使用了哪种实现。因此,只有在构建集合对象时,使用具体的类才有意义。可以使用接口类型存放集合的引用。

Queue<Customer> expressLane = new CircularArrayQueue<>(100);
expressLane.add(new Customer("Harry"));

利用这种方式,一旦改变了想法,可以轻松地使用另外一种不同的实现。只需要对程序调用构造器的地方=做出修改,如果觉得LinkedListQueue是个更好的选择,就可以将代码修改为:

Queue<Customer> expressLane = new LinkedListQueue<);
expressLane.add(new Customer("Harry"));

循环数组要比链表更高效,因此多数人优先选择循环数组。然而,通常这样做也需要付出一定的代价。循环数组是一个有界集合,即容量有限。如果程序中要收集的对象数量没有上限,就最好使用链表来实现。

Collection接口

在Java类库中,集合类的基本接口是Collection接口。这个接口有两个基本方法:

public interface Collection<E> {
	boolean add(E element);
	Iterator<E> iterator();
}

add方法用于向集合中添加元素。如果添加元素确实改变了集合就返回true,如果集合没有发生变化就返回false。例如,如果试图向集中添加一个对象,而这个对象在集中已经存在,这个添加请求就没有生效,因为集合中不允许有重复的对象。

iterator方法用于返回一个实现了Iterator接口的对象。可以使用这个迭代器对象依次访问集合中的元素。

迭代器

Iterator接口包含4个方法:

public interface Iterator<E> { 
	E next();
	boolean hasNext();
	void remove();
	default void forEachRemaining(Consumer<?super E> action);
}

通过反复调用 next方法,可以逐个访问集合中的每个元素。但是,如果到达了集合的末尾,next方法将抛出一个NoSuchElementException。因此,需要在调用 next 之前调用 hasNext 方法。如果想要查看集合中的所有元素,就请求一个迭代器,并在hasNext返回true 时反复地调用next方法。 例如:

Collection<String> c = ...;
Iterator<String>iter = c.iterator();
while (iter.hasNext)) {
	String element = iter.next();
	do something with element 
}

用“for each”循环可以更加简练地表示同样的循环操作:

for (String element : c) {
	do something with element 
}

编译器将"for each"循环翻译为带有迭代器的循环。"for each"循环可以与任何实现了Iterable接口的对象一起工作,这个接口只包含一个抽象方法:

public interface Iterable<E> {
	Iterator<E> iterator();
}

Collection接口扩展了Iterable接口。因此,对于标准类库中的任何集合都可以使用"for each”循环。

元素被访问的顺序取决于集合类型。如果对ArrayList进行迭代,迭代器将从索引0开始,每迭代一次,索引值加1。然而,如果访问HashSet中的元素,每个元素将会按照某种随机的次序出现。 虽然可以确定在迭代过程中能够遍历到集合中的所有元素,但却无法预知元素被访问的次序。

Iterator接口的remove方法将会删除上次调用next方法时返回的元素。 在大多数情况下,在决定删除某个元素之前应该先看一下这个元素是很具有实际意义的。然而,如果想要删除指定位置上的元素,仍然需要越过这个元素。例如,下面是如何删除字符串集合中第一个元素的方法:
在这里插入图片描述

Iterator<String> it = c.iterator();
it.next();// skip over the first element 
it.remove();// now remove it

注意:对next方法和remove方法的调用具有互相依赖性。如果调用remove之前没有调用next将是不合法的。如果这样做,将会抛出一个IllegalStateException异常。如果想删除两个相邻的元素,不能直接地这样调用:

it.remove();
it.remove(); // Error!

相反地,必须先调用next越过将要删除的元素。

it.remove();
it.next();
it.remove();// OK 

泛型实用方法

由于Collection与Iterator都是泛型接口,可以编写操作任何集合类型的实用方法。例如,下面是一个检测任意集合是否包含指定元素的泛型方法:

public static <E> boolean contains(Collection<E> c, Object obj) {
	for (E element : c) {
		if (element.equals(obj)) {
			return true;
		}
	}
	return false;
}

这些实用方法中的某些方法非常有用,这样,类库的使用者就不必自己重新构建这些方法了。contains就是这样一个实用方法。

Collection接口声明了很多有用的方法,所有的实现类都必须提供这些方法, 下面列举了其中的一部分:

int size()
boolean isEmpty()
boolean contains(Object obj)
boolean containsAll(Collection<?> c)
boolean equals(Object other)
boolean addAll(Collection<?extends E> from)
boolean remove(Object obj)
boolean removeAll(Collection<?> c)
void clear()
boolean retainAll(Collection<?> c)
Object[] toArray() 
<T> T[] toArray(T[] arrayToFill)

如果实现Collection接口的每一个类都要提供如此多的例行方法将是一件很烦人的事情。为了能够让实现者更容易地实现这个接口,Java类库提供了一个类AbstractCollection,它将基础方法size和 iterator抽象化了,但是在此提供了例行方法。例如:

public abstract class AbstractCollection<E>implements Collection<E> {
	public abstract Iterator<E> iterator();
	
	public boolean contains(Object obj) {
		for (E element : this) { // calls iterator()
			if (element.equals(obj)) {
				return = true;
			}
		}
		return false;
}

如果子类有更加有效的方式实现contains方法,也可以由子类提供,没有什么限制。

另外,还有一个很有用的方法:

default boolean removeIf(Predicate<? super E> filter)

这个方法用于删除满足某个条件的元素。

集合框架中的接口

集合有两个基本接口:CollectionMap。可以用以下方法在集合中插人元素:

boolean add(E element)

由于映射包含键/值对,所以要用put方法来插入:

V put(K key, V value)

要从集合读取元素,可以用迭代器访问元素。从映射中读取值则要使用get方法:

V get(K key)

List是一个有序集合(ordered collection)。元素会增加到容器中的特定位置。可以采用两种方式访问元素:使用迭代器访问,或者使用一个整数索引来访问。 后一种方法称为随机访问(random access),因为这样可以按任意顺序访问元素。与之不同,使用迭代器访问时,必须顺序地访问元素。

List接口定义了多个用于随机访问的方法:

void add(int index, E element)
void remove(int index)
E get(int index)
E set(int index, E element)

Set接口等同于Collection接口,不过其方法的行为有更严谨的定义。集(set)的add方法不允许增加重复的元素。 要适当地定义集的 equals 方法:只要两个集包含同样的元素就认为是相等的,而不要求这些元素有同样的顺序。hashCode方法的定义要保证包含相同元素的两个集会得到相同的散列码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/13617.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小航助学答题系统编程等级考试scratch一级真题2023年3月(含题库答题软件账号)

青少年编程等级考试scratch真题答题考试系统请点击 电子学会-全国青少年编程等级考试真题Scratch一级&#xff08;2019年3月&#xff09;在线答题_程序猿下山的博客-CSDN博客_小航答题助手 1.下列说法不正确的是&#xff1f;&#xff08; &#xff09; A.可以从声音库中随机…

使用buildroot编译完整系统【IMX6ULLPRO】

目录 构建 IMX6ULL Pro 版的根文件系统 编译系统 ​编辑 镜像文件 构建 IMX6ULL Pro 版的根文件系统 配置文件说明 编译系统 下面以 100ask_imx6ull_pro_ddr512m_systemV_qt5_defconfig 配置文 件为例&#xff0c;在 ubuntu 终端上说明 Buildroot 的配置过程&#x…

抖音数字人主播app

抖音数字人主播app是指一款利用计算机生成的虚拟数字人&#xff0c;在抖音平台上进行实时音视频传输和互动的应用程序。该软件可以让用户创建自己的虚拟数字人&#xff0c;并在抖音平台上进行实时互动和交流。 抖音数字人主播app通常需要包含以下功能&#xff1a; 3D建…

前端学习之路 来自前端方向学生的总结

恭喜您&#xff01;您发现了宝藏&#xff01; 我发现很多小伙伴&#xff0c;对于前端感兴趣&#xff0c;也很想去学好&#xff0c;但是却无从下手&#xff0c;不知道如何去学习。作为一名现处于大三即将大四的学生&#xff0c;借此机会来分享分享我的前端学习之路&#xff01;…

Visual Instruction Tuning: 用LLaVA近似多模态GPT-4

©Paperweekly 原创 作者 | Chunyuan Li 使用 GPT-4 进行视觉指令学习&#xff01;Visual Instruction Tuning with GPT-4! ▲ Generated by GLIGEN (https://gligen.github.io/): A cute lava llama and glasses 我们分享了 LLaVA (Language-and-Vision Assistant)&#…

设计模式--单例模式

目录 介绍 单例模式的八种实现方式 饿汉式(静态常量) 优缺点说明: 饿汉式(静态代码块) 优缺点说明 懒汉式(线程不安全) 优缺点说明 懒汉式(线程安全 同步方法) 优缺点说明 懒汉式(线程安全 同步代码块) 优缺点说明 双重检查 优缺点说明 静态内部类 优缺点说明 …

打怪升级之FPGA组成原理(LE部分)

FPGA芯片逻辑单元的原理 不论你使用哪一款FPGA芯片&#xff0c;其核心可编程逻辑单元都是从一段内存种按顺序读取执行并执行的过程。具体来说&#xff0c;FOGA芯片内部包括可编程逻辑块(LAB)、可配置输入输出单元(IOE)、时钟管理模块、嵌入式RAM(BRAN&#xff0c;在Cyclone IV…

PNAS: 这些病毒是原生动物基因组中的偷渡者

在对复杂单细胞微生物进行大规模研究时&#xff0c;奥地利因斯布鲁克大学生态学系的Christopher Bellas博士、Marie-Sophie Plakolb和Ruben Sommaruga教授发现了一个意外情况&#xff1a;微生物的基因组中找到超过30,000种先前未知的病毒DNA。这种“隐藏”的DNA可能允许宿主细胞…

字节跳动正式开源分布式训练调度框架 Primus

动手点关注 干货不迷路 项目地址&#xff1a;https://github.com/bytedance/primus 随着机器学习的发展&#xff0c;模型及训练模型所需的数据量越来越大&#xff0c;也都趋向于通过分布式训练实现。而算法工程师通常需要对这些分布式框架涉及到的底层文件存储和调度系统有较深…

基于 多态 的职工管理系统(Staff Management System)

目录 一、管理系统需求 作用&#xff1a;管理公司内所有员工的信息 分类&#xff1a;要显示每位员工的编号、姓名、岗位与职责 具体实现的功能&#xff1a; 二、创建管理 类 三、各个接口函数 1、菜单展示功能 2、 选择功能 3、创建员工功能 ①普通员工employee ②经理…

怎么批量把heic格式转化jpg,3招快速解决

怎么批量把heic格式转化jpg&#xff1f;heic是一种新型的图像文件格式&#xff0c;是苹果独家搞出来的一个图片格式&#xff0c;它小巧玲珑&#xff0c;而且图像质量超好&#xff0c;专门给iOS11系统用户用的。这种格式比老JPEG更厉害&#xff0c;不仅图片质量好&#xff0c;而…

【网络原理】应用层协议 与 传输层协议

✨个人主页&#xff1a;bit me&#x1f447; ✨当前专栏&#xff1a;Java EE初阶&#x1f447; 目 录 &#x1f3c9;一. 应用层协议⚾️二. 传输层协议&#x1f452;1. UDP 协议&#x1f302;2. 校验和&#x1f453;3. TCP 协议 &#x1f3c9;一. 应用层协议 我们自己写的应用…

Bitmap 实现当前在线用户数量

Bitmap是什么&#xff1f; Bitmap是Redis中的一种数据结构&#xff0c;它是一个类似于位数组的数据结构&#xff0c;用于处理位数据。在Redis中&#xff0c;Bitmap是使用字符串来存储的&#xff0c;一个Byte可以存储8个二进制位&#xff0c;一个字符串可以存储232个二进制位&a…

【CocosCreator入门】CocosCreator组件 | ProgressBar(进度条)组件

Cocos Creator 是一款流行的游戏开发引擎&#xff0c;具有丰富的组件和工具&#xff0c;其中的ProgressBar组件是一种用于实现进度条效果的重要组件。它可以让我们在游戏中展示各种进度条效果&#xff0c;例如加载进度条、血条等。 目录 一、组件介绍 二、组件属性 三、脚本…

12. 图的进阶

12. 图的进阶 12.1 有向图 在实际生活中&#xff0c;很多应用相关的图都是有方向性的&#xff0c;最直观的就是网络&#xff0c;可以从A页面通过链接跳转到B页面&#xff0c;那么a和b连接的方向是a->b,但不能说是b->a,此时我们就需要使用有向图来解决这一类问题&#x…

【jvm系列-09】垃圾回收底层原理和算法以及JProfiler的基本使用

JVM系列整体栏目 内容链接地址【一】初识虚拟机与java虚拟机https://blog.csdn.net/zhenghuishengq/article/details/129544460【二】jvm的类加载子系统以及jclasslib的基本使用https://blog.csdn.net/zhenghuishengq/article/details/129610963【三】运行时私有区域之虚拟机栈…

为什么许多人吐槽C++11,那些语法值得我们学习呢?

致前行的人&#xff1a; 人生像攀登一座山&#xff0c;而找寻出路&#xff0c;却是一种学习的过程&#xff0c;我们应当在这过程中&#xff0c;学习稳定冷静&#xff0c;学习如何从慌乱中找到生机。 目录 1.C11简介 2.统一的列表初始化 2.1 &#xff5b;&#xff5d;初始化 …

git 常用命令及遇到问题

自己没事&#xff0c;把git常用命令做个记录总结。方便自己和初学者查看&#xff0c;本文针对初学者&#xff0c;如果你已经是工作多年高手&#xff0c;请跳过。 git的几个区认识&#xff0c;分别为工作区&#xff0c;缓存区&#xff0c;版本库。 工作区&#xff1a;包含.git…

【Unity VR开发】结合VRTK4.0:添加碰撞忽略器

语录&#xff1a; 最远的旅行&#xff0c;是从自己的身体到自己的心&#xff0c;是从一个人的心到另一个人的心。坚强不是面对悲伤不流一滴泪&#xff0c;而是擦干眼泪后微笑面对以后的生活。 前言&#xff1a; 模块化提供了一种允许两个或者多个对象忽略彼此碰撞的方法&#x…

揭秘移动云大会展区前沿科技

2023年4月25日-26日 我们苏州金鸡湖国际会议中心见&#xff01; 1场重磅主论坛、10场分论坛、2600㎡展区 数字中国新未来 尽在2023移动云大会 2023移动云大会设有中国移动和合作伙伴两大展区&#xff0c;联合40余家优质合作伙伴&#xff0c;全方位展示移动云在自主能力、行…