Java集合:Collection接口

Collection是一个接口,继承自Iterable。我们先看一下Iterable接口的源码

一、Iterable

package java.lang;import java.util.Iterator;
import java.util.Objects;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;/***实现这个接口的的类允许使用"for-each loop"语句来遍历。*/
public interface Iterable<T> {/***返回一个元素类型为T的迭代器*/Iterator<T> iterator();/*** jdk1.8新增的遍历方式*/default void forEach(Consumer<? super T> action) {Objects.requireNonNull(action);for (T t : this) {action.accept(t);}}/*** 暂不研究*/default Spliterator<T> spliterator() {return Spliterators.spliteratorUnknownSize(iterator(), 0);}
}

Iterable接口有一个Iterator iterator();方法,而Collection继承自Iterable接口,所以我们说Collection继承于Iterator。

二、Collection 接口

Collection是一个高度封装的集合接口,它提供了所有集合要实现的默认方法接口。

我们看一下接口源码,了解它有哪些接口和默认实现。

package java.util;import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;/***这是一个集合分层的根接口。集合代表了一组包含元素的对象。有些集合允许有重复的元素,有些不允许。*有些集合是有序的有些无序的。jdk不对这个接口提供任何直接的实现,但是再一些直接子接口例如Set和List有实现了某些接口方法。*所有继承Collection的类必须提供两个默认的构造函数,一个不带参数的、一个带Collection类型参数。**/public interface Collection<E> extends Iterable<E> {//查询操作/***返回集合大小,也就是集合中元素的数量*/int size();/*** 如果集合包含元素则返回true,即判断集合是否为空*/boolean isEmpty();/*** 判断集合是否存在某个对象,注意这里参数是个Object,并没有限制为E或其子类*/boolean contains(Object o);/*** 返回一个迭代器iterator。并没有说明元素的迭代顺序,除非特别的集合有这个要求。*/Iterator<E> iterator();/***将集合转为对象数组,注意这里不是元素数组而是一个Object数组。*如果集合保证是有序的,那么通过迭代器返回数组有相同顺序*返回的数组是安全的,也就是说集合有自己的引用,数组开辟新的堆内存,也有自己的引用。所以调*用者可以随意操作返回的数组。*这个方法是数组和列表之间的桥梁*/Object[] toArray();/*** 返回一个集合元素类型的数组。如果集合满足指定的数组并且有足够的空间,则在其中返回此集合* 否则返回此集合大小的新数组。* 如果集合有序,那么返回此集合迭代器遍历顺序的数组* 如果数组大小比集合元素多,那么在数组满足集合元素后在末尾设置为null  ** 如果在这个集合中指定数组运行时类型不是运行时元素类型的超类,那么抛ArrayStoreException异常* 如果指定数组为空,则抛出NullPointerException*/<T> T[] toArray(T[] a);//修改操作/*** 确保此集合包含特定的元素类型。* 如果此集合增加元素成功返回true。* 如果此集合不允许有重复元素并且已经包含所传参数,那么返回false* * 支持此操作的集合可能会限制向该集合添加哪些元素。特别的,有些集合会拒绝null元素,有些* 会对要增加的元素强加一些限制。* Collection实现类应该在文档中明确指出所有的限制。** 如果集合以除已经包含元素之外的任何原因拒绝添加特定元素,则必须抛出异常*(而不是返回false)。这保留了集合在此调用返回后始终包含指定元素的不变式。*/boolean add(E e);/*** 如果此集合中存在此元素,那么移除一个特定元素类型的实例。更正式的说,如果集合中包含一个或多个这样的元素,* 那么删除这样的元素(o==null?e==null:o.equals(e))。如果集合包含指定的元素(或集合因调用而发生改变),那么返回true。** 如果指定元素的类型和集合不相容,抛出ClassCastException异常(可选的限制条件)* 如果指定元素是null并且这个集合不允许null元素存在,那么抛出NullPointerException异常(可选的限制条件)* 如果此集合不支持remove操作那么抛出UnsupportedOperationException异常(可选的限制条件)*/boolean remove(Object o);//容量操作/*** 如果this集合包含指定集合的所有元素,返回true* c集合必须要检查是否被包含在this集合* 如果指定元素的类型和集合不相容,抛出ClassCastException异常(可选的限制条件)* 如果指定元素是null并且这个集合不允许null元素存在,那么抛出NullPointerException异常(可选的限制条件)*/boolean containsAll(Collection<?> c);/*** 将指定集合的所有元素到this集合中(可选的操作)。* 如果指定的集合在操作进行时被修改了,那么此操作行为未定义。* (这意味着如果指定的集合是这个集合,并且这个集合是非空的,那么这个调用的行为是未定义的。)* * @参数:c集合包含了要被添加到这个集合的元素* @返回:如果调用结果改变了this集合返回true* @throws:如果 addAll操作不被此集合支持,那么抛出UnsupportedOpertaionException异常* @throws: 如果指定集合包含了空元素而this集合不允许有空元素,那么抛出NullPointerException异常* @throws:如果this集合阻止hiding集合元素类型添加,那么抛出ClassCastException异常* @throws:如果指定集合的元素的某些属性阻止将其添加到此集合,则抛出IllegalArgumentException* @throws:由于插入限制,如果不是所有元素都可以在此时添加,则抛出IllegalStateException异常*/boolean addAll(Collection<? extends E> c);/*** 移除此集合中所有的包含在指定集合中的元素(可选的操作)。调用过此函数之后,那么此集合和指定集合将不再包含相同元素。** @param:包含要从该集合中删除的元素的c集合* @return:如果此集合因调用而更改那么返回true* @throws:如果此集合不支持removeAll方法,则抛出UnsupportedOperationException* @throws:如果集合中一个或多个元素的类型与指定集合不兼容,则抛出ClassCastException(可选的操作)* @throws:如果该集合包含一个或多个空元素,且指定的集合不支持空元素(optional),或者指定的集合为空,* 则抛出NullPointerException异常*/boolean removeAll(Collection<?> c);/*** 移除此集合中所有符合给定Predicate的元素。在迭代期间或由Predicate引发的错误或运行时异常将被转发给调用方* @implSpec* 默认实现使用其迭代器遍历集合的所有元素。每一个匹配的元素使用iterator.remove()来移除。* 如果集合的iterator不支持移除将会抛出UnsupportedOperationException异常在匹匹厄到* 第一个元素时。* @param 过滤一个predicate* @param 筛选要删除的元素返回true的Predicate* @return 如果任何一个元素被删除返回true* @throws 指定过滤器为空,抛出NullPointerException* @throws 如果元素没有被删除,或者移除操作不支持,*  则立即抛出UnsupportedOperationException异常* @since 1.8*/default boolean removeIf(Predicate<? super E> filter) {//如果filter为null抛出NullPointerExceptionObjects.requireNonNull(filter);boolean removed = false;final Iterator<E> each = iterator();//通过迭代器遍历删除,只要删除一个removed就为truewhile (each.hasNext()) {if (filter.test(each.next())) {each.remove();removed = true;}}return removed;}/*** 只保留此集合中包含在指定集合中的元素(可选的操作)。* 也就是说,此集合中不包含在指定集合中的所有元素。* @param:要保留的元素的集合c* @return:如果此集合改变了返回true* @throws:如果此集合不支持retainAll,则抛出UnsupportedOperationException异常* @throws:如果集合中一个或多个元素的类型与指定集合不兼容,则抛出ClassCastException(可选的操作)* @throws:如果该集合包含一个或多个空元素,且指定的集合不支持空元素(optional),或者指定的集合为空*/boolean retainAll(Collection<?> c);/*** 移除此集合中所有元素(可选操作),调用此方法后集合里将为空。* @throws: 如果此集合clear操作不支持将会抛出UnsupportOperationException异常。*/void clear();//比较和hash/*** 比较指定的对象与此集合是否相等* */boolean equals(Object o);/***返回这个集合的hashCode。当集合接口没有对Object.hashCode方法的一般协议做任何规定,编程*人员应该注意在重写equals方法时必须重写hashCode方法,以便满足一般协议对这个*Object.hashCode方法。特别的,c1.equals(c2)表明c1.hashCode()==c2.hashCode()。*/int hashCode();/***一下1.8新增的Spliterator,暂不研究*/@Overridedefault Spliterator<E> spliterator() {return Spliterators.spliterator(this, 0);}default Stream<E> stream() {return StreamSupport.stream(spliterator(), false);}default Stream<E> parallelStream() {return StreamSupport.stream(spliterator(), true);}
}

三、AbstractCollection

AbstractCollection是一个实现了Collection接口的抽象类,除了iterator()和size()接口,它提供了一些其他接口的默认实现,其他集合类可以继承此类来复用。

package java.util;public abstract class AbstractCollection<E> implements Collection<E> {/*唯一的构造函数*/protected AbstractCollection(){}//查询操作public abstract Iterator<E> iterator();public abstract int size();/** 返回size() == 0*/public boolean isEmpty(){return size() == 0;}/*** 实现的contains方法,通过迭代器遍历*/public boolean contains(Object o){Iterator<E> it = iterator();if (o == null){while (it.hasNext())if (it.next() == null)return true;}else{while (it.hasNext())if (o.equals(it.next()))return true;}return false;}/*** 此默认实现,考虑到数组在迭代器遍历过程中大小可能会改变,* 也就是可能会增加或减少元素怒*/public Object[] toArray(){//估计数组大小,并做好变小或变大的准备Object[] r = new Object[size()];Iterator<E> it = iterator();for (int i = 0; i < r.length; i++){if (! it.hasNext())  //比期望的元素少,那么调用Arrays.copyOf()方法返回一个新的数组return Arrays.copyOf(r, i);r[i] = it.next();}//判断集合有没有被增加(迭代器改变),如果没有返回数组,如果有调用finishToArray()方法返回数组return it.hasNext() ? finishToArray(r, it) : r;}/*** */@SuppressWarnings("unchecked")public <T> T[] toArray(T[] a) {// Estimate size of array; be prepared to see more or fewer elementsint size = size();T[] r = a.length >= size ? a :(T[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);Iterator<E> it = iterator();for (int i = 0; i < r.length; i++) {if (! it.hasNext()) { // fewer elements than expectedif (a == r) {r[i] = null; // null-terminate} else if (a.length < i) {return Arrays.copyOf(r, i);} else {System.arraycopy(r, 0, a, 0, i);if (a.length > i) {a[i] = null;}}return a;}r[i] = (T)it.next();}// more elements than expectedreturn it.hasNext() ? finishToArray(r, it) : r;}/*** 一些VM会在数组中保留头信息,所以要占用8字节空间,头信息大小不能超过8* 重新分配更大的长度给数组,如果要求的数组大小超过VM限制,会抛出OutOfMemoryError* 默认值 2147483647 - 8;*/private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;/*** 重新在toArray方法中,如果iterator返回了比期望中的大小更多的元素时,重新给数组分配空间来完成填充数组。* @param 之前的已经被填满的数组* @param 操作中集合的iterator* @return 除了给定的数组之外,增加了从迭代器中获取的元素,并修正数组长度*/@SuppressWarnings("unchecked")private static <T> T[] finishToArray(T[] r, Iterator<?> it) {int i = r.length; //被填充满的数组长度(原始集合大小)while (it.hasNext()) {int cap = r.length;if (i == cap) {  //第一次(刚进来的时候)一定为true,那么分配新的数组大小int newCap = cap + (cap >> 1) + 1; //右移一位+1再加上原大小if (newCap - MAX_ARRAY_SIZE > 0)  //新数组大小大于集合默认最大值,调用hugeCapacity()方法重新分配,值为Integer.MAX_VALUEnewCap = hugeCapacity(cap + 1);r = Arrays.copyOf(r, newCap);}r[i++] = (T)it.next();}// 修正数组多余的空间,如果正好直接返回,否则调用Arrays.copyOf()方法return (i == r.length) ? r : Arrays.copyOf(r, i);}private static int hugeCapacity(int minCapacity) {if (minCapacity < 0) // 内存溢出throw new OutOfMemoryError("Required array size too large");return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;}//修改操作/*** 此操作总是抛出 UnsupportedOperationException* @throws UnsupportedOperationException {@inheritDoc}* @throws ClassCastException            {@inheritDoc}* @throws NullPointerException          {@inheritDoc}* @throws IllegalArgumentException      {@inheritDoc}* @throws IllegalStateException         {@inheritDoc}*/public boolean add(E e) {throw new UnsupportedOperationException();}/*** 通过集合迭代器查找元素,如果找到调用iterator.remove()方法删除元素。* 删除一个就返回true*/public boolean remove(Object o) {Iterator<E> it = iterator();if (o==null) {while (it.hasNext()) {if (it.next()==null) {it.remove();return true;}}} else {while (it.hasNext()) {if (o.equals(it.next())) {it.remove();return true;}}}return false;}// Bulk Operations/*** 判断此集合是否包含指定集合所有元素,有一个没有返回false*/public boolean containsAll(Collection<?> c) {for (Object e : c)if (!contains(e))return false;return true;}/*** 调用add(E e)方法添加指定集合到此集合中** @see #add(Object)*/public boolean addAll(Collection<? extends E> c) {boolean modified = false;for (E e : c)if (add(e))modified = true;return modified;}/*** 这个方法将从此集合中删除指定集合的所有元素,通过迭代器删除。* @throws UnsupportedOperationException {@inheritDoc}* @throws ClassCastException            {@inheritDoc}* @throws NullPointerException          {@inheritDoc}** @see #remove(Object)* @see #contains(Object)*/public boolean removeAll(Collection<?> c) {Objects.requireNonNull(c);boolean modified = false;Iterator<?> it = iterator();while (it.hasNext()) {if (c.contains(it.next())) {it.remove();modified = true;}}return modified;}/*** 此集合中保留指定集合的所有元素,也就是说调用此方法之后,此集合中删除了不存在指定集合中*的元素* */public boolean retainAll(Collection<?> c) {Objects.requireNonNull(c);boolean modified = false;Iterator<E> it = iterator();while (it.hasNext()) {if (!c.contains(it.next())) {it.remove();modified = true;}}return modified;}/*** 清空集合中所有元素* @throws UnsupportedOperationException {@inheritDoc}*/public void clear() {Iterator<E> it = iterator();while (it.hasNext()) {it.next();it.remove();}}//  String conversion/*** 集合的toString方法,所有继承AbstractCollection的类都有此方法*/public String toString() {Iterator<E> it = iterator();if (! it.hasNext())return "[]";StringBuilder sb = new StringBuilder();sb.append('[');for (;;) {E e = it.next();//如果将自己这个集合添加到自己,就会打印(this Collection)sb.append(e == this ? "(this Collection)" : e);if (! it.hasNext())return sb.append(']').toString();sb.append(',').append(' ');}}}
}

AbstractCollection类默认实现的方法,在上面源代码中我都已经讲解过了,很多常用的集合都会使用 默认实现,比如常用的toString方法,我们在输出ArrayList时调用的就是此方法。

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

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

相关文章

Java集合:List集合

List集合 List集合类中元素有序、且可重复&#xff0c;集合中的每个元素都有其对应的顺序索引。 List容器中的元素都对应一个整数型的序号记载其在容器中的位置&#xff0c;可以根据序号存取容器中的元素。 JDK API中List接口的实现类常用的有&#xff1a;ArrayList、LinkList和…

MySQL为什么要set names

大家都知道SET NAMES x相当于SET character_set_client x;SET character_set_results x;SET character_set_connection x; 以下从MySQL5.0官方文档上摘录了相关内容&#xff0c;并翻译&#xff0c;说明了相关系统变量的用处&#xff1a; What character set is the statem…

MySql日期处理系列-常用的日期推算处理

以下都是我平时用的一些日期推算处理方法&#xff0c;方法并不一定是最有效率的.全部均通过测试!转载请注明来自[phpchina.com] #title: 常用的日期推算处理#auther: 小强(占卜师) #date: 2007-12-25 #取得当前日期set dtCURDATE();select dt; #当前日期这个月的第一天selec…

Java集合:Set集合

一、Set接口的特点 一个不包含重复元素的collection。更确切地讲&#xff0c;Set不包含满足e1.equals(e2)的元素对 e1和e2&#xff0c;并且最多包含一个null元素。 Set集合由Set接口和Set接口的实现类组成&#xff0c;Set接口继承了Collection接口&#xff0c;因此包含了Coll…

谈谈我对MYSQL乱码的解决办法

经常更换虚拟主机,而各个服务商的MYSQL版本不同,当导入数据后,总会出现乱码等无法正常显示的问题,查了好多资料,总结出自己的一点技巧: WINDOWS 下导入应该这样使用MYSQL的命令在DOS命令下进入mysql的bin目录下,输入mysql -uroot -p密码 数据库名称<要恢复的数据库, 例如我们…

Java集合:Map集合

一、简述 public interface Map<K,V>将键映射到值的对象。一个映射不能包含重复的键&#xff1b;每个键最多只能映射到一个值。 注意&#xff1a;Map中的集合不能包含重复的键&#xff0c;值可以重复。每个键只能对应一个值。 Map集合是键值对形式存储值的&#xff0c…

用离线编辑器Zoundry写zblog日志

Zoundry是免费的离线网志发布工具&#xff0c;由于家里的网络很差&#xff0c;写了一半的日志经常因为掉线而丢失&#xff0c;这样一款软件的确是很必要的。今天下载试用了一下&#xff0c;感觉的确不错。使用起来也很简单&#xff1a; 1.下载并安装zoundry软件&#xff1a;现…

MySQL:基本命令

一、数据库操作 1、查询数据库&#xff0c;命令如下: SHOW DATABASES;2、我们可以在登陆 MySQL 服务后&#xff0c;使用 create 命令创建数据库&#xff0c;命令格式: CREATE DATABASE 数据库名;3、使用 drop 命令删除数据库&#xff0c;命令格式&#xff1a; drop databas…

CentOS 5打造全功能Web服务器

转&#xff1a;主要做为历史记录&#xff0c;以后用。另外很少见这么好的编译的文章&#xff0c;其实我不推荐用编译安装。但这个文章不错.V3.0 2007年11月11日 将搭建教程划分阶段以适应不同需要。加入程序优化&#xff0c;程序安全&#xff0c;加入memcache&#xff0c;squid…

MySQL:查询条件

查询条件 1、使用 WHERE 子句从数据表中读取数据的通用语法&#xff1a; SELECT field1, field2,...fieldN FROM table_name1, table_name2... [WHERE condition1 [AND [OR]] condition2.....查询语句中你可以使用一个或者多个表&#xff0c;表之间使用逗号**,** 分割&#x…

linux下的ImageMagick安装

检查系统有无安装ImageMagick官方网址是&#xff1a; www.imagemagick.org 从官方不好下载&#xff0c;提供 sourceforge的下载地址&#xff1a; imagemagick.sourceforge.net shell> rpm -qa | grep ImageMagick 没有就开始安装ImageMagickshell> rpm -Uvh ImageMagi…

MySQL:进阶应用

一、进阶应用 1、可以在 SELECT, UPDATE 和 DELETE 语句中使用 Mysql 的 JOIN 来联合多表查询。 JOIN 按照功能大致分为如下三类&#xff1a; INNER JOIN&#xff08;内连接,或等值连接&#xff09;&#xff1a;获取两个表中字段匹配关系的记录。**LEFT JOIN&#xff08;左连…

Hive-常用操作

一. 数据库操作 1、创建数据库 //用户可以用 IF NOT EXISTS 选项来忽略这个异常。create database [ if not exists ] myhive ;2、创建数据库并指定hdfs存储位置 create database myhive2 location /myhive2;3、修改数据库&#xff0c;可以使用alter database 命令来修改数据…

linux下nmap工具的使用

nmap NMap&#xff0c;也就是Network Mapper&#xff0c;是Linux下的网络扫描和嗅探工 具包&#xff0c;其基本功能有三个&#xff0c;一是探测一组主机是否在线&#xff1b;其次是扫描主机端口&#xff0c;嗅探所提供的网络服务&#xff1b;还可以推断主机所用的操作系统 。N…

Hive-分区分桶概述

一、分区 简介 为了对表进行合理的管理以及提高查询效率&#xff0c;Hive可以将表组织成“分区”。 分区是表的部分列的集合&#xff0c;可以为频繁使用的数据建立分区&#xff0c;这样查找分区中的数据时就不需要扫描全表&#xff0c;这对于提高查找效率很有帮助。 分区是…

定时提醒你休息的脚本

本文来源于阿里西西WEB开发社区http://www.alixixi.com收集整理&#xff0c;欢迎访问。 定时弹窗提醒功能脚本..把以下代码存为.vbs运行即可. 以下是引用片段&#xff1a;set WshShell WScript.CreateObject("WScript.Shell") ’对话框标题 alerttitle "你的…

Hive-分区分桶操作

在大数据中&#xff0c;最常用的一种思想就是分治&#xff0c;我们可以把大的文件切割划分成一个个的小的文件&#xff0c;这样每次操作一个小的文件就会很容易了&#xff0c;同样的道理&#xff0c;在hive当中也是支持这种思想的&#xff0c;就是我们可以把大的数据&#xff0…

ubuntu好文收集

ubuntu全程配置手册 http://ljlau.blogdriver.com/ljlau/1220277.html ubuntu下向系统日志写记录 http://linux0818.bokee.com/viewdiary.14153197.html aptitude 使用快速参考 http://linuxtoy.org/archives/aptitude_quick_reference.html

Flume简单介绍

在一个完整的离线大数据处理系统中&#xff0c;除了HDFSMapReduceHive组成分析系统的核心之外&#xff0c;还需要数据采集、结果数据导出、任务调度等不可或缺的辅助系统&#xff0c;而这些辅助工具在hadoop生态体系中都有便捷的开源框架&#xff0c;在此&#xff0c;我们首先来…

linux系统优化篇之---top

top命令是Linux下常用的性能分析工具&#xff0c;能够实时显示系统中各个进程的资源占用状况&#xff0c;类似于Windows的任务管理器。下面详细介绍它的使用方法。 top - 01:06:48 up 1:22, 1 user, load average: 0.06, 0.60, 0.48Tasks: 29 total, 1 running, 28 sleeping, …