Java基础(十二)——内部类、集合(ArrayList、ArrayList扩容、LinkedList、相关底层实现、Stack、Queue、迭代器)、泛型初了解

Java基础(十二)

一、内部类

面向对象的时候学了类的概念以及使用。其实在类的内部,还可以创建类,这种叫内部类。

内部类有四种:
1、成员内部类
2、局部内部类
3、静态内部类
4、匿名内部类(重点)

1、成员内部类

成员内部类。在类的内部,再创建一个类,就是成员内部类:
在这里插入图片描述
想要调用内部类,需要先创建外部类,通过外部类创建内部类,再去调用内部类的属性跟方法:
在这里插入图片描述

2、局部内部类

局部内部类,就是在类中的方法里面,再创建类,因为这个类的作用范围在方法里面,所以是局部内部类:
在这里插入图片描述

调用方式:
在这里插入图片描述

通过外部类调用方法即可调用。

3、静态内部类

类中再创建一个静态的类,就是静态内部类。
在这里插入图片描述
类比静态方法/属性,类可以直接调用,所以静态类,也可以被类直接调用:
在这里插入图片描述

4、匿名内部类(重点)

作用:减少了类的创建,只适用于对象的方法只调用一次或者少次。

创建方式:
先写一个接口:
在这里插入图片描述

接着,通过匿名内部类的方式去重写;
在这里插入图片描述

二、集合

集合分为两大块:
一个是Collections,一个是Map。

	迭代器(只服务于Collection以及底下的那些集合)
	CollectionsList:(有序可重复)
				ArrayList
				LinkedList
				Vector
				Stack
		SetTreeSet
			HashSet
		QueueLinkedList
	MapTreeMap
		HashMap

1、ArrayList——动态数组

ArrayList 数组与之前那个数组不同,该数组当容量满了会自动扩容。且该数组储存不再需要同一类型,而是不同类型的都能存储,因为该数组存储的是对象。

ArrayList 数组与之前用过的数组使用方式不太一样。下面了解该数组的增删改查方式:

a、添加与获取数据

在这里插入图片描述

b、修改

在这里插入图片描述

c、中间插入元素

在这里插入图片描述

在索引1 这个位置插入 ’ f '。

d、根据索引删除元素

在这里插入图片描述

这里删除用 remove 关键字,这里是删除索引为 2 处的位置。

e、根据对象删除元素

数组里面有个 1 ,如果想要删除 1,不能直接用数字1去删,因为这里面的元素不再是属性,而是一个个对象:
在这里插入图片描述

f、foreach循环

在这里插入图片描述

g、add()/addAll()添加集合

再创建一个集合,并把这个集合加到前面的集合中去:
在这里插入图片描述
可以看到里面多了个集合,有个中括号。

如果不想要这个中括号,使用addAll():
在这里插入图片描述

2、ArrayList动态数组如何自动扩容

a、ArrayList扩容解读

ArrayList动态数组如何自动扩容呢?直接查看其源码:

下面代码注释中,红色为第一次执行,蓝色为第二次执行,绿色为第三次执行:
在这里插入图片描述

b、扩容总结

解释:
ArrayList 底层是动态数组,通过无参构造方法创建集合对象,第一次添加对象时,容量会扩容到10,当容量满的时候再添加对象会扩容到原来的倍。

缺陷:
1、长度有限:数组哪怕可以扩容,也有其最大限制。该限制就是 int 类型的最大值。
2、当删除中间元素时,后面的所有元素都需要往前挪一位,意味着整体结构需要改变。中间增加元素也一样的。

3、LinkedList

a、用法

用法跟上面的 ArrayList 数组一模一样,用 LinkedList 去替换即可。

b、LinkedList 实际是一个双向链表

其实 LinkedList 就是一个双向链表:
在这里插入图片描述

c、LinkedList 底层实现代码

同样的,红色是第一次执行,蓝色是第二次执行、绿色是第三次执行。
在这里插入图片描述

d、LinkedList总结

LinkedList :底层是双向链表,first属性指向第一个节点,不存在索引,理论上长度无限。

4、ArrayList 对比LinkedList

1、ArrayList 底层是动态数组,LinkedList 底层是双向链表。
2、ArrayList 查询比 LinkedList 更快。
3、如果不需要扩容,ArrayList 末尾追加比 LinkedList 更快。
4、修改对象 ArrayList 比 LinkedList 更快。
5、中间插入和中间删除不同情况效率不一致。
6、ArrayList 长度有限,LinkedList 理论上长度无限。

5、Vector

Vector:元老级别的集合,底层是动态数组,线程安全的集合。

了解即可

6、Stack——模拟栈的集合

栈的特点是:用完即删,后进先出(LIFO)。

用法:
在这里插入图片描述

注意:此处取出数据不可用 for 循环,因为取出栈顶数据后,栈顶就变成 null ,而 for 循环时,会循环到 null 这部分,导致不能把所有元素都遍历出来。

7、Queue——模拟队列的集合

特点:用完即删,先进先出。
在这里插入图片描述

8、迭代器

用 for 循环和 foreach 循环遍历 ArrayList 数组,可以发现输出结果。如果查看其编译文件,就会发觉有很大不同:
在这里插入图片描述

foreach 循环这种遍历方式,就是迭代器。foreach 循环本质上就是调用迭代器。

既然 foreach 循环本质上是调用迭代器,那么何不自己写,自己调用呢?
在这里插入图片描述

其中,hashNext 指向的方向根据 next 指向的方向,意思是,next 指哪,hashNext 就指哪。
在这里插入图片描述

三、泛型初了解

1、引子

ArrayList 数组可以存不同类型的对象,如果只想让它存一种类型的呢?
在这里插入图片描述

可以看到,即便只想存储对象类型,后面还是可以存储其他类型,因为少了约束。

这里就需要用到泛型,因为泛型可以限制集合的类型。

2、用法

用法:
只需要加个尖括号 <>,就能起到限制作用:
在这里插入图片描述

可以看到,一加上,其他不是这种类型的都有红线。

为什么能够这样去使用呢?

3、了解底层代码

在这里插入图片描述
可以看到类那里多了个尖括号,传递 User 进来,这里就会变成User。再查看 add 方法:
在这里插入图片描述
也是同样的。

所以,泛型就是约束了集合存储对象的数据类型。

4、尝试写一个泛型

在这里插入图片描述

接着就是静态方法:
在这里插入图片描述

静态方法这么写会报错,因为静态方法优先于对象加载进内存,所以这么写不行,这么写这个static 后面的 K,意味着由对象来决定返回值类型。所以这里需要自己定义类型,所以需要自己在前面加:
在这里插入图片描述

然后,自己创建对象:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41824825/article/details/121253127