学习日志_07 集合

1、Collection

1.1.概述

集合可以理解为数据结构的封装,集合分为List和Set,根据不同的特性及操作性能进行分类

集合用于保存多个元素,但是只能保存一种数据类型,那就是Object

因为Object是java提供的根类,所以能够保存任意数据

因为数据都可以向上转型为Object,发生多态

集合和数组不同的是,集合只能存储对象,数据可以存储任意的数据类型。

1.2.继承体系

Collection(集合)分为List和Set

其中List有序可重复,Set无序不可重复

LIst又分为ArrayList和LinkedList,其中ArrayList具有数组特性,LinkedList具有链表特性

Set分为TreeSet和HashSet,其中TreeSet具有二叉树特性,HashSet具有散列表特性

在这之外,集合因为有序列特性,所以具有迭代器功能来帮助集合进行遍历

1.3.集合常用方法

增加元素:add(element);

移除元素:remove(element)

 判断集合是否包含某个元素:contains(elements),返回boolean型

返回集合中元素的数量:size();

清空集合中的元素:clear();

判断集合是否为空: isEmpty();

1.4.迭代器

1.4.1.迭代器是什么

Interator是迭代器

迭代器是一种设计模式,它可以使对于序列类型的数据结构遍历行为与被遍历的对象分离

也就是说我们不需要关心他底层是什么数据结构,也不需要关心这个数据结构如何去存储

而集合中获取迭代器只需要调用一个方法

Iterator it = 集合对象.iterator();

迭代器有三个方法

hashnext():判断还有没有数据,如果有就返回true,没有就返回false;

next:将光标向下移动一位,并且返回该数据。 注意:光标一旦向下就不能回到原处,只能向一个方向前进。

remove:删除当前光标指向的数据

迭代器一旦创建就不能对数据进行修改,如果需要操作集合数据,就需要重新生成迭代器

1.4.2.迭代器的使用

在使用迭代器时只需要注意四点 

1生成集合 2hashNext用于循环  3.next()用于返回当前光标数据  4.remove()用于删除当前光标元素

注意iterator迭代器不是简单的记录集合里的数据,迭代器里数据的改变会让原集合数据发生改变,而原集合数据不通过迭代器来改变会导致迭代器出错。

1.4.3.forEach

forEach是增强for循环,是iterator的简写方式,写起来方便

但是功能不太全,没有删除功能,如果要在遍历时进行删除,则需要使用iterator

如果只是要遍历,则可以用forEach。

2.List

2.1.概述

List特性:有序可重复

有序:添加顺序和取出顺序一致

可重复:可以保存相同的数据

ArrayList:底层是一个Object数组,查询和修改效率极高,随机性添加和删除效率较低,适合二分法查找

LinkedList:底层是一个双向链表,随机性添加和删除效率较高,但是查询和修改效率较低

2.2.ArrayList

常用方法如下:

2.3.LinkedList

LinkedList底层是一个双向链表,链表中保存节点对象保存三个属性

1.当前保存的数据  2.下一个节点对象  3.上一个节点对象

LinkedList和ArrayList操作一样,虽然LinkedList中也可以根据下标进行操作

但是本质还是循环,因为链表中并没有下标,所以查询效率依然不如ArrayList。

LinkedList内部有一个节点类,保存着三个数据,分别是数据,下一个节点对象,上一个节点对象

LinkedList保存着节点的长度,首节点和尾节点。

2.3.2.使用方式

2.3.3.底层实现

LinkedList是双向链表,当数据添加时调用add(e)时,其底层会调用linkLast(E e)方法。在这个方法中,会有一个节点保存链表的最后一个节点,一个保存了新增数据的新节点会生成,然后让新节点替换掉最后一个节点(最后一个节点的数据已经被保存了,可以放心替换)如果最后一个节点为空,代表此链表为空,也就是size=0,这时让首节点保存最新节点的数据,否则就让最后一个节点的下一个节点保存最新节点。

3.Set

3.1.概述

特性:无序不可重复

无序:不保证有序,存入顺序会被打乱,但是因为在随机的顺序中可能与存入的顺序一致,因此这里的无序又是不保证有序。

不可重复:无法保存相同的数据。

HashSet:底层是HashMap,本质上是散列表

TreeSet:底层是TreeMap,本质上是链表/红黑树,会自动转化。

3.2.HashSet

3.2.TreeSet

TreeSet会自动排序,因此,TreeSet内的元素必须支持排序,即实现了comparator或者comparable接口,并且必须是相同类型的数据.

排序默认是升序,若想降序需要覆写comparaTo方法。

4.排序

4.1.概述

为什么会自动排序?因为被添加的元素类实现了Comparable接口并覆写了comparTo方法

不能排序的数据因为没有Comparable或者Comparator,所以不能使用TreeSet

4.2.Comparable

在自定义的类中,没办法放到自动排序的集合中,这时候需要实现Comparable接口并覆写compareTo方法就能实现类的自动排序.返回的数值大于0,代表调换两个数据的位置,其他则不变.

4.3.Comparator

Comparator是比较器,但是要添加的元素不需要实现这个接口,该接口对象需要传入到集合构造方法中

*两个比较接口的应用场景:

当我们保存了Java中可以自动排序数据在集合中,但是默认是升序,而我们的需求是降序,我们又不能去修改Java自带的类,没办法去覆写compareTo方法,,所以我们可以使用comparator来进行功能扩展.

另外当Comparable和Comparator同时存在时,Comparator优先级大于Comparable,因为实现comparable接口的类具有一定的入侵性,而使用comparator比较器则不会产生入侵性.

总结:当要添加的元素是我们自己写的类时,使用comparable并覆写ComparaTO方法,或者在集合构造时引入比较器comparator方法.

当要添加的元素不是我们写的类的时候,并且不满足我们的排序要求,使用Comparator来解决

下面是comparator的用法:

直接在集合的构造方法中放入一个comparator的对象,并且覆写了compare方法.

5.散列表

5.1.概述

散列表是Hash table ,即哈希表,特征就是存储键值对,根据键值对直接访问的数据结构.

5.2.底层实现

散列表是由数组和链表组成,但是在Java中1.8之前,存储数据就是数组,链表加上hashCode()组成,Key值通过HashCode()获取到hash值,对数组长度取余得到数组下标,如果value值存在,则替换,如果不存在,则添加到链表

5.3.HashMap

5.3.1.HashMap常用方法

.put(K,V) 向Map中添加键值对
.size() 获取Map中键值对数量
.get("K") 根据键获取值
.containsKey("K") 判断是否包含某个键
.containsValue("V") 判断是否包含某个值
.values() 将Map中所有的值封装到集合中返回
.KeySet() 将Map中所有的键封装到集合中返回
.entrySet() 将Map中所有的键值对封装到集合中返回

5.4.TreeMap

5.4.1.TreeMap特性;

TreeMap会根据键自动排序,因此添加的数据需要实现comparable接口或者集合TreeMap实现比较器的方法重写.

6.泛型

作用:泛型能够在编译时效验数据类型是否准确.

6.1.泛型的使用

我们在创建集合时,会跟随一个尖括号产生,如果删除则默认泛型为Object类,因此,泛型必须是引用类型,如果要放入整形等非引用数据类型,需要将数据改成包装类,如Interage包装类.

6.2.自定义泛型

在自定义泛型时要注意几点规则:

泛型的命名,出自方便其他人读懂代码的需求,需要有固定的命名方式,

E:表示集合中的元素

K:表示键,一般用于Map

V:表示值,一般用于Map

?:表示不确定的Java类型

T:表示确定的Type类型

N:表示数字

另外:如果自定义的泛型还有<T extends 某个类>表示继承某个类的类

猜你喜欢

转载自blog.csdn.net/DA_YA_/article/details/139725746