2接口详解_java集合【2】——— Collection接口详解

  • 一、Collection接口简介

  • 二、Collection源码分析

  • 三、Collection的子类以及子类的实现

    • 3.1 List extend Collection

    • 3.2 Set extend Collection

    • 3.3 Queue extend Collection

  • 四、Collection和Map的辨析

  • 五、Collection和Collections的辨析

  • 六、总结

一、Collection接口简介

collection在java集合中,算是顶级接口,它继承了iterable接口,不能实例化,只能实例化其子类。之所以需要这样一个接口,是因为java作为面向对象,总是避免不了处理多个对象的情况,要处理多个对象,首先需要容器存储,这个容器就是集合。为什么有了数组,还需要集合,因为数组的功能单一,长度不可变,而有些集合实现类则是对数组操作的封装。

Collection集合和数组的区别:

  • 集合长度可以变,数组是定长的
  • 集合存储的元素只能是引用类型,而数组则可以是基本类型
  • 数组只能执行基本操作,而集合功能经过拓展,更加丰富。
graph TD;
Collection -->List-有顺序,可重复
List-有顺序,可重复 -->LinkedList-使用链表实现,线程不安全
List-有顺序,可重复 -->ArrayList-数组实现,线程不安全
List-有顺序,可重复 -->Vector-数组实现,线程安全
Vector-数组实现,线程安全 -->Stack-堆栈,先进后出

Collection-->Set-不可重复,内部排序
Set-不可重复,内部排序-->HashSet-hash表存储
HashSet-hash表存储-->LinkHashSet-链表维护插入顺序
Set-不可重复,内部排序-->TreeSet-二叉树实现,排序

Collection-->Queue-队列,先进先出

二、Collection源码分析

Collection继承于Iterable接口,而Iterable接口,是集合的顶级接口,没有之一,Iterable接口定义的功能是可以迭代,也就是获取迭代器iterator的功能,因此Collection以及其实现类也间接获得迭代的功能。

为什么需要这样子定义呢?我陷入了深深地思考...?

其实,这也算是哲学问题,java的类的设计是经过很长时间的考验以及调整形成的,平衡修改以及耦合等各方面的原因,结构更加清晰,维护成本更低,逻辑性更强。这些接口就是一个个标准或者规范,其子类就是不断拓展功能,这些接口的形成是一种抽象,将能迭代事物抽象成为迭代器iterator,将获取迭代器,也就是迭代能力抽象成iterableCollection则是获得迭代能力的接口之一,其实Map的实现类里面也是有使用到iterable接口,几乎所有的集合实现类都是需要遍历元素的,所以这个iterable也是必须存在的,存在即合理。

下面看Collection接口以及iterable接口的方法对比:f8dd85552b51800aa1f779e818419e78.png从上面的图我们可以看出,iterable接口功能主要是

  • 获取迭代器iterator
  • foreach()遍历
  • 获取可切分迭代器Spliterator

Collection接口在此基础上进行拓展,源码接口如下:

boolean add(Object o)    //添加元素boolean remove(Object o)  //移除元素boolean addAll(Collection c) //批量添加boolean removeAll(Collection c)  //批量移除void retainAll(Collection c)   // 移除在c中不存在的元素void clear()  //清空集合int size()   //集合大小boolean isEmpty()    //是否为空boolean contains(Object o)    //是否包含在集合中boolean containsAll(Collection c)    //是否包含所有的元素
Iterator iterator()    // 获取迭代器
Object[] toArray()   // 转成数组default boolean removeIf(Predicate super E> filter) {} // 删除集合中复合条件的元素,删除成功返回true

boolean equals(Object o)int hashCode()default Spliterator spliterator() {} //获取可分割迭代器

default Stream stream() {}   //获取流

default Stream parallelStream() {} //获取并行流

里面获取并行流的方法parallelStream(),其实就是通过默认的ForkJoinPool(主要用来使用分治法(Divide-and-Conquer Algorithm)来解决问题),提高多线程任务的速度。我们可以使用ArrayList来演示一下平行处理能力。例如下面的例子,输出的顺序就不一定是1,2,3...,可能是乱序的,这是因为任务会被分成多个小任务,任务执行是没有特定的顺序的。

List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
list.parallelStream()
       .forEach(out::println);

上面源代码可以看出,Collection接口定义了功能规范,有以下功能方法:

  • 添加元素
  • 删除元素
  • 判断是否包含/是否全部包含/是否为空
  • 获取迭代器/可分割迭代器
  • 获取长度
  • 取交集
  • 获取流/并行流

我们遍历元素的时候可以获取Iterator,但是具体的实现是以子类的特性去实现的,比如ArrayList是用内部类的方式实现了Iterator接口。

三、Collection的子类以及子类的实现

继承Collection的子类关系如下:e0b898690dd0e3872db4c63c633740b6.png

上面的类图已经足够清楚,下面是一些简单的概括(上面的类型是使用IDEA的类图功能自动生成,简直不能太好用???感觉发现了新大陆)

3.1 List extend Collection

继承于Collection接口,有顺序,取出的顺序与存入的顺序一致,有索引,可以根据索引获取数据,允许存储重复的元素,可以放入为null的元素。
最常见的三个实现类就是ArrayListVector,LinkedListArrayListVector都是内部封装了对数组的操作,唯一不同的是,Vector是线程安全的,而ArrayList不是,理论上ArrayList操作的效率会比Vector好一些。

里面是接口定义的方法:

int size();  //获取大小

boolean isEmpty();  //判断是否为空

boolean contains(Object o);  //是否包含某个元素

Iterator iterator(); //获取迭代器

Object[] toArray();  // 转化成为数组(对象)

 T[] toArray(T[] a);  // 转化为数组(特定位某个类)boolean add(E e); //添加boolean remove(Object o);  //移除元素boolean containsAll(Collection> c); // 是否包含所有的元素boolean addAll(Collection extends E> c); //批量添加boolean addAll(int index, Collection extends E> c); //批量添加,指定开始的索引boolean removeAll(Collection> c); //批量移除boolean retainAll(Collection> c); //将c中不包含的元素移除default void replaceAll(UnaryOperator operator) {}//替换default void sort(Comparator super E> c) {}// 排序void clear();//清除所有的元素boolean equals(Object o);//是否相等int hashCode(); //计算获取hash值E get(int index); //通过索引获取元素E set(int index, E element);//修改元素void add(int index, E element);//在指定位置插入元素E remove(int index);//根据索引移除某个元素int indexOf(Object o);  //根据对象获取索引int lastIndexOf(Object o); //获取对象元素的最后一个元素ListIterator listIterator(); // 获取List迭代器ListIterator listIterator(int index); // 根据索引获取当前的位置的迭代器List subList(int fromIndex, int toIndex); //截取某一段数据default Spliterator spliterator(){} //获取可切分迭代器

上面的方法都比较简单,值得一提的是里面出现了ListIterator,这是一个功能更加强大的迭代器,继承于Iterator,只能用于List类型的访问,拓展功能例如:通过调用listIterator()方法获得一个指向List开头的ListIterator,也可以调用listIterator(n)获取一个指定索引为n的元素的ListIterator,这是一个可以双向移动的迭代器。
操作数组索引的时候需要注意,由于List的实现类底层很多都是数组,所以索引越界会报错IndexOutOfBoundsException
说起List的实现子类:

  • ArrayList:底层存储结构是数组结构,增加删除比较慢,查找比较快,是最常用的List集合。线程不安全。
  • LinkedList:底层是链表结构,增加删除比较快,但是查找比较慢。线程不安全。
  • Vector:和ArrayList差不多,但是是线程安全的,即同步。

3.2 Set extend Collection

Set接口,不允许放入重复的元素,也就是如果相同,则只存储其中一个。

b878714d57bd44c90bc58d8850b9a9df.png

下面是源码方法:

int size(); //获取大小

boolean isEmpty();  //是否为空
 
boolean contains(Object o); //是否包含某个元素

Iterator iterator(); //获取迭代器

Object[] toArray(); //转化成为数组

 T[] toArray(T[] a); //转化为特定类的数组boolean add(E e);   //添加元素boolean remove(Object o);   //移除元素boolean containsAll(Collection> c);   //是否包含所有的元素boolean addAll(Collection extends E> c);  //批量添加boolean retainAll(Collection> c); //移除所有不存在于c集合中的元素boolean removeAll(Collection> c); //移除所有在c集合中存在的元素void clear();   //清空集合boolean equals(Object o);   //是否相等int hashCode(); //计算hashcodedefault Spliterator spliterator() {}     //获取可分割迭代器

主要的子类:

  • HashSet
    • 允许空值
    • 通过HashCode方法计算获取hash值,确定存储位置,无序。
    • 底层是哈希表,一个元素为链表的数组
  • LinkedHashSet
    • HashSet的子类
    • 有顺序
    • 底层由哈希表组成
  • TreeSet
    • 如果无参数构建Set,则需要实现Comparable方法。
    • 亦可以创建时传入比较方法,用于排序。

3.3 Queue extend Collection

队列接口,在Collection接口的接触上添加了增删改查接口定义,一般默认是先进先出,即FIFO,除了优先队列和栈,优先队列是自己定义了排序的优先顺序,队列中不允许放入null元素。

2983d133072770918f0f3e98b26d6cfe.png

下面是源码:

boolean add(E e);   //插入一个元素到队列,失败时返回IllegalStateException (如果队列容量不够)

boolean offer(E e); //插入一个元素到队列,失败时返回false

E remove(); //移除队列头的元素并移除

E poll();   //返回并移除队列的头部元素,队列为空时返回null

E element();    //返回队列头元素

E peek();   //返回队列头部的元素,队列为空时返回null

主要的子接口以及实现类有:

aeee65e02fbcdd6f79850955dfedd6bf.png
  • Deque(接口):Queue的子接口,双向队列,可以从两边存取
    • ArrayDeque:Deque的实现类,底层用数组实现,数据存贮在数组中
  • AbstractQueue:Queue的子接口,仅实现了add、remove和element三个方法
    • PriorityQueue:按照默认或者自己定义的顺序来排序元素,底层使用堆(完全二叉树)实现,使用动态数组实现,
  • BlockingQueue:在java.util.concurrent包中,阻塞队列,满足当前无法处理的操作。

对于Collection集合我们应该使用哪一个?

每个实现都有自己的特点,重要的是知道当前数据以及业务的特点,选取最适合的集合类进行数据操作。

  • 元素唯一(Set)
    • 唯一,有序 (自定义排序):TreeSet(速度较慢)
    • FIFO,按照插入顺序,唯一:LinkedHashSet(速度较快)
    • 需要排序
    • 不需要排序:HashSet(速度最快)
  • 元素唯一
    • 普通排队 :Queue的子类
    • 两端都可以排队:ArrayDeque
    • 按照自己定义的规则排序:PriorityQueue
    • 处理排队当前无法处理太多请求(相当于缓冲):阻塞队列接口BlockingQueue
    • 线程安全:Vector
    • 接受线程不安全
    • 查询比较多:ArrayList
    • 增加删除操作较多:LinkedList
    • 列表:List
    • 排队

四、Collection和Map的辨析

  • Collection接口是存储单列元素,而Map是键值对,也就是存储了双列元素。
  • Collection接口继承了Iterable接口,而Map则不是,Map是在各自的实现类中才用内部类的方式实现Iterator接口,例如HashMap,key或者value或者它们的组合entry都可以使用迭代器进行遍历。
  • 两个的子类其实是有交集的,比如HashSet的底层实现其实就是定义了一个HashMapTreeSet同样依赖于Map接口的子实现类TreeMap

Map集合可以存储键值对,可以获取所有的键,或者值或者键值对,键不允许重复,但是值可以重复。随便说说Map相关的子类:

  • HashTable:
    • 源于JDK1.1,底层使用数组和链表
    • 线程安全,不允许null作为key或者value
  • HashMap:
    • 源于JDK1.2,JDK1.7以及之前使用数组+链表实现,JDK1.8使用数组+链表/红黑树
    • 线程不安全
  • LinkedHashMap:
    • 保存了插入的顺序,可以按照顺序遍历
  • TreeMap:
    • 实现了SortMap接口,可以把保存的记录按照键排序
    • 底层是用红黑树实现

五、Collection和Collections的辨析

(1).Collection是集合的顶级接口之一,衍生出了SetListQueue等一系列接口以及实现类。而Collections是一个辅助类,就是实现一些排序,搜索,线程安全等功能,它主要体现的功能是操作集合,而Collection则是集合本身。

(2).Collection是接口,其本身不能实例化,但是可以实例化为其子类或者实现类,但是Collections是包装类,一般不会实例化,直接调用static方法。

Collections接口主要提供了以下操作,只展示了部分,详细需要后面文章说:

  1. Sort(排序):public static > void sort(List list),元素需要实现Comparable接口,按照比较器进行排序。
  2. binarySearch(二分搜索):public static int binarySearch(List extends Comparable super T>> list, T key),
  3. reverse(反转):public static void reverse(List> list)反转顺序
  4. Shuffling(混排):public static void shuffle(List> list),将list的元素随机打乱。
  5. 交换(swap):public static void swap(List> list, int i, int j)交换两个索引的元素
  6. 拷贝(copy):public static void copy(List super T> dest, List extends T> src),copy出一个内容一致的list
  7. 返回最小的元素(min):所谓大小,根据指定的比较器决定,static > T min(Collection extends T> coll)
  8. 返回最大的元素(max):static > T max(Collection extends T> coll)
  9. 旋转(Rotate):将一个List旋转,假如有个序列列list是[1,2,3,4],调用方法Collections.rotate(list, 1)后,得到list就变成[4,1,2,3],public static void rotate(List> list, int distance)
  10. 替换所有元素(replaceAll):public static boolean replaceAll(List list, T oldVal, T newVal)
  11. 获取元素出现最后的索引(lastIndexOfSubList):public static int lastIndexOfSubList(List> source, List> target)

六、总结

Collection接口继承了iterable接口,是集合的顶级接口之一,衍生接口有List,Set,Queue等,主要定义了元素的基本操作,删除,添加等等方法,迭代一个Collection可以使用Iterator,但是Collection本身不能实例化。

a22bca31fbac01298372a8d6e1e29684.png
- END -

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

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

相关文章

幅度响应怎么计算_四电平脉冲幅度调制(PAM4)信号的误码分析

- PAM4 是一种高效利用带宽传输串行数据的方法,所需的通道带宽仅为 NRZ 所需带宽的一半。用户需要具有即时数据访问能力的互联网络,这种不断增长的需求推动着以太网、64G光纤通道、CEI-56 G以及其他新一代数据中心网络链路向前发展。用户需要具有即时数据…

使用pytorch自定义DataSet,以加载图像数据集为例,实现一些骚操作

使用pytorch自定义DataSet,以加载图像数据集为例,实现一些骚操作 总共分为四步 构造一个my_dataset类,继承自torch.utils.data.Dataset重写__getitem__ 和__len__ 类函数建立两个函数find_classes、has_file_allowed_extension,…

python文件和数据的格式化_Python在文本文件中格式化特定数据

谢谢你们的帮助。作为一个新手,我最终得到的代码不是那么优雅,但它仍然起作用:)。在#open the file and create the CSV after filtering the input file.def openFile(filename, keyword): #defines the function to open the file. User to…

windows功能_这 12 个好用 Windows 软件,让你也能用上 macOS 的独占功能

在离开 macOS 这段时间,每天在家依赖 Windows To Go 为生,感到日常工作流程在四处冒烟。这才发现 macOS 的有些特性就如同空气一样,虽然毫无存在感,却不可缺失。关于「如何在 Windows 中实现 macOS 的 xxx」,随便上网一…

Batch Normalization、Layer Normalization、Group Normalization、Instance Normalization原理、适用场景和实际使用经验

Batch Normalization、Layer Normalization、Group Normalization、Instance Normalization原理、适用场景和使用经验 一、 简单介绍各种Normalization 先放一张来自Group Normalization原论文中的图,个人认为这个图很形象,以此图直观感受一下各种归一…

blockly自定义中文出问题_[BlocklyNukkit入门]#5自定义物品

自定义物品创建一个木棍item blockitem.buildItem(280, 0, 1);设置名字item.setCustomName("棍");设置信息,用分号隔开换行blockitem.setItemLore(item, "第一行;第二行;第三行;第四行");添加有序合成添加有序合成,设置G为橡木原木的键,G就代表原木.参数1…

收发一体超声波测距离传感器模块_芜湖低功耗超声波液位计物位计设备排名

KUS 超声波液位物位计 8种工作状态设置指导 1), 窗口常开模式(模拟量输出产品为正线性工作模式或者距离测量模式)2), 窗口常闭模式(模拟量输出产品为负线性工作模式或者液位测量模式)3), 单点常开模4), 单点常闭模式。5), 单点常开带大滞回区间模式6), 单点常闭带大滞回区间模式…

学术写作科研工具推荐

最近在写论文,然后过程中觉得一些工具可以提升效率,所以就简单总结一下,以后也会逐渐更新 Ccf deadlines:我该赶哪个ddl呢? 一些主要ccf A、B、C类会议的截稿日期都会被统计显示在此哦,看看你想投哪个会吧…

如何加声调口诀_声母韵母口诀顺口溜歌曲(怎么快速记住声母韵母)

家有一年级的小朋友,或者是孩子即将上小学的爸爸妈妈们,孩子的拼音学习进行得怎么样了?拼音是孩子进行语文学习的第一课,也是基础。但对很多小朋友来说真的是一道拦路虎。很多孩子由于一年级拼音基础不牢,到了四五年级…

pytorch model.train() 和model.eval() 对 BN 层的影响

model.train() BN做归一化时,使用的均值和方差是当前这个Batch的如果这时 track_running_statsTrue, 则会更新running_mean 和 running_var但是,running_mean 和 running_var不用在训练阶段 model.eval() BN 做归一化时,使用的…

联想用u盘重装系统步骤_详解联想如何使用u盘重装win10系统

联想是国内知名的品牌之一,很多朋友都购买了联想品牌的电脑,但是在使用的过程中难免会出现些磕磕碰碰的问题。所以今天小编就大家详细的介绍一下联想电脑使用u盘重装win10系统的方法。联系怎么使用u盘重装win10系统呢?最近有不少朋友在询问这…

笔记本电脑键盘切换_真想本小新13pro搭档,笔记本电脑周边好物清单推荐

原标题:真想本小新13pro搭档,笔记本电脑周边好物清单推荐真想本小新13pro搭档,笔记本电脑周边好物清单推荐 2020-10-24 15:21:493点赞4收藏2评论9月28日 - 11月12日,参与#双11购物攻略#征稿活动,赢取苹果全家桶8888元超…

pytorch 训练模型很慢,卡在数据读取,卡I/O的有效解决方案

多线程加载 在 datalaoder中指定num_works > 0,多线程加载数据集,最大可设置为 cpu 核数设置 pin_memory True, 固定内存访问单元,节约内存调度时间示例如下: loader DataLoader(dataset,batch_sizebatch_size * group_size,shuffleTr…

python达梦数据库_python 操作达 梦数据库

python 达梦数据库操作流程连接数据库 dm.connect( ... )获取游标 dm_conn.cursor()编写SQL语句 sql_str执行SQL语句 dm_cursor.execute()获取结果列表 dt_breakpoint dm_cursor.fetchall()关闭游标 dm_cursor.close()关闭数据库连接 dm_conn.close()代码示例import pandas as…

C++求复数的角度_11.初中数学:方程5x2m=4x的解,在2与10之间,怎么求m的取值范围?...

欢迎您来到方老师数学课堂,请点击上方蓝色字体,关注方老师数学课堂。所有的视频内容,全部免费,请大家放心关注,放心订阅。初中数学:方程5x-2m-4-x的解,在2与10之间,怎么求m的取值范围…

python3 beautifulsoup 模块详解_关于beautifulsoup模块的详细介绍

这篇文章主要给大家介绍了python中 Beautiful Soup 模块的搜索方法函数。 方法不同类型的过滤参数能够进行不同的过滤,得到想要的结果。文中介绍的非常详细,对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。前言我们将利用 Beautifu…

python解zuobiaoxi方程_欧式期权定价的python实现

0. pre 在《给你的二叉树期权定价》中就挖了坑要写期权定价的代码,这会有时间来填坑啦。本文将会用python实现欧式期权定价。具体的定价算法分别是基于BS公式的、蒙特卡洛的以及二叉树的。对于二叉树和BS公式还不熟悉的小伙伴可以移步至往期关于二叉树期权定价和BS公…

去除标签_有效去除“狗皮膏药”标签,快学起来吧

去除商品标签向来是比较头疼一件事,有时候在去掉标签后会留下粘性残留物,它会粘上灰尘和其他脏东西,把表面变成脏兮兮的颜色,让人看着太不舒服了。其实去除标签残留粘胶并不难,可能家里就有去除它的工具哦~那今天小编就…

win10很多软件显示模糊_还在使用第三方软件?Win10可以直接显示显卡温度啦

微软刚刚开始向参与快速通道测试的用户推送Windows 10 20H1 Build 18963 版带来部分新功能和优化等。这个版本也是常规优化版本因此带来的新功能很少,但这次更新为任务管理器带来原生的显示显卡温度功能。用户打开任务管理器点击性能选项卡然后找到「独立显卡」即可…

分数怎么化成带分数_小升初数学总复习第三个基础模块:分数的认识

今天我们开始小升初数学总复习第三个基础模块的复习:分数的认识分数的认识一共分为8个知识考点。第一,分数的意义把单位“1”.平均分成若干份,表示这样的一份或者几份的数叫做分数。表示其中一份的数叫做分数单位。第二&#xff0…