【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 集合中的所有元素,则返回true;
boolean equals(Object other)
boolean addAll(Collection<? extends E> from)
boolean remove(Object obj)
boolean removeAll(Collection<?> c)
void clear() :移除集合中的所有元素;
boolean retainAll(Collection<?> c) : 从集合中移除所有与 other 集合中的元素不同的元素。如果这个调用改变了集合,返回true;
Object[] 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超类提供了;

java集合——集合接口+迭代器接口相关推荐

  1. Java基础知识(二)(Object类的常用方法、日期时间类、System类、StringBuilder类、包装类、Collection集合、Iterator迭代器、泛型、list集Set接口...)

    文章目录 Java基础知识(二) 1.Object类的常用方法 1.1 toString方法 1.2 equals方法 1.3 Objects类 2.日期时间类 2.1 Date类 2.2 DateF ...

  2. 2021-06-19复习java Collection集合 Iterator接口_迭代器 增强for循环 泛型

    2021-06-19复习java Collection集合 Iterator接口_迭代器 增强for循环 泛型 Collection集合 java.util.coLlection接口 所有单列集合的最 ...

  3. Java Collection集合 --迭代器 -- 泛型 --List接口案例

    案例1 需求:具体要求如下:学生练习 1.定义一个学生类Student,包含三个属性姓名.年龄.性别, 私有成员变量,生成无参,有参构造方法,生成get/set方法并重写toString()方法. 2 ...

  4. java之集合框架一Collection接口

    1.集合的由来: 我们学习的是面向对象的语言.而面向对象语言对事物的描述是通过对象体现的.为了方便对多个对象进行操作,我们就必须把多个对象进行存储.而要想存储多个对象,就不能是一个基本的变量,而应该是 ...

  5. Java集合框架之四大接口、常用实现类,java基础面试笔试题

    我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...

  6. Java学习关于集合框架的基础接口--Collection接口

     集合框架(Collection  Framework)是Java最强大的子系统之一,位于java.util 包中.集合框架是一个复杂的接口与和类层次,提供了管理对象组的最新技术.Java集合框架标准 ...

  7. JavaSE入门学习34:Java集合框架之Collection接口、子接口及其实现类

    一Collection接口 Collection接口定义了存取一组对象的方法,其子接口Set.List和Queen分别定义了存储方式. 使用Collection接口需要注意: 1Collection接 ...

  8. java之集合Collection之List接口总结

    总结自韩顺平老师的零基础30天学 JAVA 目录 一.集合的框架体系 1.java的集合体系主要可分为两大类:Collection和Map集合. 2.Collection和Map的区别 二.Colle ...

  9. Java集合框架及基本接口

    文章目录 Collection接口及迭代器 泛型方法的使用 集合基本接口和实现 List ArrayList LinkedList ListIterator接口和Iterable接口的区别 Set H ...

最新文章

  1. VS2013安装OpenCV4.1版本并搭建一个小程序
  2. SpringMVC注解驱动标签做了什么操作
  3. 开始使用Lumen吧,3分钟搞定登陆认证
  4. python 关闭 定时开启_Qt多种定时器
  5. Android 11 将推出系统试用功能,满意后再正式安装
  6. a标签鼠标放上去变色_一切为了集齐一套装备:杜伽LEO600游戏鼠标和P300鼠标垫简评...
  7. 学校为什么要单位接收函_为什么要选择语言学校留学?
  8. 6. 吴恩达机器学习课程-作业6-SVM
  9. 英文期刊论文翻译格式要求和文献要求
  10. 基于MATLAB OCR的发票识别系统
  11. java pdfreader 用法_使用 iText 进行 Acroform 编辑的 Pdf
  12. C#中的Builder模式
  13. C与C++学习经典网站
  14. java如何连接与断开SQL server2008数据库
  15. v4l2框架—申请缓存(VIDIOC_REQBUFS)
  16. 关系型数据库第四章笔记---关系数据理论
  17. React中文文档之Handling Events
  18. 一种基于属性加密技术(ABE)的轻量级数据共享方案
  19. 奥运圣火29日起点燃燕赵激情 李梅素将承担首棒
  20. 2.从自然数1开始累加,直到累加和大于1000为止,统计被累加的自然数的个数,并把统计的个数送入n单元,将累加和送入sum单元。

热门文章

  1. HDU - 6558/概率dp(从后往前推导)
  2. Fight against involution
  3. [HAOI2018] 染色(二项式反演+NTT)
  4. 周末狂欢赛2(冒泡排序,概率充电器,不勤劳的图书管理员)
  5. P4593-[TJOI2018]教科书般的亵渎【拉格朗日差值】
  6. jzoj3833-平坦的折线【模型转换,LIS】
  7. P3435-[POI2006]OKR-Periods of Words【KMP】
  8. Codeforces Round #659 (Div. 2)
  9. 【动态规划】 多米诺骨牌 (ssl 1632/luogu 1282)
  10. 有上下界网络流问题汇总