3.2 表 ADT

处理形如 A0, A1, A2, ……, AN-1 的一般的表。我们称这个表大小为N。将大小为0的特殊表称为空表

对于除空表以外的任何表,称 Ai-1 前驱 Ai,Ai 后继 Ai-1

表ADT上进行操作有:

printList 打印整个表

makeEmpty 清空整个表

find 返回某一项首次出现的位置

insert 从表的某个位置插入元素

remove 从表的某个位置删除元素

findKth 返回某个位置上的元素

数组实现表

对表的操作都可以通过数组来实现。虽然数组由固定容量创建,但是需要的时候可以使用双倍的容量再创建一个数组。

在这种实现下,printList花费时间为 O(N),findKth 花费时间是常数。但是插入和删除也会花费O(N)的时间,因为在 0 位置插入或删除,会将数组元素整体后移或前移。平均下来都需要移动表的一半的元素。

表的另一种实现方式:链表

链表由一系列节点组成,每个节点均含有表元素和到包含该元素后继的节点的链。链只有后继元素的信息,并没有前驱节点的信息。

和数组实现一样,printList 花费时间为 O(N),findKth(i) 花费时间 O(i)。remove 方法可以通过修改一个 next 引用来实现,insert 则需要改变两个next 引用。

实际中更为常用的是双链表。

3.3 Java Collections API 中的表

Collection接口
  1. public interface Collection<E> extends Iterable<E> {
  2. int size();
  3. boolean isEmpty();
  4. void clear();
  5. boolean contains(Object o);
  6. boolean add(E e);
  7. boolean remove(E e);
  8. Iterator<E> iterator();
  9. }

Collection 实现了 Iterable 接口,因此可以对其使用增强 for 循环

  1. public static <E> void enhanceFor(Collection<E> coll) {
  2. for (E e : coll) {
  3. //对每一个元素操作
  4. }
  5. }
Iterator接口
  1. public interface Iterator<E> {
  2. boolean hasNext();
  3. E next();
  4. default void remove() {
  5. throw new UnsupportedOperationException("remove");
  6. }

通过 iterato r方法,每个集合都可以创建并返回一个实现 Iterator 的对象

next 方法返回下一项,hasNext 方法返回是否存在下一项。编译器遇见一个用于 Iterable 对象的增强 for 循环时,它用 iterator 方法的方法来替代增强 for 循环。如下

  1. public static <E> void iter(Collection<E> coll) {
  2. Iterator<E> iter = coll.iterator();
  3. while (iter.hasNext()) {
  4. E item = iter.next();
  5. //对每一个元素操作
  6. }
  7. }

remove 方法将删除由 next 最新返回的元素。Collection 的 remove 方法必须先找出要被删除的项。而 Iterator 的 remove 方法要删除的就是当前迭代器所在位置的元素。

当直接使用 Iterator 而不是通过一个增强 for 循环间接使用时,如果对正在被迭代的集合进行结构上的改变( 即对该集合使用 add 、remove 或 clear 方法), 那么迭代器就不再合法。

只有在需要立即使用一个迭代器的时候,才应该获取迭代器。如果迭代器调用了自己的 remove 方法,那么这个迭代器依然合法,且自己的 remove 方法也只应该被调用一次。

List 接口、ArrayList 类和 LinkedList 类

List 接口继承了 Collection 接口

  1. public interface List<E> extends Collection<E> {
  2. E get(int index);
  3. E set(int index, E element);
  4. void add(int index, E element);
  5. E remove(int index);
  6. }

listIterator 方法将产生比通常认为还要复杂的迭代器。

ArrayList 类提供了 List ADT 的一种可增长数组的实现,对 get 和 set 的调用花费常数时间。缺点是新项插入和现有项删除代价高。LinkedList 类提供的是 List ADT 的双链表实现,优点是新项的插入和删除都是常数时间的操作,这里假设变动项的位置是已知的。LinkedList 对 get 的调用代价高。

不论 ArrayList 或是 LinkedList 作为参数被传递,makeList1 的运行时间都是 O(N) ,因为每次对add调用都是在表的末端。从而均花费常数时间(忽略ArrayList扩容的时间)

  1. public static void makeList1(List<Integer> lst, int N) {
  2. lst.clear();
  3. for (int i = 0; i < N; i++) {
  4. lst.add(i);
  5. }
  6. }

对于 LinkedList ,makeList2 的运行时间还是 O(N),而对于 ArrayList 运行时间是 O(N2),因为在 ArrayList 中在前端添加是一个 O(N) 操作。

  1. public static void makeList2(List<Integer> lst, int N) {
  2. lst.clear();
  3. for (int i = 0; i < N; i++) {
  4. lst.add(0,i);
  5. }
  6. }
ListIterator 类

扩展了 List 的 Iterator 的功能。方法 previous 和 hasPrevious 能够使表从后向前遍历

  1. public interface ListIterator<E> extends Iterator<E> {
  2. boolean hasPrevious();
  3. E previous();
  4. }

add 方法将一个新的项以当前位置放入表中,set 方法改变被迭代器看到的最后一个值,对于 LinkedList 来说很方便

3.2 表 ADT -3.3 Java Collection API 中的表的更多相关文章

  1. Java基础学习总结(67)——Java接口API中使用数组的缺陷

    如果你发现在一个接口使用有如下定义方法: public String[] getParameters(); 那么你应该认真反思.数组不仅仅老式,而且我们有合理的理由避免暴露它们.在这篇文章中,我将试图 ...

  2. 利用socket模拟http的混合表单上传(在一个请求中提交表单并上传多个文件)

           在非常多企业级应用中,我们都没法直接通过开发语言sdk包封装的http工具来模拟http复合表单(multipart/form-data),特别是在跨语言跨平台的编程过程中.事实上实现方 ...

  3. Java Collection API

    在 Java2中,有一套设计优良的接口和类组成了Java集合框架Collection,使程序员操作成批的数据或对象元素极为方便.这些接口和类有很多对抽象数据类型操作的API,而这是我们常用的且在数据结 ...

  4. Java Hour 67 Java Collection API

    本文不是一个大而全的讲述Java Coleection 相关的APi, 而是笔者认为哪些是一个初学者所能够而且必须确切知道的知识点. Collection 一脉 这里有我们比较常用的List<E ...

  5. Java Collection集合中的iterator方法

    Iterator接口的概述 /** * java.util.Iterator接口:选代器(对集合进行遍历) * 有两个常用的方法 * boolean hasNext() * 如果仍有元素可以迭代,则返 ...

  6. 用java查询HBase中某表的一批数据

    java代码如下: package db.query; import java.io.IOException; import org.apache.hadoop.conf.Configuration; ...

  7. 再说表单验证,在Web Api中使用ModelState进行接口参数验证

    写在前面 上篇文章中说到了表单验证的问题,然后尝试了一下用扩展方法实现链式编程,评论区大家讨论的非常激烈也推荐了一些很强大的验证插件.其中一位园友提到了说可以使用MVC的ModelState,因为之前 ...

  8. Java Concurrency API 中的 Lock 接口(Lock interface) 是什么?对比同步它有什么优势?

    Lock 接口比同步方法和同步块提供了更具扩展性的锁操作. 他们允许更灵活的结构,可以具有完全不同的性质,并且可以支持多个相关类的 条件对象. 它的优势有: 可以使锁更公平 可以使线程在等待锁的时候响 ...

  9. Java设置的读书笔记和集合框架Collection API

    一个.CollectionAPI 集合是一系列对象的聚集(Collection). 集合在程序设计中是一种重要的数据接口.Java中提供了有关集合的类库称为CollectionAPI. 集合实际上是用 ...

随机推荐

  1. 《C++ primer plus》第3章练习题

    注:有的题设条件自己改动了一下,比如英寸英尺改成米和厘米,部分题目自己加了点额外要求. 1.要求用户输入身高(m),用下划线提示用户输入,将身高转化成"米"加"厘米&qu ...

  2. Arduino的外部中断

    Arduino的中断函数格式为attachInterrupt(interrput,function,mode). attachInterrupt函数用于设置外部中断,有3个参数,interrput表示 ...

  3. win10下安装使用Docker:Docker for Windows

    一.下载win10下安装docker和桌面管理的工具: 下载地址:Docker for Windows 安装软件学习地址:https://www.runoob.com/docker/docker-tu ...

  4. 极客 Play 玩 Terminal——GitHub 热点速览 Vol.40

    作者:HelloGitHub-小鱼干 多少人以为暗黑的终端便是一名程序员的工作台,其实上,终端可以不只是一个输入 command 的界面,也可以是本周特推 kb 一样,面向极客的极简命令行知识库管理器 ...

  5. 执行新增和修改操作报错connection is read-only. Queries leading to data modification are not allowed

    出现这个问题的原因是默认事务只有只读权限,因此要添加下面的每一个add*,del*,update*等等. 分别给予访问数据库的权限. 方法名的前缀有该关键字设置了read-only=true,将其改为 ...

  6. Oracle报错>记录被另外一个用户锁定

    原因 当一个用户对数据进行修改时,若没有进行提交或者回滚,Oracle不允许其他用户修改该条数据,在这种情况下修改,就会出现:"记录被另外一个用户锁定"错误. 解决 查询用户.数据 ...

  7. 转一个veth的文章

    这篇写的很好,清晰明白,保存一下https://www.cnblogs.com/bakari/p/10613710.html

  8. rs232转rs485

    rs232转rs485 rs232转rs485 ZLAN9223E是上海卓岚科技开发的一款先进的无源RS232转RS485转换器.具有如下优点: 支持最高达230400bps的波特率.高波特率下供电能 ...

  9. 什么是C和C++标准——小白必看

    本文简要介绍编写C/C ++应用程序的领域,标准库的作用以及它是如何在各种操作系统中实现的. 我已经接触C++一段时间了,一开始就让我感到疑惑的是其内部结构:我所使用的内核函数和类从何而来? 谁发明了 ...

  10. 扫描仪扫描文件处理-ABBYY对扫描版PDF文字加黑加粗、去除背景漂白

    1. 设置ABBYY自动歪斜矫正: 2. 设置导出PDF参数: 3. PDF文字加黑加粗.去除背景漂白步骤:3.1 ABBYY - 打开扫描版PDF文档3.2 ABBYY - 编辑图像3.3 等级 - ...