java集合——集合接口+迭代器接口

【0】README

0.1) 本文描述转自 core java volume 1, 源代码 diy 的, 旨在理解 java集合框架——集合接口+迭代器接口 的相关知识;
0.2) for full source code , please visit https://github.com/pacosonTang/core-java-volume/tree/master/chapter13


【1】将集合的接口与实现分离

1.1)java集合类库将 接口与实现分离。 我们看一下, 队列是如何分离的;
1.2)队列接口指出可以再队列的尾部添加元素, 在队列的头部删除元素, 并可以查找队列中元素的个数;

  • 1.2.1)一个队列接口的最小形式类似下面这样:
interface Queue<E>
{void add(E element);E remove();int size;
}
  • 1.2.2)队列通常有两种实现方式: 一种是使用循环数组, 另一种是使用链表;
    这里写图片描述
  • 1.2.3)每一个实现都可以通过一个实现了 Queue接口的类表示:
class CircularArrayQueue<E> implements Queue<E> // not an actual library class
{CircularArrayQueue(int capacity) {...}pubilc void add(E element) {...}public E remove() {...}public int size(){...}private E[] elements;private int head;private int tail;
}
class LinkedListQueue<E> implements Queue<E> // not an actual library class
{LinkedListQueue() {}pubilc void add(E element) {...}public E remove() {...}public int size(){...}private Link head;private Link tail;    
}

Annotation)

  • A1)如果需要使用循环数组队列: 可以使用 ArrayDeque 类;
  • A2)如果需要使用 一个链表队列: 就直接使用 LinkedList 类, 这个类实现了 Queue接口;

1.3)使用接口类型存放集合的引用:

Queue<Customer> expressLane = new CircularArrayQueue<>(100);
expressLane.add(new Customer("Harry"));
  • 1.3.1)只需要对程序的一个地方做出修改,即调用构造器的地方, 如果觉得LinkedListQueue是个更好的选择,将代码修改为:
Queue<Customer> expressLane = new LinkedListQueue<>(100);
expressLane.add(new Customer("Harry")); // nothing changed
  • 1.3.2)因为循环数组要比链表效率高,因此多数人优先选择循环数组;循环数组是一个有界集合, 即容量有限。如果程序中要收集的对象数量没有上限, 就最好使用链表来实现;
  • 1.3.3)在研究API文档时,发现另外一组名字为 Abstract开头的类: 如, AbstractQueue, 这些类是为类库实现者而设计的, 如果想要实现自己的队列类,会发现扩展AbstractQueue类要比实现Queue接口中的所有方法要轻松得多;

这里写图片描述


【2】java类库中的集合接口和迭代器接口

2.1)在java类库中, 集合类的基本接口是 Collection 接口,有两个基本方法:

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

对上述代码的分析(Analysis):

  • A1)add方法: 用于向集合添加元素,如果添加元素确实改变了集合就返回ture, 否则返回false;如,如果试图向集合中添加一个对象, 而这个对象在集合中已经存在, 这个添加请求就没有实效了,因为集合中不允许有重复的对象;
  • A2)iterator方法:该方法用于返回一个实现了 Iterator接口的对象 。 可以使用这个迭代器对象依次访问集合中的元素:

2.2)迭代器, Iterator接口包含3个方法:

public interface Iterator<E>
{E next();boolean hasNext();void remove();
}
  • 2.2.1)通过反复调用 next方法, 可以逐个访问集合中的每个元素。但是, 如果达到了集合的末尾,next方法将抛出一个 NoSuchElementException;因此,需要在 next之前调用 hasNext方法;
  • 2.2.2)看个荔枝:
Collection<String> c = ...; //集合
Iterator<String> iter = c.iterator(); //集合迭代器
while(iter.hasNext()) //判断集合中是否还有下一元素
{String element = iter.next();do sth with element
}

Attention)从Java SE 5.0 后, 可以使用for each循环表示上述操作:

for(String elements : c)
{do sth with element
}

这里写图片描述
对上述代码的分析(Analysis):

  • A1)编译器将简单地将 “for each”循环翻译为 带有迭代器的循环;
  • A2)for each循环可以与任何实现了 Iterator接口的对象一起工作,这个接口只包含一个方法:
public interface Iterable<E>
{Iterator<E> iterator();
}

Attention)Collection接口扩展了 Iterable 接口, 因此, 对于标准类库中的任何集合都可以使用 for each;

  • 2.2.3)元素被访问的顺序取决于集合类型

    • 2.2.3.1)如果对 ArrayList进行迭代, 迭代器将从索引0开始;
    • 2.2.3.2)如果访问 HashSet中的元素, 每个元素将会按照某种随机的次序出现;虽然可以确定在迭代过程中能够遍历到集合中的所有元素, 但却无法预知元素被访问的顺序;
      这里写图片描述
      Annotation)编程老手会注意到: Iterator接口的next 和 hasNext方法 与 Enumeration 接口的nextElement 和 hasMoreElements 方法的作用一样。 java集合类库的设计者可以选择使用Enumeration接口。但是, 它们不喜欢这个接口累赘的方法名, 于是引入了较短的方法名的新接口;
  • 2.2.4)java迭代器:应该将java迭代器认为是位于 两个元素之间, 当调用next 方法时, 迭代器就越过下一个元素, 并返回刚刚越过的那个元素的引用;

Annotation)有用的类推:可以将Iterator.next 和 InputStream.read 看做是等效的。从数据流中读取一个字节, 就会自动地消耗掉这个字节。下一次调用read将会消耗并返回输入的下一个字节。用同样的方式, 反复地调用next 就可以读取集合中所有元素了;

2.3)删除元素

  • 2.3.1)Iterator的remove方法 将会删除上次调用next方法时返回的 元素。在大多数情况下,在决定删除某个元素前应该先看一下这个元素是很具有实际意义的。然而, 如果想要删除指定位置上的元素, 仍然需要越过这个元素。
  • 2.3.2)看个荔枝(如何删除集合中第一个元素):
Iterator<String> it = c.iterator();
it.next(); // skip over the first element
it.remove(); // now remove it
  • 你要记住, 要删除某个元素, 你得要先越过这个元素;
  • 2.3.3)对next方法 和 remove方法的调用具有相互依赖性。 如果调用 remove 之前没有调用next 将是不合法的。 如果这样做, 会抛出一个 IllegalStateException 异常;
  • 2.3.4)看个荔枝: 如果想删除两个相邻元素, 不能直接这样调用:
it.remove();
it.remove(); //ERROR
正确的方法是:
it.remove();
it.next();
it.remove();

这里写图片描述
这里写图片描述

2.4)泛型使用方法
* 2.4.1)由于Collection 和 Iterator 都是泛型接口,可以编写操作任何集合类型的实用方法。看个荔枝:下面是一个检测任意寄贺卡是否包含指定元素的泛型方法:

public static<E> boolean contains(Collection<E> e, Object obj)
{for(E element : c)if(element.equals(obj))return true;return false;
}
  • 2.4.2)事实上, Collection接口声明了很多有用的方法, 所有的实现类都必须提供这些方法, 下面列举了部分:
int size()
boolean isEmpty()
boolean contains(Object obj)
boolean containsAll(Collection<?> c): 这个集合包含other 集合中的所有元素,则返回trueboolean equals(Object other)
boolean addAll(Collection<? extends E> from)
boolean remove(Object obj)
boolean removeAll(Collection<?> c)
void clear() :移除集合中的所有元素;
boolean retainAll(Collection<?> c) : 从集合中移除所有与 other 集合中的元素不同的元素。如果这个调用改变了集合,返回trueObject[] toArray(); : 返回这个集合的对象数组;
<T> T[] toArray(T[] arrtyToFill[]): 返回这个集合的对象数组。如果arrayToFill 数组足够大, 就将集合中的元素填入这个数组中。 剩余空间填补 null ; 否则, 分配一个新数组, 其成员类型与 arrayToFill 的成员类类型相同, 其长度等于集合的大小, 并添入集合元素;
  • 2.4.3)AbstractCollection:当然, 如果实现 Collection接口的每个类都要提供如此多的例行方法是一件很烦人的事情。为了能够让实现者更容易地实现这个接口,java类库提供了一个 类 AbstractCollection , 它将基础方法 size 和 iterator 抽象化了;
    (我的理解为: 抽象类AbstractCollection实现部分的例行方法, 其他可变的方法交给用户去实现)
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;}......
}

对以上代码的分析(Analysis):

  • A1)一个具体集合类可以扩展 AbstractCollection类了;
  • A2)现在要由具体的集合类提供 iterator 方法, 而 contains 方法已由 AbstractCollection超类提供了;

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

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

相关文章

snmp在php中的使用,在php中转换python代码以计算snmpvlan掩码的最佳方法

我有一些python代码&#xff0c;我想在一个100%的php代码中使用。你知道我怎么转换代码吗&#xff1f;&#xff1f;&#xff1f;我在转换代码时遇到问题&#xff0c;尤其是部分get bit和set bit。在位掩码通过snmp从交换机中读取&#xff0c;掩码表示交换机端口位于定义的vlan中…

java ssl发送邮件_通过SSL发送的Java邮件

java ssl发送邮件抽象 本博客的目的是演示如何使用Java Mail通过具有SSL连接的SMTP服务器发送电子邮件。 免责声明 这篇文章仅供参考。 在使用所提供的任何信息之前&#xff0c;请认真思考。 从中学到东西&#xff0c;但最终自己做出决定&#xff0c;风险自负。 要求 我使用以…

java集合—— 链表(java中的所有链表都是双向链表)

【0】README 0.1&#xff09; 本文描述转自 core java volume 1&#xff0c; 源代码 diy 的&#xff0c; 旨在理解 java集合—— 链表&#xff08;java中的所有链表都是双向链表&#xff09; 的相关知识&#xff1b; 0.2&#xff09; for full source code , please visit ht…

使用matlab内存不足,Matlab内存不足问题(Out of memory)

今天遇到过这个错误&#xff1a;??? Error using > horzcatOut of memory. Type HELP MEMORY for your options.做算法仿真时&#xff0c;矩阵太大&#xff0c;超出内存了。当信号矩阵缩到可以满足内存时&#xff0c;仿真也没意义了&#xff0c;只有找解决办法了。找到一…

java 邮件 tls_通过TLS发送的Java邮件

java 邮件 tls抽象 本博客的目的是演示如何使用Java Mail通过具有TLS连接的SMTP服务器发送电子邮件。 免责声明 这篇文章仅供参考。 在使用所提供的任何信息之前&#xff0c;请认真思考。 从中学到东西&#xff0c;但最终自己做出决定&#xff0c;风险自负。 要求 我使用以下…

java中的break与continue用法

一、break break 的作用为跳出循环&#xff0c;执行循环外面的操作 &#xff08;1&#xff09;简单break public class Main {public static void main(String[] args) {int i0;for(;i<100;i){if(i2)break;}System.out.println(i);} } 输出结果&#xff1a;2 双重循环 publ…

java中的native关键字有什么作用?(java本地方法)

转自&#xff1a; http://zhidao.baidu.com/link?urlXu94DBMxXz3sJyCrG7G1sCmXoHuyuYx4DMG1x7UqYL7FhfFnqF7-Z9nxIQUpntPkqzaZ0xAyIjKIrEYrwIett_ 1、什么是Native Method 简单地讲&#xff0c;一个Native Method就是一个java调用非java代码的接口。一个Native Method是这样一…

php sessionid 重复,php_ session_id 限制同一用户同时登录

出于信息安全的考虑&#xff0c;希望给每个能进入系统的人员一个账户&#xff0c;而不是所有人共用一个账户&#xff0c;并且一个账户同时只能一人登陆。刚开始的做法是登陆加锁&#xff0c;当用户登陆之后&#xff0c;对此用户进行标记&#xff0c;若此用户未下线状态下进行第…

JavaFX之TableView

TableView表 构建一个表主要有TableView,TableColumn,ObservableList,Bean。 添加列table.getColumns().addAll(); ObservableList里面是存放的数据 table.setItems(observableList);添加数据 observableList里面一般是存放的Bean&#xff0c;列与Bean之间建立联系&#xf…

java native关键字(java本地方法)

转自&#xff1a; http://blog.csdn.net/youjianbo_han_87/article/details/2586375 native是与C联合开发的时候用的&#xff01;java自己开发不用的&#xff01; 【1】使用native关键字说明这个方法是原生函数&#xff0c;也就是这个方法是用C/C语言实现的&#xff0c;并且被…

php 按钮的属性值,HTML button标签的属性有哪些

HTML button的属性有&#xff1a;autofocus、disabled、form、formaction、formenctype、formmethod、formnovalidate、formtarget、name、type、value。本教程操作环境&#xff1a;windows7系统、HTML5版、Dell G3电脑。HTML 标签标签定义一个按钮。在 button 元素内部&#x…

javafx之TableView的FXCSS

TableView的FXCSS 一、特殊的table设置 TableView的单元之间去掉行横线 .table-view .table-row-cell { -fx-background-insets: 0; } TableView的单元之间去掉没有数据的竖线 table-row-cell:empty .table-cell { -fx-border-width: 0px; } TableView 的单元…

sql 注射_令人惊讶的注射

sql 注射所以&#xff0c;我欠吉姆道歉。 他编写了一个有效的模拟和JUnit测试&#xff0c;我在回顾中告诉他&#xff0c;我认为它没有达到他的预期。 当我错了时&#xff0c;这种情况对我来说就像是一个错误 。 称它为理想的意外副作用。 假设您有以下两类&#xff1a; public…

java中的equals方法+hashCode方法

【0】README 0.1&#xff09;以下内容均为原创&#xff0c;包括源代码&#xff0c; 旨在理清 equals 和 hashCode 方法的 实现原理&#xff1b; 0.2&#xff09; for full resource code, please visit https://github.com/pacosonTang/core-java-volume/blob/master/chapte…

mysql判断条件用法,MySQL数据库讲解条件判断函数 MySQL数据库使用教程

函数&#xff1a;(1)IF(expr,v1,v2)函数(2)IFNULL(v1,v2)函数(3)CASE函数(相关免费学习推荐&#xff1a;mysql视频教程)(1)if(expr,v1,v2)函数在if(expr,v1,v2)函数中,若表达式expr是true(expr<>0 and epr<>null)返回v1&#xff0c;否则返回v2。【例】使用if()函数…

cuba.platform_CUBA 7.2 –有什么新功能?

cuba.platformCUBA平台的第七版向前迈出了一大步。 内部体系结构的改进和新的IDE为进一步改进奠定了良好的基础。 我们将继续添加新功能&#xff0c;以使开发人员的生活更轻松&#xff0c;并使他们的工作更加高效。 在7.2版中&#xff0c;我们引入了许多可能看起来像是主要更新…

javafx之TableView的TableColumn

TableColumn列 列与Bean之间建立联系&#xff1a; setCellValueFactory(); 通过cell值工厂建立与Bean的联系。它这里并不需要知道你是传了什么Bean&#xff0c;它只需要通过“字段名”反射去Bean里面获得值&#xff0c;所以Bean属性定义的名字不需要与它相同&#xff0c;只需…

java集合——具体的集合

【0】README 0.1&#xff09; 本文描述 转自 core java volume 1&#xff0c; 旨在理解 java集合——具体的集合 的相关知识&#xff1b; 【1】下表展示了 java类库中的集合&#xff0c;并简要描述了每个集合类的用途。 1.1&#xff09;在下表中&#xff0c; 除了以 Map结尾的…

excel 26进制 php,记录一次华为招聘的编程题-excel中的26进制

var line "abcdefghijklmnopqrstuvwxyz";var list line.split("");function baseConversion(N) {var jz [];//获得有0的26进制while (true) {if (parseInt(N/26) 0) {jz.push(N%26);break;} else{jz.push(N%26);N parseInt(N/26);}}//转化成无0的26进…

日发帖 发帖频率 发帖时段_先发帖

日发帖 发帖频率 发帖时段通常&#xff0c;我们编写代码来计算出一堆可用的答案。 让我们来看一下Java中的情况。 public Widget getAppropriateWidget(CustomerRequest request) { if (shelfstock.contains(request.getBarcode()) { return new ShelfWidget(); } if (backroom…