java17

发布时间:2024年01月23日

集合

  • Java集合是使程序能够存储和操纵元素不固定的一组数据。 所有Java集合类都位于java.util包中。

为什么要有集合

  • 之前我们需要把多个元素放到一起的时候,使用的是数组。那么为何还要提供Java集合工具类呢?
  • 数组没有提供方法, 操作比较繁琐, 长度不可变, 所以适当进行封装,提高开发效率和使用难度.
  • 注意 : 如果集合中存放基本类型,一定要将其 “装箱”成对应的”基本类型包装类”。 如int类型的就要存放Integer. ( 集合 不能存放基本数据类型,只能存放对象的引用 )

Collection集合的家族

图片1

  • Collection 表示一组对象,它是集中、收集的意思。Collection接口的两个子接口是List、Set接口。

  • List 特性 : 有序 可重复,保证数据的添加顺序和取出顺序一致

  • Set 特性 : 无序 不可重复,不能保证数据的添加和取出顺序一致

Collection

  • Collection作为集合类的父类,所以,collection中的方法,是所有集合类都有的方法
  • 下面方法都是Collection的所以继承他的所有集合家族都会拥有这个方法(覆写)
  • Collection接口中没有定义查询和修改的方法,是因为它的子接口有不同的实现方式,不能用一个统一的方法来查询和修改它们的元素。

常用方法

添加
  • add(Object)
// 这里 ArrayList 间接继承了 Collection(接口并不包含实现) 所以用实现了他方法的ArrayList进行展示.
Collection c1 = new ArrayList();  //这里发生了多态父类引用指向子类对象, 多态会丢失子类特有属性,所以可以证明下面方法都是Collection定义的. 
// Collection
c1.add(11); // 此时在ArrayList中 11会自动包装变为Integer类型 传入后因为父类引用指向子类对象发生多态, 内部实际保存时Object类型. 所以可以传入所有继承object类型的类
删除
  • 根据内容进行删除 (因为只有list才可以按顺序查找删除 set里并没有办法删除, 所以在Collection中只定义了 根据内容删除)
  • c1.remove("a"); 其余内容和上面一样
元素个数
  • 返回集合中已有元素个数
  • c1.size()
清空集合
  • 清空集合
  • c1.clear();
判断是否为空
  • 判断是否个数为0 , 而不是null
  • c1.isEmpty()
转为数组
  • 转为数组并返回
  • c1.toArray()

Iterator 迭代器

  • Interator 迭代器,屏蔽了不同数据结构的底层结构差异性,提供了遍历的统一方式
  • 迭代器有三种方法
  • hasNext() 如果还有下一个元素就返回true, 如果没有就返回false
  • next() 返回当前指向的元素返回,并让光标指向下一个元素
  • remove() : 删除当前指向的元素,当使用迭代器时,想要删除数据,只能使用迭代器的删除.
    • 为什么集合里面有删除迭代器还会有一个remove呢
    • 因为只要迭代器生成,那么集合中就不能添加或删除元素,如果需要添加或删除,则需要重新生成迭代器
    • 因为迭代器要保护自己的安全, 如果在迭代器遍历的时候集合就改了元素的内容, 会导致迭代器可能出错, 所以迭代器有个快速失败机制 集合中会有一个modCount变量记录集合中的任何操作的修改如果修改就 + 1 当创建迭代器的时候, 会把这个集合当前的修改次数赋值给迭代器, 每次执行操作的时候就会比较迭代器中modCount的值, 和集合中的值是否相等, 如果不等就抛出异常.

迭代器工作原理

  • 迭代器会有两个指针一个指针负责判断是否还有元素是否还有元素如果有就返回true, 如果没有就返回false hasNext()
  • 第二个指针负责返回值 没返回一个值就往后移动一次 如果当前指向的没有元素就会抛出异常 (执行后会指向当前元素, 执行完后就同停在当前元素) next()

使用迭代器

// 创建集合
Collection c1 = new ArrayList();
// 向集合中添加元素
c1.add("a");
c1.add("b");
c1.add("c");
// 创建迭代器
Iterator it = c1.iterator(); // iterator()是创建迭代器并放回的方法 集合中包含
while (it.hasNext()) { //判断是否有下一个元素
	Object o = it.next();
	System.out.println(o);
	if (o.equals("a")) {
		// 需要使用迭代器的删除,不过一般不会删除的
			t.remove();
	}
}
// 迭代器使用完后,光标不会自动复原,此时还指向最后一个元素呢, 想要再次使用,只能重新生成
it = c1.iterator();

forEach

  • 增强for循环,
  • 使用增强for循环时,也不能对集合进行添加和删除 ( 底层实现方式就是迭代器 )
  • 语法 for(数据类型 变量 : 集合/数组){ 循环体 }
Collection c1 = new ArrayList();
for(Object o : c1){
	// 循环的内容如打印
}

List

  • List 有序的可重复的,
  • 有序 : 添加和取出顺序一致,队列操作
  • 可重复 : 可以存储重复数据

ArrayList

  • ArrayList底层是数组, 查询和就该效率极高, 但是添加删除效率较低.
  • ArrayLis t默认加载长度10 , 扩容是原来的1.5倍,非线程安全,效率极高.
  • 当第一次添加数据的时候,再创建数组,我们如果只是new了ArrayList()的对象时,是并不会初始化底层数组的是一个空数组{}.
添加到尾部
List list = new ArrayList(); //让我们先创建一个ArrayList
  • 添加元素到尾部
  • list.add(Object) 传入基本数据类型也会因为自动装箱变为对象包装类型从而继承Object
添加到指定位置
  • list.add(2, "d"); 第一个是插入的索引为int类型, 第二个为插入的内容为Object
根据内容删除
  • list.remove("a") 传入要删除的内容
  • 注意如果我们要根据内容删除,但是恰好该内容是整数数字, 那么我们不能直接传入,否则会把该内容当成下标进行删也就是下一个 需要把该值转换为对应的包装类
  • list.remove(Integer.valueOf(22))
  • 因为如果直接传入int会根据方法重载找到对应传入下标删除的方法因为下标删除的方法就是传入int
根据下标删除
  • list.remove(1) 传入要删除的索引下标
根据索引查询
  • list.get(1) 传入索引
根据索引修改
  • list.set(1, "e"); 第一个传入索引,第二个传入要修改内容
返回个数
  • list.size();
判断是否包含
  • list.contains("a");
判断是否为空 (个数是否为0)
  • list.isEmpty();
清空
  • list.clear();
获取对应元素的索引下标
  • list.indexOf("a"); 传入对应元素
遍历
  • 遍历可以选择正常的循环也可以选择增强for循环
// 使用正常循环获取size使用根据索引获取的get方法进行展示
for (int i = 0; i < list.size(); i++) {
		System.out.println(list.get(i));
}
// 直接使用增强for循环进行遍历 
for (Object object : list) {
	System.out.println(object);
}

LinkedList

  • LinkedList的底层是双向链表,随机删除效率极高, 但是查询和更改效率较低
  • 双向就表示互相可以找到, 可以向下找,也可以向上找
  • 链表中存储的都是节点对象 , 每一个双向链表中的节点都包含3个属性 : 保存的值 , 下一个节点的引用 , 上一个节点的引用
LinkedList list = new LinkedList(); // 我们先创建一个LinkedList

常用方法

  • 和ArrayList一样请看ArrayList

底层实现

Node
  • LinkedList中有一个名为Node的静态内部类用来创建节点. 其中包含三个成员变量, 一个是保存的值, 一个是下一个节点对象的地址, 一个是上一个节点对象的地址.

  • Node的构造方法会分别接受这三个值并放入成员之中

  • image-20240118204407750

    image-20240118205023784

LinkedList
  • LinkedList 里主要包含四个重要的成员变量.
    • 一个是size添加成员的个数.
    • 一个是 first 用来保存第一个节点的引用.
    • 一个是 last 用来保存最后一个节点的引用.
    • 还有一个modCount记录操作次数
添加方法
  • 添加方法就是创建了一个新的node节点并把向前变量指向原来最后的一个节点,把自己的向后变量变为null, 原来最后一个节点的向后指向变为自己.
  • image-20240118205347017
获取方法
  • 获取方法看似是根据下表进行寻找,但实际上是根据传入整数,进行循环找到对应的节点值返回

    img

  • 为了加快效率, 如果在前一半就从前往后寻找, 如果在后一半就从后往前寻找

删除方法
  • 删除方法和添加方法类似
a.prev.next = a.next;
a.next.prev = a.prev;
文章来源:https://blog.csdn.net/jiangshicsdn/article/details/135684225
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。