JAVA小知识20:万字详解List与ArrayList

news2024/11/29 22:44:14

一、集合简介

1.1、什么是集合?

可同时存储多个元素的数据结构就是集合。

1.2、为什么要有集合?

我们可以使用数组同时存储多个元素,但是数组有个弊端。数组创建之后长度就会固定,如需扩容则需要手动扩容,我们需要一个长度可变的新的容器(自动扩容)。

1.3、集合与数组的区别

数组可以存储基本数据类型,也可以存储引用数据类型。但是集合是不能直接存储基本数据类型的,需要把它转化为对应的包装类。

1.4、集合都有什么?

Java 集合框架可以分为两条大的支线:Collection接口与Map接口

  • Collection接口:
    • List接口:有序集合,允许重复元素。
      • ArrayList:基于动态数组实现,支持快速随机访问。
      • LinkedList:基于双向链表实现,适合频繁插入和删除操作。
  • Set接口:无序集合,不允许重复元素。
    • HashSet:基于哈希表实现,元素无序。
    • LinkedHashSet:继承自HashSet,维护插入顺序。
    • TreeSet:基于红黑树实现,元素有序。
  • Queue接口:用于处理先进先出(FIFO)的队列。
    • PriorityQueue:基于堆实现的优先级队列,元素按自然顺序或指定的Comparator排序。
  • Deque接口:双端队列,支持在两端插入和删除元素。
    • ArrayDeque:基于数组实现的双端队列。
    • LinkedList:也实现了Deque接口。
  • Map接口:
    • HashMap:基于哈希表实现,键值对无序。
    • LinkedHashMap:继承自HashMap,维护插入顺序。
    • TreeMap:基于红黑树实现,键值对有序。

我们引用一张图片就能很好地来解释上面的文字:
在这里插入图片描述
今天我们要研究的目标是List这条分支,也是我们开发中最常用的一种集合。

二、List

2.1、List简介

List接口是Java集合框架中的一部分,提供了一组有序的、可重复的元素集合。List接口继承自Collection接口,并在其基础上添加了允许精确控制元素插入位置的操作。

java.util.Collection 接口是 Java 集合框架的根接口之一,它定义了一组通用的方法,用于操作集合中的元素。Collection 接口是 Java 集合框架中所有集合类的共同父接口。

2.2、主要特点

  • 有序性:List接口保证元素的插入顺序,即元素的迭代顺序与插入顺序一致。
  • 可重复性:List接口允许存储重复的元素。
  • 索引访问:List接口提供了基于索引的位置访问元素的能力,类似于数组。

2.3、主要实现类

List接口有几个常用的实现类,每个类有其特定的特点和使用场景:

  • ArrayList:
    • 基于动态数组实现,支持快速随机访问。
    • 适合频繁读取元素的场景。
    • 插入和删除操作相对较慢,尤其是在列表中间插入或删除时。
  • LinkedList:
    • 基于双向链表实现,适合频繁插入和删除操作。
    • 读取速度较慢,因为需要从头遍历到指定位置。
    • 也实现了Deque接口,可以用作双端队列。

2.4、实现类对比

  • ArrayList:适用于随机访问频繁的场景,因为基于数组的实现提供了快速的索引访问。
  • LinkedList:适用于插入和删除操作频繁的场景,因为基于链表的实现提供了更高效的插入和删除操作。

2.5、为什么要用实现类?

在 Java 中,List 是一个接口(java.util.List),而不是一个具体的类。接口本身不能直接实例化为对象,因为它只是一组方法的声明,没有实际的方法实现。所以我们要想实现List,就要做一个向上造型,其中 ArrayList 是 List 接口的子类。将 ArrayList 类的对象赋值给 List 接口的引用,这是一种向上造型操作。这允许各位程序员使用 List 接口的方法来操作 ArrayList 对象,因为 ArrayList 实现了 List 接口,所以它是 List 接口的一个实例。

三、ArrayList

ArrayList 在数组的基础上实现了自动扩容,并且提供了比数组更丰富的预定义方法(各种增删改查),非常方便我们在开发中的使用。

3.1、创建ArrayList

先来看看List的源码:
在这里插入图片描述
我们可以看到List确确实实是继承了Collection,并且他也是一个接口,而且他还有个泛型(关于泛型的知识在java小知识19里面可以看看)。下面我们来看构造方法:
在这里插入图片描述
那我们如何初始化一个ArrayList集合呢?下面有两种方法,我们常用的为方法一。我们可以看到泛型(泛型只能是引用数据类型)里面规定了这个集合只能存储Integer包装类的数据。
在这里插入图片描述

3.2、ArrayList的成员方法

讲完了如何创建一个ArrayList我们来讲讲如何使用ArrayList

方法名描述
add()将元素插入到指定位置的 ArrayList
addAll()添加集合中的所有元素到 ArrayList
clear()删除 ArrayList 中的所有元素
clone()复制一份 ArrayList
contains()判断元素是否在 ArrayList
get()通过索引值获取 ArrayList 中的元素
indexOf()返回 ArrayList 中元素的索引值
removeAll()删除存在于指定集合中的 ArrayList 里的所有元素
remove()删除 ArrayList 里的单个元素
size()返回 ArrayList 里元素数量
isEmpty()判断 ArrayList 是否为空
subList()截取部分 ArrayList 的元素
set()替换 ArrayList 中指定索引的元素
sort()ArrayList 元素进行排序
toArray()ArrayList 转换为数组
toString()ArrayList 转换为字符串
ensureCapacity()设置指定容量大小的 ArrayList
lastIndexOf()返回指定元素在 ArrayList 中最后一次出现的位置
retainAll()保留 ArrayList 中在指定集合中也存在的那些元素
containsAll()查看 ArrayList 是否包含指定集合中的所有元素
trimToSize()ArrayList 中的容量调整为数组中的元素个数
removeRange()删除 ArrayList 中指定索引之间存在的元素
replaceAll()将给定的操作内容替换掉数组中每一个元素
removeIf()删除所有满足特定条件的 ArrayList 元素
forEach()遍历 ArrayList 中每一个元素并执行特定操作

3.3、ArrayList的特性

  1. 动态数组: ArrayList是基于动态数组实现的,它允许存储和操作一个可变数量的元素。数组的容量会自动增长或减少,以适应元素的添加和删除操作,因此无需手动管理数组的大小。
  2. 有序性: ArrayList 是有序集合,它以元素插入的顺序来维护元素的顺序。这意味着可以按照添加元素的顺序来访问和遍历元素。
  3. 允许重复元素: ArrayList 允许存储重复的元素,即同一个元素可以在列表中出现多次。
  4. 随机访问: 由于 ArrayList 基于数组实现,因此它支持随机访问。可以通过索引来直接访问列表中的元素。
  5. 线程不安全: ArrayList 不是线程安全的,这意味着在多线程环境下,如果多个线程同时访问和修改同一个 ArrayList 实例,可能会导致数据不一致或异常。如果需要在多线程环境中使用,可以考虑使用 Collections.synchronizedList() 方法来获得一个线程安全的 ArrayList。
  6. 性能: 由于 ArrayList 支持随机访问,因此对于需要频繁访问元素的场景非常高效。然而,在需要频繁插入或删除元素的情况下,性能可能较差,因为这涉及到数组元素的移动。
  7. 动态扩容: 当 ArrayList 内部数组的容量不足以容纳新元素时,它会自动扩展数组的大小,通常是当前容量的一半。这可以避免频繁的数组重新分配操作,提高了性能。

四、ArrayList成员方法详解

4.1、add():将元素插入到指定位置的 ArrayList 中。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add(1, "Banana"); // 在索引1处插入
System.out.println(list); // 输出: [Apple, Banana]

4.2、addAll():添加集合中的所有元素到 ArrayList 中。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
List<String> moreFruits = Arrays.asList("Banana", "Orange");
list.addAll(moreFruits);
System.out.println(list); // 输出: [Apple, Banana, Orange]

4.3、clear():删除 ArrayList 中的所有元素。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.clear();
System.out.println(list); // 输出: []

4.4、clone():复制一份 ArrayList。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
ArrayList<String> clonedList = (ArrayList<String>) list.clone();
System.out.println(clonedList); // 输出: [Apple]

4.5、contains():判断元素是否在 ArrayList 中。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
boolean hasApple = list.contains("Apple");
System.out.println(hasApple); // 输出: true

4.6、get():通过索引值获取 ArrayList 中的元素。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
String fruit = list.get(0);
System.out.println(fruit); // 输出: Apple

4.7、indexOf():返回 ArrayList 中元素的索引值。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
int index = list.indexOf("Banana");
System.out.println(index); // 输出: 1

4.3、removeAll():删除存在于指定集合中的 ArrayList 里的所有元素。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Orange");
List<String> toRemove = Arrays.asList("Banana", "Orange");
list.removeAll(toRemove);
System.out.println(list); // 输出: [Apple]

4.3、remove():删除 ArrayList 里的单个元素。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.remove("Apple");
System.out.println(list); // 输出: []

4.3、size():返回 ArrayList 里元素数量。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
int size = list.size();
System.out.println(size); // 输出: 1

4.3、isEmpty():判断 ArrayList 是否为空。

ArrayList<String> list = new ArrayList<>();
boolean empty = list.isEmpty();
System.out.println(empty); // 输出: true

4.3、subList():截取部分 ArrayList 的元素。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Orange");
List<String> subList = list.subList(1, 3);
System.out.println(subList); // 输出: [Banana, Orange]

4.3、set():替换 ArrayList 中指定索引的元素。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.set(0, "Banana");
System.out.println(list); // 输出: [Banana]

4.3、sort():对 ArrayList 元素进行排序。

ArrayList<String> list = new ArrayList<>();
list.add("Banana");
list.add("Apple");
list.sort(String::compareTo);
System.out.println(list); // 输出: [Apple, Banana]

4.3、toArray():将 ArrayList 转换为数组。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
Object[] array = list.toArray();
System.out.println(Arrays.toString(array)); // 输出: [Apple]

4.3、toString():将 ArrayList 转换为字符串。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
String str = list.toString();
System.out.println(str); // 输出: [Apple]

4.3、ensureCapacity():设置指定容量大小的 ArrayList。

ArrayList<String> list = new ArrayList<>();
list.ensureCapacity(100);
list.add("Apple");
System.out.println(list); // 输出: [Apple]

4.3、lastIndexOf():返回指定元素在 ArrayList 中最后一次出现的位置。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Apple");
int lastIndex = list.lastIndexOf("Apple");
System.out.println(lastIndex); // 输出: 2

4.3、retainAll():保留 ArrayList 中在指定集合中也存在的那些元素。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
List<String> toRetain = Arrays.asList("Apple");
list.retainAll(toRetain);
System.out.println(list); // 输出: [Apple]

4.3、containsAll():查看 ArrayList 是否包含指定集合中的所有元素。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
List<String> toCheck = Arrays.asList("Apple", "Banana");
boolean containsAll = list.containsAll(toCheck);
System.out.println(containsAll); // 输出: true

4.3、trimToSize():将 ArrayList 中的容量调整为数组中的元素个数。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.trimToSize();
System.out.println(list); // 输出: [Apple]

4.3、removeRange():删除 ArrayList 中指定索引之间存在的元素。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Orange");
list.subList(1, 2).clear(); // 删除索引1到2之间的元素
System.out.println(list); // 输出: [Apple, Orange]

4.3、replaceAll():将给定的操作内容替换掉数组中每一个元素。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.replaceAll(fruit -> fruit.toUpperCase());
System.out.println(list); // 输出: [APPLE, BANANA]

4.3、removeIf():删除所有满足特定条件的 ArrayList 元素。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.removeIf(fruit -> fruit.startsWith("A"));
System.out.println(list); // 输出: [Banana]

4.3、forEach():遍历 ArrayList 中每一个元素并执行特定操作。

ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.forEach(fruit -> System.out.println(fruit));

五、ArrayList的扩容机制

结合源码我们来讲一下ArrayList的扩容机制

第一步:创建ArrayList对象

首先我们来看一下创建一个ArrayList对象的时候都发生了什么

public static void main(String[] args) {
    List<String> list = new ArrayList<>();
}

ArrayList在底层有一个数组,他的名字叫做elementData,他还有一个成员变量size记录元素的个数。
在这里插入图片描述

如果利用空参的构造方法或者参数为0的情况下,在底层他会默认创建一个长度为0的数组
在这里插入图片描述
在这里插入图片描述
也就是说我们创建一个空参ArrayList对象时候,他的数组长度为0

第二步、添加元素

我们来看看当向ArrayList集合中添加第一个元素时候发生了什么。

当第一次添加元素时,ArrayList 会检查是否需要扩容。在 add 方法中,会调用ensureCapacityInternal 方法来确保容量足够:
在这里插入图片描述

然后我们来看那可能这个ensureCapacityInternal(size + 1); 方法是怎么来保证容量是足够的。

当我们刚刚创建这个ArrayList的时候,他的size值为0,而+1之后参数就为1。
此时,就变成了ensureCapacityInternal(1)
ensureCapacityInternal()方法会调用 ensureExplicitCapacity 来判断是否需要扩容:
在这里插入图片描述

此时又来了一个方法,我们先看看这个calculateCapacity(elementData, minCapacity)都干了什么?

两个参数,一个是底层数组,一个是刚刚传过来的size+1,底层数组在初始化的时候赋值的就是空数组DEFAULTCAPACITY_EMPTY_ELEMENTDATA,所以满足if条件在这里插入图片描述
而这个DEFAULT_CAPACITY这个常量在源码中的默认值就是10。minCapacity的值为1。所以会返回10

说完了calculateCapacity(elementData, minCapacity)我们接着来看最外层的ensureExplicitCapacity()都干了什么?

在这里插入图片描述

第三步、扩展数组

重点来了!!!可以看到初始数组长度为0,进入到了grow()函数,这个函数就是扩容函数,我们来详细的分析看看。

先上完整代码:
在这里插入图片描述

1、变量初始化

// overflow-conscious code
int oldCapacity = elementData.length;

elementData.length 表示当前 ArrayList 内部数组的长度,即当前容量。
oldCapacity 就是当前数组的长度,即当前 ArrayList的容量。
2、计算新容量

int newCapacity = oldCapacity + (oldCapacity >> 1);

oldCapacity >> 1 是对 oldCapacity 进行右移一位的操作,相当于 oldCapacity / 2。这一步是为了将当前容量增加 50%
newCapacity 就是计算出来的新容量,通常是当前容量的1.5倍。
3、调整新容量

if (newCapacity - minCapacity < 0)
   newCapacity = minCapacity;

这里判断如果 newCapacity(计算后的新容量) 小于 minCapacity(参数),则将newCapacity设置为 minCapacity。这是为了确保扩容后的容量至少能够满足 minCapacity,即确保能够容纳至少 minCapacity 个元素。
4、最大容量限制

if (newCapacity - MAX_ARRAY_SIZE > 0)
   newCapacity = hugeCapacity(minCapacity);

MAX_ARRAY_SIZE 是 ArrayList 内部定义的一个常量,表示数组的最大容量。如果 newCapacity 超过了 MAX_ARRAY_SIZE,则调用hugeCapacity方法进行处理,通常是返回一个较大的合理容量。
5、扩容操作

// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);

·Arrays.copyOf ·方法用于将 ·elementData· 数组扩展到 ·newCapacity ·的大小,并复制原数组的内容到新数组中。这一步实现了真正的扩容操作

关于这个copyof可以看一下我的java小知识18有讲过,这里也直接贴出截图:
在这里插入图片描述

六、关于ArrayList的一些问答

6.1 ArrayList的扩容机制

上面五讲过了

6.2 ArrayList频繁扩容导致性能下降问题

问题:
假设现在需要添加10w条数据,可能时间上很快,不到1s就能添加完,但是这其中ArrayList就会扩容n次,并且重复拷贝n次,这样的操作非常的占用我们的内存开销。
答案:
可以使用有参构造来创建ArrayList,然后添加元素。看下列示例,同样添加10w条数据。

public static void main(String[] args) {
    long t1 = System.currentTimeMillis();
    List<String> list = new ArrayList<>();
    for(int i=0; i<100000; i++) {
        list.add(i+"a");
    }
    long t2 = System.currentTimeMillis();
    System.out.println("方法一运行:"+(t2 - t1)+"毫秒");
    long t3 = System.currentTimeMillis();
    List<String> list2 = new ArrayList<>(100000);
    for(int i=0; i<100000; i++) {
        list2.add(i+"a");
    }
    long t4 = System.currentTimeMillis();
    System.out.println("方法二运行:"+(t4 - t3)+"毫秒");
}

在这里插入图片描述

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

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

相关文章

MEGALODON:突破传统,实现高效无限上下文长度的大规模语言模型预训练和推理

在人工智能领域&#xff0c;尤其是在自然语言处理&#xff08;NLP&#xff09;中&#xff0c;大模型&#xff08;LLMs&#xff09;的预训练和推理效率一直是研究的热点。最近&#xff0c;一项突破性的研究提出了一种新型神经网络架构——MEGALODON&#xff0c;旨在解决传统Tran…

2024年武汉市中级、高级职称水测考试开卷方法分享

2024年武汉市&#xff08;除开东湖高新区外&#xff09;职称首次组织全员水测&#xff0c;先考水测后报名&#xff0c;水测报名在5月16号截止。 武汉市水测组织形式&#xff1a; 武汉市2024年专业技术职务水平能力测试分为笔试和面试&#xff0c;面试答辩有关事项另行通知&…

全息图分类及相位型全息图制作方法

全息图是一种光学器件&#xff0c;全息图分为振幅型和相位型全息图&#xff0c;振幅型全息图记录光的振幅信息即强度信息&#xff0c;相位型全息图记录光的相位信息&#xff0c;利用相位信息可以恢复光的波前形状&#xff0c;从而记录物体形状&#xff0c;这里主要介绍相位全息…

C# Winform 用户控件,扩展控件,自定义控件综合实例

Control类是Windows窗体控件的基类&#xff0c;它提供了在 Windows 窗体应用程序中进行可视显示所需的基础结构&#xff0c;可以通过继承来扩展熟悉的用户控件和现有控件的功能。本列介绍三种不同自定义控件以及怎么创建他们。 自定义控件分类 用户控件&#xff1a;基本控件的…

django学习入门系列之第二点《浏览器能识别的标签1》

文章目录 文件的编码(head)网站表头信息(head)标题&#xff08;body&#xff09;div和span往期回顾 文件的编码(head) <!--浏览器会以"UTF-8"这种编码来读取文件--> <meta charset"UTF-8">网站表头信息(head) <title>Title</title&…

React Native将 ipad 端软件设置为横屏显示后关闭 Modal 弹窗报错

问题&#xff1a; 将 ipad 端软件设置为横屏显示后&#xff0c;关闭 Modal 弹窗报错。 Modal was presented with 0x2 orientations mask but the application only supports 0x18.Add more interface orientations to your apps Info.plist to fix this.NOTE: This will cras…

移动端超超超详细知识点总结(Part3)

flex布局体验 1. 传统布局与flex布局 传统布局&#xff1a; 兼容性好布局繁琐局限性&#xff0c;不能再移动端很好的布局flex 弹性布局&#xff1a; 操作方便&#xff0c;布局极为简单&#xff0c;移动端应用很广泛PC 端浏览器支持情况较差IE 11或更低版本&#xff0c;不支持…

代码随想录算法训练营第39天(py)| 动态规划 | 62.不同路径、 63. 不同路径 II

62.不同路径 力扣链接 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路…

ShardingSphere-proxy添加自定义分片规则(踩坑日记)

文章目录 一、新建spring boot项目二、编写代码(1) 新建一个类(2) doSharding方法详解(3) 实际例子 三、增加spi文件&#xff08;很关键&#xff09;四、打包五、把生成的文件放到ext-lib中六、yaml配置&#xff08;怎么用&#xff09;七、测试 版本环境 mysql 5.7.40 sharding…

使用 Python 进行测试(1)测试基础

原文 总结 我们将从unittest开始&#xff0c;尽管它并不那么好用&#xff0c;但它是Python标准库中的测试工具。 使用unittest编写测试看起来像这样&#xff1a; import unittest# 需要测试的代码 def add(a, b):return a b# The tests class TestAddFunction(unittest.Test…

MySQL之优化服务器设置(三)

优化服务器设置 InnoDB表空间 InnoDB把数据保存在表空间内&#xff0c;本质上是一个由一个或多个磁盘文件组成的虚拟文件系统。InnoDB用表空间实现很多功能&#xff0c;并不只是存储表和索引。它还保存了回滚日志(旧版本行)、插入缓冲(Insert Buffer)、双写缓冲(Doublewrite …

大模型企业落地:制造业可以选择的应用场景

前言 在当今制造业快速发展的背景下&#xff0c;设备稳定运行对于企业的发展至关重要。然而&#xff0c;传统的设备维修模式已无法满足现代企业的需求。为此&#xff0c;引入智能化、数字化的设备维修解决方案成为必然趋势。本文将探讨如何利用大模型技术&#xff0c;构建企业…

《2023-2024中国数据资产发展研究报告》

中国电子信息产业发展研究院发布《2023-2024中国数据资产发展研究报告》&#xff08;下称《报告》&#xff09;&#xff0c;紧跟国家战略部署&#xff0c;调研国内数据资产发展现状&#xff0c;掌握数据价值实现路径&#xff0c;助力释放数字经济新动能。 《报告》从数据资产相…

北京活动会议通常会邀约哪些媒体参会报道?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 北京作为我国的首都和文化中心&#xff0c;各类活动会议资源丰富&#xff0c;吸引了众多媒体的关注。以下是一些通常会被邀约参会报道的重要媒体类型&#xff1a; 国家级新闻机构&#x…

探索AI的魔力:这5款AI应用让你全面感受人工智能的魅力

“ AI 的出现就像燃气机和蒸汽机一样&#xff0c;极大地提高了生产力。” 01、—chatGPT ChatGPT 是由 OpenAI 公司开发的一种大型语言模型。 OpenAI 公司成立于 2015年&#xff0c;早期马斯克是该公司的创始人之一。 自 2018 年推出 GTP-1 以来&#xff0c;OpenAI 已经推出…

关于Linux ping 不通外网

网关为第三段为137那么子网ip第三段必须为137且IPaddr必须为137 将主机虚拟适配器连接到此网络必须勾上&#xff0c;不然vmnet适配器在windows将找不到 ping www.baidu.com不行的话试着勾上桥接模式应该是不行在勾上取消勾上桥接模式最后勾上nat模式

C语言小例程20/100

题目&#xff1a;一个数如果恰好等于它的因子之和&#xff0c;这个数就称为"完数"。例如61&#xff0b;2&#xff0b;3.编程找出1000以内的所有完数。 #include<stdio.h> #define N 1000 int main() {int i,j,k,n,sum;int a[256];for(i2;i<N;i){suma[0]1;k…

Transformer系列:图文详解Decoder解码器原理

从本节开始本系列将对Transformer的Decoder解码器进行深入分析。 内容摘要 Encoder-Decoder框架简介shifted right移位训练解码器的并行训练和串行预测解码器自注意力层和掩码解码器交互注意力层和掩码解码器输出和损失函数 Encoder-Decoder框架简介 在原论文中Transformer用…

视频转换器在线哪个好?让视频播放不受格式限制

在日常的视频观看中&#xff0c;我们可能会遇到视频格式与设备不兼容的问题&#xff0c;导致无法顺畅播放。这就像是缺少了播放的钥匙&#xff0c;让人无法享受视频内容。 面对视频格式不兼容的挑战&#xff0c;选择合适的转换工具至关重要。但不用担心&#xff0c;本文将分享…

框架学习之spring学习笔记(一)

一、框架前言 1-什么是spring框架&#xff0c;有哪些主要模块&#xff1f; Spring 框架是一个专门针对于 Java 应用程序开发&#xff0c;并提供了综合、广泛的基础性支持的轻量级框架。Spring框架使用目的是为了提高开发人员的开发效率以及系统的可维护性。 Spring 是以IoC和A…