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

news2024/12/23 16:29:55

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.coloradmin.cn/o/450685.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

把Windows装进内存条里,提前感受超越PCIe 6.0固态的顶级体验

这两年电脑内存条是越来越白菜价了&#xff0c;看到大伙儿慢慢富足起来的内存容量&#xff0c;小忆是由衷地感到高兴。 不过话说&#xff0c;动不动 32G、64G 内存你真能用得完吗&#xff1f;为了榨干大家真金白银买来的空闲内存价值。 咱这期整个骚操作——将 Windows 11 系统…

虚拟机安装linux系统centos(保姆级)

虚拟机安装linux系统centos 1.软硬件准备2.虚拟机准备1.打开VMware选择新建虚拟机2.典型安装与自定义安装3.虚拟机兼容性选择4.选择稍后安装操作系统5.操作系统的选择7.处理器与内存的分配8.网络连接类型的选择&#xff0c;网络连接类型一共有桥接、NAT、仅主机和不联网四种。9…

ArcMap气温数据插值处理

一、插值数据处理 1.先把气温excel在excel中另存为气温.csv&#xff08;网盘链接中有转好的csv文件&#xff09;&#xff0c;导入数据江苏.shp和jiangsustation.shp 和气温.csv 数据在文末百度网盘链接中 2.打开jiangsustation.shp的属性表&#xff0c;连接与字段-连接-连接的…

RabbitMQ的五种工作模式

目录 前言介绍 &#xff08;1&#xff09;启动RabbitMQ &#xff08;2&#xff09;账户管理 一、简单模式 &#xff08;1&#xff09;概念 &#xff08;2&#xff09;生产者代码 &#xff08;3&#xff09;消费者代码 二、工作队列模式 &#xff08;1&#xff09;概念…

LLVM编译流程

一、LLVM 1.1 LLVM概述 LLVM是构架编译器(compiler)的框架系统,以C编写而成,用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time),对开发者保持开放,并兼容已有脚本.LLVM计划启动于2000年,最初由美国…

Dynamics 365 开启 Modern advanced find后如何创建个人视图

本篇是自己在新的环境被新的高级查找晃的没找到如何创建个人视图而发。如何在老的高级查找页面创建这里就不表了。 D365 2022 Wav1后有了新的feature叫Modern advanced find&#xff0c;开启方式如下&#xff0c;进Power Platform的管理中心&#xff0c;找到你对应的环境&#…

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

Java核心技术 卷1-总结-6 接口示例接口与回调Comparator接口对象克隆 lambda表达式为什么引入lambda表达式lambda表达式的语法 接口示例 接口与回调 回调&#xff08;callback&#xff09;是一种常见的程序设计模式。在这种模式中&#xff0c;可以指出某个特定事件发生时应该…

珍藏多年的MySQL函数大全笔记,掌握数据库真不难

做程序员的谁会离得开数据库呢&#xff1f;今天就来分享一下我整理的MySQL的常用函数&#xff0c;基本上囊括了平时要用的函数&#xff0c;它们已经陪我走过了不少年头了&#xff0c;风里来雨里去&#xff0c;缝缝补补又几年&#xff0c;希望能帮到你们&#xff01; 如果数据库…

短视频app开发:如何实现视频直播功能

短视频源码的实现 在短视频app开发中&#xff0c;实现视频直播功能需要借助短视频源码。短视频源码可以提供一个完整的视频直播功能模块&#xff0c;包括视频采集、编码、推流等。因此&#xff0c;我们可以选择一些开源的短视频源码&#xff0c;例如LFLiveKit、ijkplayer等&am…

Nacos简介 安装 配置

简介 什么是注册中心 注册中心在微服务项目中扮演着非常重要的角色&#xff0c;是微服务架构中的纽带&#xff0c;类似于通讯录&#xff0c;它记录了服务和服务地址的映射关系。在分布式架构中&#xff0c;服务会注册到这里&#xff0c;当服务需要调用其它服务时&#xff0c;…

RHCE(六)

目录 1.编写脚本for1.sh,使用for循环创建20账户&#xff0c;账户名前缀由用户从键盘输入&#xff0c;账户初始密码由用户输入&#xff0c;例如: test1、test2、test3、.....、 test10 &#xff08;1&#xff09;编写脚本 &#xff08;2&#xff09;运行脚本 &#xff08;3&…

机器学习——主成分分析法(PCA)概念公式及应用python实现

机器学习——主成分分析法&#xff08;PCA&#xff09; 文章目录 机器学习——主成分分析法&#xff08;PCA&#xff09;一、主成分分析的概念二、主成分分析的步骤三、主成分分析PCA的简单实现四、手写体识别数字降维 一、主成分分析的概念 主成分分析&#xff08;PCA&#x…

华为OD机试真题(Java),分班(100%通过+复盘思路)

一、题目描述 幼儿园两个班的小朋友在排队时混在了一起&#xff0c;每位小朋友都知道自己是否与前面一位小朋友是否同班&#xff0c;请你帮忙把同班的小朋友找出来。 小朋友的编号为整数&#xff0c;与前一位小朋友同班用Y表示&#xff0c;不同班用N表示。 二、输入描述 输…

Android Jetpack - Navigation 组件:进行应用程序导航

一. Navigation 组件的介绍 1.1 什么是 Navigation 组件 Navigation 组件是一种 Android Jetpack 库&#xff0c;它可以帮助开发者轻松地实现应用程序中的导航功能。导航组件包含多个类和组件&#xff0c;包括导航图、目的地、导航控制器等&#xff0c;可以帮助我们管理应用程…

【Node.JS Web编程】记录从语法基础到网络框架的学习过程

文章目录 1. Node.JS 模块系统2. npm使用介绍3. 搭建第一个服务端应用4. GET / POST请求5. Web 前后端分离6. 使用Express框架搭建Web服务7. Request 和 Response8. 中间件9. 使用 Koa 框架搭建Web服务10. 使用 Egg 框架搭建Web服务11. egg 项目结构大全 注意&#xff1a;本次教…

【Linux】uptime命令详解平均负载

命令 ➜ ~ uptime 22:37 up 90 days, 21:45, 2 users, load averages: 2.91 3.46 3.81 具体含义 22:37&#xff1a;代表的是当前的系统时间&#xff0c;也即晚上10点37分。 up 90 days, 21:45&#xff1a;代表系统运行时间 2 users &#xff1a;当前两个用户 load averages: 2…

【Linux】命名管道使用示例-代码实现

文章目录 1 管道基础知识复习(可直接跳转代码实现)1.1 管道的读写规则1.2 管道的特点 2 命名管道2.1 命名管道本质2.2 创建命名管道2.2.1 在命令行创建:2.2.2 在程序中调用函数创建 2.3 命名管道和匿名管道的区别2.4 命名管道的打开规则 3 代码分解实现3.1 makefile书写3.1.1 测…

计算值组成原理 作业8

作业8 题量: 28 满分: 100 作答时间:04-20 09:40至04-26 23:59 100分 一. 单选题&#xff08;共14题&#xff0c;32分&#xff09; 1. (单选题, 2分)计算机硬件能直接执行的只有_____。 A. 算法语言B. 汇编语…

2023-04-22 学习记录--C/C++-数组

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、定义一维数组 ⭐️ &#xff08;一&#xff09;、初识 格式 &#x1f308;&#xff1a;数组元素类型 数组名[数组元素个数]…

Java每日一练(20230423)

目录 1. 数组元素统计 ※ 2. 杨辉三角 II &#x1f31f; 3. 二进制求和 &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 数组元素统计 定义一个长度为5的数组arr1&a…