2021-07-30笔记

3.集合框架

3.1 Collection集合

3.1.1存储特点

Collection接口时单列集合的顶级接口。在这种集合中存储的数据,只占一列。所有的元素,直接存储与各种数据结构中。

Collection集合中,没有下标的概念

3.1.2 Collection API

  • 接口方法

由于这个接口时单列集合的顶级接口,在这里定义的所有方法,在所有的实现类中都是可以使用的。

修饰&返回值方法描述
booleanadd(E element)将一个指定类型的元素添加到集合的末尾
booleanaddAll(Collection coll)批量添加,将一个集合中的所有的元素,添加到当前集合的末尾
booleanremove(E ele)删除集合中指定的元素
booleanremoveAll(Collection coll)删除集合中所有的在参数集合中存在的元素(删除交集)
booleanretainAll(Collection coll)保留集合中所有的在参数集合汇总存在的元素,删除其他元素(保留交集)
voidclear()清空集合中的所有的数据
booleanremoveIf(Predicate predicate)删除集合中满足指定条件的数据
booleancontains(E ele)判断一个集合中是否包含指定的元素
booleancontiansAll(Collection coll)判断参数集合中,是否所有的元素都在当前集合中包含。
intsize()获取集合中元素的数量,类似于数组length
booleanisEmpty()判断一个集合是否是空集合
Object[]toArray()将集合中的元素,转成Object数组
T[]toArray(T[] arr)将集合中的元素,转成指定类型的数组

3.1.3Collection集合遍历

3.1.3.1迭代器(Iterator)

工作原理 

  • 使用集合的iterator()方法,获取到一个迭代器对象

原因:迭代器在对集合进行遍历时,要与对应的集合产生关系,通过集合的一个方法获取迭代器对象,可以在方法内部创建迭代器对象,同时自动与当前集合产生关系,对于使用者来说简化了代码
  • 这个迭代对象,内部维护了一个引用,指向集合中的某一个元素。默认指向-1位

  • 使用next()方法,向后移动一位元素指向,并返回新的指向元素

  • 如果使用next()方法,向后移动指向的时候,以及超出了集合的范围,指向了一个不存在的元素,会抛出异常NoSuchElenmentException

  • 一般情况下,配合hasNext()方法一起使用的。

注意事项

在使用迭代器进行元素的遍历过程中,不要使用集合的方法修改集合中内容!!!否则会出现ConcureentModificationException。可以使用迭代器自带的remove()方法操作

对出现ConcurrentModificationException异常的解释(扩展内容)

Fail-Fast机制:
    我们知道java.util.ArrayList不是线程安全的,因此如果在使用迭代器的过程中有其他线程修改了list,那么将抛出ConcurrentModificationException,这就是所谓的fall-fast策略。
    这⼀策略在源码中的实现是通过modCount域,modCount顾名思义就是修改次数,
对ArrayList内容的修改都将增加这个值,那么在迭代器初始化过程中会将这个值赋给
迭代器的expectedModCount。
[java] view plain copy
1.HashIterator() {
2.  expectedModCount = modCount;
3.  if (size > 0) { // advance to first entry
4.      Entry[] t = table;
5.      while (index < t.length && (next = t[index++]) == null)
6.          ;
7.      }
8.}
在迭代过程中,判断modCount跟expectedModCount是否相等,如果不相等就表示已
经有其他线程修改了list:
 注意到modCount声明为volatile,保证线程之间修改的可⻅性。
[java] view plain copy
1.final Entry<K,V> nextEntry() {
2. if (modCount != expectedModCount)
3. throw new ConcurrentModificationException();
 在HashMap的API中指出:
 由所有ArrayList类的“collection 视图⽅法”所返回的迭代器都是快速失败
的:在迭代器创建之后,如果从结构上对映射进⾏修改,除⾮通过迭代器本身的
remove ⽅法,其他任何时间任何⽅式的修改,迭代器都将抛出
ConcurrentModificationException。因此,⾯对并发的修改,迭代器很快就会
完全失败,⽽不冒在将来不确定的时间发⽣任意不确定⾏为的⻛险。
 注意,迭代器的快速失败⾏为不能得到保证,⼀般来说,存在⾮同步的并发修改
时,不可能作出任何坚决的保证。快速失败迭代器尽最⼤努⼒抛出
ConcurrentModificationException。因此,编写依赖于此异常的程序的做法是
错误的,正确做法是:迭代器的快速失败⾏为应该仅⽤于检测程序错误。

3.1.3.2增强for循环

注意事项:

在使⽤增强for循环进⾏元素的遍历过程中,不要修改集合中的内容 !!! 否则, 会出现 ConcurrentModificationException 。

原因:增强for循环内部实际调⽤的是⼀个迭代器

3.1.3.3forEach

java8之后,在Collection集合中添加了一个新的方法forEach

方法原型:

default void forEach(Consumer<? super T> action)

方法逻辑:

将集合中的每一个元素,代入到参数Consumer函数式接口的方法中,作为参数,在调用这个方法的时候,可以自定义实现的方式。

3.2 List集合

3.2.1存储特点

List集合是单列集合,是Collection接⼝的⼦接⼝。Collection接⼝中所有的⽅法,这 ⾥都有。同时,这个集合⽐Collection集合,多个若⼲⽅法。

在List接⼝中,是有下标的概念的。多出来的这些⽅法,基本也都是围绕着下标操作 的。

3.2.2 List与Set对比

  • List:存储的数是有序的(元素的存储顺序与添加元素的顺序一致),可以重复的。

  • Set:存储的数据是无序的,不可以重复

3.2.3 List ApI

修饰&返回方法描述
voidadd(int index, E element)向集合中指定的下标位插入一个元素。
voidaddAll (int index,Collection coll)在集合中指定的下标位插入另外一个集合中所有的数据。
Eremove(int index)删除集合中指定下标位的元素
Eset(int index,E element)修改指定下标位的值
Eget(int index)获取指定下标位的元素
intindexOf (E element)获取集合的某一个元素第一次出现的下标
intlastIndexOf (E element)获取集合中的摸一个元素最后一次出现的下标
ListsubList(int formIndex,int toIndex)从一个集合中,截取一部分,作为子集合。[from,to)。
voidreplaceAll (UnaryOperator operator)将集合中的元素带入到接口方法中,用返回值替换原来的元素
voidsort(Comparator comparator)将集合中的元素进行升序排序

3.2.4 List集合排序

在List接口中,提供了一个排序的方法sort

方法原型

default void sort(Comparator<? super E> c)

方法逻辑

这是系统封装好的一个用来做排序的方法,由于集合中只能存储引用数据类型的数据,因此,需要明确两个元素的大小关系。参数Comparaor是一个对象大小比较的接口。在这个接口的方法中,有两个参数,分别表示参与比较的两个对象。返回值是int类型,不看具体的值,只看正负。

3.2.5 List集合遍历

有与List接口是继承自Collection接口的,因此在Collection部分的三种遍历方式,都可以用来遍历List集合,同时在List集合中,还添加了两种用来遍历集合的其他方式。

  • 下标遍历

顾名思义,类似于数组的下标遍历。遍历集合中的所有的下标,依次获取指定下标位的元素。

  • 列表迭代器

这种⽅式, 类似于迭代器。 在List集合中, 有⼀个⽅法 listIterator() , 可以获 取到⼀个 ListIterator 接⼝的引用。 ⽽ ListIterator 是 Iterator 的子接⼝。 因此在保留了传统的迭代器的迭代⽅法的基础上, 还添加了若⼲个其他的⽅法。

ListIterator 中新增了hasPrevious()和previous()⽅法 当我们使⽤hasnext()和next()⽅法实现从左到右遍历后,可以继续使⽤使⽤ hasPrevious()和previous()⽅法从右到左遍历.

使⽤ListIterator, 在遍历集合中的元素的同时, 可以向集合中添加元素、删除
元素、修改元素。
但是, 这⾥对集合中的元素操作, 并不是使⽤ List 接⼝中的⽅法, ⽽是⽤
ListIterator 接⼝中的⽅法完成。

4. List详解

4.1 ArrayList与LinkedList对比

  • 相同点:

    • 都是List集合的常用的实用类

    • 对集合中的元素操作的方法基本一致

    • 都是线程不安全的

  • 不同点:

    • ArrayList底层实现是数组,使用数组这种数据结构进行数据的存储

    • LinkedList底层实现是双链表,使用双链表这种数据结构进行数据的存储

数组与链表结果特点比较:

  • 数组实现功能时查找快,添加删除慢

  • 链表查找慢,添加删除快

ArrayList与LinkedList的使用场景

  • 对集合中的元素,增删操作不怎么频繁,查询操作比较频繁。使用ArrayList。

  • 对集合中的元素,增删操作比较频繁,查询操作不怎么频繁。使用LinkedList。

4.2集合对自定义对象的存储

  • 类分成系统类和⾃定义类

  • 系统类往往已经重写了tostring(),equals(),hashcode()等⽅法

  • ⾃定义类,为了实现我们的功能,往往我们需要重写⽗类的常⽤⽅法,⽐ 如:tostring(),equals(),hashcode()

4.3LinkedList

对于LinkedList的特有方法对比:

jdk1.6以前的删除获取方法,拿不到元素报异常

jdk1.6以后的删除获取方法,拿不到元素返回null

4.4数据结构

4.4.1数据结构定义

数据结构是计算机存储、组织数据的⽅式,是相互之间存在⼀种或多种特定关系的数 据元素的集合,即带“结构”的数据元素的集合。“结构”就是指数据元素之间存在的关 系,分为逻辑结构和存储结构.通常情况下,精⼼选择的数据结构可以带来更⾼的运行或者存储效率。

数据的逻辑结构和物理结构是数据结构的两个密切相关的⽅⾯,同⼀逻辑结构可以对应不同的存储结构。算法的设计取决于数据的逻辑结构,⽽算法的实现依赖于指定的存储结构.

4.4.2数据的逻辑结构

指反映数据元素之间的逻辑关系的数据结构,其中的逻辑关系是指数据元素之间的前 后间关系,⽽与他们在计算机中的存储位置⽆关。逻辑结构包括:

  • 集合:数据结构中的元素之间除了“同属⼀个集合” 的相互关系外,别⽆其他关 系;

  • 线性结构:数据结构中的元素存在⼀对⼀的相互关系;

  • 树形结构:数据结构中的元素存在⼀对多的相互关系;

  • 图形结构:数据结构中的元素存在多对多的相互关系。

4.4.3数据的物理结构

指数据的逻辑结构在计算机存储空间的存放形式。

4.4.4常用的数据结构

程序设计中常⽤的数据结构包括如下⼏个。注意:这⾥的数据结构分类是从逻辑结构 上进⾏的.

  • 数组(Array)

数组是⼀种聚合数据类型,它是将具有相同类型的若⼲变量有序地组织在⼀起的集 合。数组可以说是最基本的数据结构,在各种编程语⾔中都有对应。⼀个数组可以分 解为多个数组元素,按照数据元素的类型,数组可以分为整型数组、字符型数组、浮 点型数组、指针数组和结构数组等。数组还可以有⼀维、⼆维以及多维等表现形式。

  • 栈(Stack)

栈是⼀种特殊的线性表,它只能在⼀个表的⼀个固定端进⾏数据结点的插⼊和删除操 作。栈按照后进先出的原则来存储数据,也就是说,先插⼊的数据将被压⼊栈底,最 后插⼊的数据在栈顶,读出数据时,从栈顶开始逐个读出。栈在汇编语⾔程序中,经 常⽤于重要数据的现场保护。栈中没有数据时,称为空栈。

  • 队列(Queue)

队列和栈类似,也是⼀种特殊的线性表。和栈不同的是,队列只允许在表的⼀端进⾏ 插⼊操作,⽽在另⼀端进⾏删除操作。⼀般来说,进⾏插⼊操作的⼀端称为队尾,进 ⾏删除操作的⼀端称为队头。队列中没有元素时,称为空队列。

  • 链表( Linked List)

链表是⼀种数据元素按照链式存储结构进⾏存储的数据结构,这种存储结构具有在物 理上存在⾮连续的特点。链表由⼀系列数据结点构成,每个数据结点包括数据域和指 针域两部分。其中,指针域保存了数据结构中下⼀个元素存放的地址。链表结构中数 据元素的逻辑顺序是通过链表中的指针链接次序来实现的。

  • 树( Tree)

树是典型的⾮线性结构,它是包括,2个结点的有穷集合K。在树结构中,有且仅有 ⼀个根结点,该结点没有前驱结点。在树结构中的其他结点都有且仅有⼀个前驱结 点,⽽且可以有两个后继结点,m≥0。

  • 图(Graph)

图是另⼀种⾮线性数据结构。在图结构中,数据结点⼀般称为顶点,⽽边是顶点的有 序偶对。如果两个顶点之间存在⼀条边,那么就表示这两个顶点具有相邻关系。

  • 堆(Heap)

堆是⼀种特殊的树形数据结构,⼀般讨论的堆都是⼆叉堆。堆的特点是根结点的值是 所有结点中最⼩的或者最⼤的,并且根结点的两个⼦树也是⼀个堆结构。

  • 散列表(Hash)

散列表源⾃于散列函数(Hash function),其思想是如果在结构中存在关键字和T相等 的记录,那么必定在F(T)的存储位置可以找到该记录,这样就可以不⽤进⾏⽐较操作 ⽽直接取得所查记录。

5.泛型

5.1泛型在类中的使用

5.1.1语法部分

定义:在类名的后⾯, 紧跟上⼀对尖括号

class Animal <T> {}
class Dog <T, M> {}

泛型类的使用:声明引⽤、实例化对象、被继承。

// 1. 声明引⽤
Animal<String> animal;
// 2. 实例化对象
Animal<Integer> animal = new Animal<>();
// 3. 被继承
class Dog extends Animal<String> {}
class Dog<T> extends Animal<T> {}

5.1.2泛型类的特点

  • 在类中定义的泛型, 虽然还不明确是什么类型, 但是在当前类中是可以使⽤ 的。

  • 在使⽤到这个类的时候, 必须要指定泛型的类型。 如果不指定, 默认是Object。

  • 泛型, 只能在当前的类中使⽤, 不能在其他的类中使⽤, 包括⼦类。

5.2泛型在接口中的使用

5.2.1 语法部分

泛型接口的定义: 在接⼝名字的后⾯, 添加上⼀对尖括号。 在尖括号⾥⾯定义泛型。

interface MyInterface<T> {}
interface MyInterface<T, M> {}

泛型接口的使⽤: 实现类实现接⼝、使⽤接⼝访问接⼝中的静态成员、被继承。

// 1. 实现类实现接⼝
class MyInterface1Impl implements MyInterface1<Person> {}
// 2. 被继承
interface SubMyInterface extends MyInterface1<String> {}

5.2.2泛型接口的特点

  • 在接⼝中定义的泛型, 虽然还不明确是什么类型, 但是在当前接⼝中是可以使 ⽤的。

  • 在使⽤到这个接⼝的时候, 必须要指定泛型的类型。 如果不指定, 默认是 Object。

  • 泛型, 只能在当前的接⼝中使⽤, 不能在其他的接⼝中使⽤, 包括⼦接⼝。

5.2.3子类使用接口泛型

这⾥有两种情况: 第⼀种:⼦类与接⼝泛型⼀致,接⼝可以直接使⽤泛型类型

第⼆种:接⼝使⽤泛型,⼦类不⽤,在实现的接⼝位置必须指定⼀个具体的数据类型

5.3泛型在方法中的使用

5.3.1语法部分

定义: 泛型⽅法中, 在定义⽅法时,在返回值前⾯通过定义泛型

public static <T> void test(T t) {
​
}
  • 在定义处的<>⽤来定义泛型

  • 在调⽤处的<>⽤来使⽤泛型

5.3.2泛型方法的分类

  • 第⼀:⽅法上的泛型与类上的⼀致

  • 第⼆:⽅法上独⽴使⽤泛型

    • 在⽅法中定义的泛型,虽然还不明确是什么类型,但是在当前⽅法中是可以使⽤的。

    • 泛型⽅法,在使⽤的时候,不能跟类、接⼝似的,⼿动的设置类型。 泛型⽅法中,泛型的设置,在参数中体现。

    • 泛型⽅法,⼀定需要是有参的。参数列表中,必须有泛型类型。

    • 泛型⽅法中的泛型的设置,是通过在调⽤⽅法的时候,实参的类型推导出 来的。

    • 泛型,只能在当前的⽅法中使⽤, 不能在其他的⽅法中使⽤

  • 第三:静态⽅法使⽤泛型

5.4关于java中?的使用总结

  • ⽤于?: 这⾥是三⽬运算符⼀部分,前⾯是判断条件,后⾯是两个分⽀结果

  • ⽤于数据库的sql语句 select * from emp where name=? :表示占位符

  • ⽤于泛型,是通配符,表示任意⼀种数据类型.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值