集合-CollectionListSet

Collection体系的特点、使用场景总结

如果希望元素可以重复,又有索引,索引查询要快?

  • 用ArrayList集合, 基于数组的。(用的最多)

如果希望元素可以重复,又有索引,增删首尾操作快?

  • 用LinkedList集合, 基于链表的。

如果希望增删改查都快,但是元素不重复、无序、无索引。

  • 用HashSet集合,于哈希表的。

如果希望增删改查都快,但是元素不重复、有序、无索引。

  • 用LinkedHashSet集合, 于哈希表和双链表。

如果要对对象进行排序。

  • 用TreeSet集合, 基于红黑树。后续也可以用List集合实现排序。

数组的特点

  • 数组定义完成并启动后,类型确定、长度固定。

  • 不适合元素的个数和类型不确定的业务场景,更不适合做需要增删数据操作。

  • 数组的功能也比较的单一,处理数据的能力并不是很强大。

集合的特点

  • 集合的大小不固定,启动后可以动态变化,类型也可以选择不固定。集合更像气球。
  • 集合非常适合元素个数不能确定,且需要做元素的增删操作的场景。
  • 同时,集合提供的种类特别的丰富,功能也是非常强大的,开发中集合用的更多。

1、数组和集合的元素存储的个数问题。

  • 数组定义后类型确定,长度固定
  • 集合类型可以不固定,大小是可变的。

2、数组和集合存储元素的类型问题。

  • 数组可以存储基本类型和引用类型的数据。
  • 集合只能存储引用数据类型的数据。

3、数组和集合适合的场景

  • 数组适合做数据个数和类型确定的场景。
  • 集合适合做数据个数不确定,且要做增删元素的场景,集合种类更多,功能更强大。

集合

集合的体系特点

  • Collection代表单列集合,每个元素(数据)只包含一个值。
  • Map代表双列集合,每个元素包含两个值(键值对)。
  • 集合中存储的是元素的什么信息?
    • 集合中存储的是元素对象的地址。

集合体系结构

image-20240413141849783

Collection集合体系

image-20240413125332420

Collection集合的特点

  • List系列集合:有序、可重复 有索引
    • ArrayList、LinekdList: 有序、可重复 有索引
  • Set系列集合:无序、不重复 无索引
    • HashSet: 无序、不重复、无索引
    • LinkedHashSet: 有序、不重复、无索引
    • TreeSet:按照大小默认升序排序、不重复、无索引。

Collection的常用方法

1、集合的代表是?

  • Collection接口。

2、Collection集合分了哪2大常用的集合体系?

  • List系列集合:添加的元素是有序、可重复、有索引。
  • Set系列集合:添加的元素是无序、不重复、无索引。

3、如何约定集合存储数据的类型,需要注意什么?

  • 集合支持泛型。
  • 集合和泛型不支持基本类型,只支持引用数据类型。

为啥要先学Collection的常用方法?

Collection是单列集合的祖宗,它规定的方法(功能)是全部单列集合都会继承的。

Collection的常见方法如下:

方法名说明
public boolean add(E e)把给定的对象添加到当前集合中
public void clear()清空集合中所有的元素
public boolean remove(E e)把给定的对象在当前集合中删除
public boolean contains(Object obj)判断当前集合中是否包含给定的对象
public boolean isEmpty()判断当前集合是否为空
public int size()返回集合中元素的个数。
public Object[] toArray()把集合中的元素,存储到数组中

Collection的遍历方式

迭代器

迭代器是用来遍历集合的专用方式(数组没有迭代器),在Java中迭代器的代表是Iterator。

Collection集合获取迭代器的方法

方法名称说明
Iterator iterator()返回集合中的迭代器对象,该迭代器对象默认指向当前集合的第一个元素

Iterator迭代器中的常用方法

方法名称说明
boolean hasNext()询问当前位置是否有元素存在,存在返回true,不存在返回false
E next()获取当前位置的元素, 并同时将迭代器对象指向下一个元素处。
Iterator<String> it = lists.iterator();
while(it.hasNext()){
    String ele = it.next();
    System.out.println(ele);
}

1、迭代器的默认位置在哪里。
Iterator<E> iterator():得到迭代器对象,默认指向当前集合的索引0
2、迭代器如果取元素越界会出现什么问题。
会出现NoSuchElementException异常。
image-20230508115342189
增强for循环

1、增强for可以遍历哪些容器?

  • 既可以遍历集合也可以遍历数组。

2、增强for的关键是记住它的遍历格式

for(元素数据类型 变量名 : 数组或者Collection集合) { //在此处使用变量即可,该变量就是元素 }
    
Collection<String> c = new ArrayList<>();  ...
for(String s : c) {
    System.out.println(s);
}
增强for可以用来遍历集合或者数组。
增强for遍历集合,本质就是迭代器遍历集合的简化写法。
Lambda表达式遍历集合

Lambda表达式,提供了一种更简单、更直接的方式来遍历集合。

需要使用Collection的如下方法来完成

方法名称说明
default void forEach(Consumer<? super T> action)结合lambda遍历集合
Collection<String> lists = new ArrayList<>(); ...
lists.forEach(new Consumer<String>() {
    @Override
    public void accept(String s) {
        System.out.println(s);
    }
});
转为
lists.forEach(s -> {
    System.out.println(s);
});
//  lists.forEach(s -> System.out.println(s));

集合存储对象的原理
image-20240413152713436

集合的并发修改异常问题

问题引出

  • 使用迭代器遍历集合时,又同时在删除集合中的数据,程序就会出现并发修改异常的错误。
  • 由于增强for循环遍历集合就是迭代器遍历集合的简化写法,因此,使用增强for循环遍历集合,又在同时删除集合中的数据时,程序也会出现并发修改异常的错误

怎么保证遍历集合同时删除数据时不出bug?

  • 使用迭代器遍历集合:但用迭代器自己的删除方法删除数据即可。
  • 使用增强for循环遍历集合:无法解决这个问题
  • 使用普通for循环遍历集合:可以倒着遍历并删除;或者从前往后遍历,但删除元素后做i --操作。

List集合

有序,可重复,有索引。

List特有方法

collection集合体系

image-20230508122146507

List集合特有方法

  • List集合因为支持索引,所以多了很多索引操作的独特api,其他Collection的功能List也都继承了。
方法名称说明
void add(int index,E element)在此集合中的指定位置插入指定的元素
E remove(int index)删除指定索引处的元素,返回被删除的元素
E set(int index,E element)修改指定索引处的元素,返回被修改的元素
E get(int index)返回指定索引处的元素

List集合的遍历方式有几种?

  • 迭代器
  • 增强for循环
  • Lambda表达式
  • for循环(因为List集合存在索引)

ArrayList集合的底层原理

  • ArrayList底层是基于数组实现的
    • 查询速度快(注意: 是根据索引查询数据快): 查询数据通过地址值和索引定位,查询任意数据耗时相同。
    • 删除效率低:可能需要把后面很多的数据进行前移。
    • 添加效率极低:可能需要把后面很多的数据后移,再添加元素;或者也可能需要进行数组的扩容。
  1. 利用无参构造器创建的集合,会在底层创建一个默认长度为0的数组

  2. 添加第一个元素时,底层会创建一个新的长度为10的数组

    List<String> list1 = new ArrayList<>();list1.add("a");

  3. 存满时,会扩容1.5倍

  4. 如果一次添加多个元素,1.5倍还放不下,则新创建数组的长度以实际为准

应用场景
  • ArrayList适合:
  • 根据索引查询数据, 比如根据随机索引取数据(高效)! 或者数据量不是很大时
  • ArrayList不适合:
    • 数据量大的同时, 又要频繁进行增删操作

List集合的遍历方式有几种?

  • 迭代器
  • 增强for循环
  • Lambda表达式
  • for循环(因为List集合存在索引)

LinkedList集合底层原理

基于双链表实现的

查询慢,增删相对较快,但对首尾元素进行增删改查的速度是极快的。

什么是链表? 有啥特点?

  • 链表中的结点是独立的对象,在内存中是不连续的,每个结点包含数据值和下一个结点的地址。

特点:

  • 链表的特点1:查询慢,无论查询哪个数据都要从头开始找。
  • 链表的特点2:增删首尾元素是非常快的
image-20240413161305139

image-20240413161504349

image-20240413161639992

LinkedList集合的特有功能

方法名称说明
public void addFirst(E e)在该列表开头插入指定的元素
public void addLast(E e)将指定的元素追加到此列表的末尾
public E getFirst()返回此列表中的第一个元素
public E getLast()返回此列表中的最后一个元素
public E removeFirst()从此列表中删除并返回第一个元素
public E removeLast()从此列表中删除并返回最后一个元素
应用场景
  • 可以用来设计队列

    • 先进先出, 后进后出
  • 可以用来设计栈

    • 后进先出,先进后出

Set集合

介绍

Collection集合体系

image-20240413163552073

Set系列集合特点: 无序; 不可重复

  • 无序:存取顺序不一致
  • 不重复:可以去除重复
  • 无索引: 没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索弓l来获取元素。
  • HashSet:无序、 不重复、无索引.

  • LinkedHashSet: 有序、不重复、无索引。

  • TreeSet: 排序、不重复、无索引。

  • 注意:

    • Set要用到的常用方法,基本上就是Collection提供的!!
    • 自己几乎没有额外新增一些常用功能!

HashSet

Hash值

注意:在正式了解HashSet集合的底层原理前,我们需要先搞清楚一个前置知识:哈希值!

  • 就是一个int类型的数值,Java中每个对象都有一个哈希值。
  • Java中的所有对象,都可以调用Obejct类提供的hashCode方法,返回该对象自己的哈希值。

public int hashCode():返回对象的哈希码值。

对象哈希值的特点

  • 同一个对象多次调用hashCode()方法返回的哈希值是相同的。
  • 不同的对象,它们的哈希值一般不相同,但也有可能会相同(哈希碰撞)。
  • Object的hashCode方法根据"对象地址值"计算哈希值子类重写后的hashCode方法可以根据"对象属性值"计算哈希值

HashSet集合判定两个对象的标准就是两个对象的hash值是否一致, 因此我们经常重写hashcode实现集合中对象去重

  • 如果希望Set集合认为2个内容相同的对象是重复的应该怎么办?
  • 重写对象的hashCode和equals方法。
底层原理
  • HashSet集合底层采取哈希表存储的数据。
  • 哈希表是一种对于增删改查数据性能都较好的结构。

哈希表的组成

  • JDK8之前的, 底层使用数组+链表组成
  • JDK8开始后,底层采用数组+链表+红黑树组成。

在了解哈希表之前需要先理解哈希值的概念

哈希值

  • 是JDK根据对象的地址, 按照某种规则算出来的int类型的数值。

Object类的API

  • public int hashCode0:返回对象的哈希值

对象的哈希值特点

  • 同一个对象多次调用hashCode0方法返回的哈希值是相同的
  • 默认情况下,不同对象的哈希值是不同的。
image-20230508124709994

哈希表的详细流程

  • 创建一个默认长度16,默认加载因为0.75的数组,数组名table
  • 根据元素的哈希值跟数组的长度计算出应存入的位置
  • 判断当前位置是否为null,如果是null直接存入,如果位置不为null,表示有元素, 则调用equals方法比较属性值,如果一样,则不存,如果不一样,则存入数组。
  • 当数组存满到16*0.75=12时,就自动扩容,每次扩容原先的两倍

JDK8开始,当链表长度超过8,且数组长度>=64时,自动将链表转成红黑树

image-20230508124924102

树结构(了解)
image-20240413170017082

了解数据结构

image-20240413170105743

(树)

image-20240413170244912
  • 二叉树存在的问题:

    • 当数据已经是排好序的,导致查询的性能与单链表一样,查询速度变慢!
  • 平衡二叉树

    • 在满足查找二叉树的大小规则下,让树尽可能矮小,以此提高查数据的性能。

红黑树,就是可以自平衡的二叉树

  • 红黑树是一种增删改查数据性能相对都较好的结构。
  • 左右子树高度差大于 1 便会调整
image-20240413170612905
/*
HashSet集合的底层原理
    JDK8之前: 数组+链表
    JDK8开始: 数组+链表+红黑树

树结构
    二叉树: 基本模型
        每一个根节点最多只能有两个子节点,子节点数量称为度,树的总层数为树高
        左子节点
        右子节点
        左子树
        右子树

    二叉查找/二又搜索树: BST (Binary Search  Tree)
        小的存左边,大的存右边,相同则不存
        如果数据已经排好序,那么存入二又树查找树,会形成类似链表结构,查询效率还是低
        如果左、右子树的树高差比较大,那么导致左右子树不平衡,影响查询效率

    平衡二叉树: AVL (Balanced  Binary Tree)
        有规律且相对平衡的二叉树
        当插入一个元素,导致左右子树的树高差大于1。那么就会触发旋转
        旋转分为左旋和右旋,用来保证左右子树的相对平衡

    红黑: RBT (Red-Black  Tree)
        特殊的/自平衡的二又查找树,是计算机科学中用到的一种数据结构
        1972年出现时被称为平衡二叉树,后来1978年被修改为如今的红黑树
        红黑树不是高度平衡的,有自己保证平衡的规则(红黑规则),性能较好,红黑规则如下:
            每一个节点都是红色或者黑色的
            根节点必须是黑色的
            两个红色节点不能相连
            如果一个节点没有子节点,则该节点相应的指针属性为Nil (称为叶子结点),叶子结点是黑色的
            对于每一个节点,到其所有后代叶节点的简单路径上,包含的黑色 节点数量相同
*/

手撕平衡二叉树

手撕红黑树

总结

JDK8开始,当链表长度超过8,且数组长度>=64时,自动将链表转成红黑树

HashSet集合的底层原理是什么样的?

  • 结构: 数组 + 链表 8-
    数组 + 链表 + 红黑树 8+

  • 数组初始16,加载因子0.75, 新数组是原来老数组的2倍

  • 对元素进行HashCode % 16[0~15]

  • 如果索引对应的值是null, 先equal比较, 如果一样不存储,
    如果不一样, 8- 存储新的, 老的挂载新的下面 8+ 新的挂载到老的下面

  • 扩容: 加载因子计算什么时候开始扩容 16 * 0.75= 12
    创建新的数组, 长度是原来的两倍, 重新计算索引放入新的数组中

  • 基于哈希表实现的。

  • JDK8之前的,哈希表:底层使用数组+链表组成

  • JDK8开始后,哈希表:底层采用数组+链表+红黑树组成。

HashSet集合利用哈希表操作数据的详细流程是咋回事?

  • 创建一个默认长度16,默认加载因为0.75的数组,数组名table
  • 根据元素的哈希值跟数组的长度计算出应存入的位置
  • 判断当前位置是否为null,如果是null直接存入,如果位置不为null,表示有元素,
  • 则调用equals方法比较属性值,如果一样,则不存,如果不一样,则存入数组.
  • 当数组存满到16*0.75=12时,就自动扩容,每次扩容原先的两倍

LinkedHashSet

底层原理
  • LinkedHashSet是不可重复的,存取有序的,底层是基于哈希表**(数组、链表、红黑树)**实现的。
  • 但是,它的每个元素都额外的多了一个双链表的机制记录它前后元素的位置。
image-20240413170955068

TreeSet

  • 特点:不重复、无索引、可排序(默认升序排序 ,按照元素的大小,由小到大排序)
  • 底层是基于红黑树实现的排序。

注意:

  • 对于数值类型:Integer , Double,默认按照数值本身的大小进行升序排序。
  • 对于字符串类型:默认按照首字符的编号升序排序。
  • 对于自定义类型如Teacher对象,TreeSet默认是无法直接排序的。
自定义排序规则
  • TreeSet集合存储自定义类型的对象时,必须指定排序规则,支持如下两种方式来指定比较规则。

方式一:自然排序

  • 让自定义的类(如教师类)实现Comparable接口,重写里面的compareTo方法来指定比较规则。

方式二:比较器排序

  • 通过调用TreeSet集合有参数构造器,可以设置Comparator对象(比较器对象,用于指定比较规则)。
public TreeSet(Comparator<? super E> comparator)

总结
  • TreeSet集合的特点是怎么样的?

    • 可排序、不重复
    • 底层基于红黑树实现排序,增删改查性能较好
  • TreeSet集合对自定义类型的对象排序,有几种方式指定比较规则?

    • 2种
    • 类实现Comparable接口,重写比较规则。
    • 集合自定义Comparator比较器对象,重写比较规则。

Collection集合特点

  • List系列集合:有序,可重复
  • ArrayList、LinekdList
  • Set系列集合:无序,不可重复
  • HashSet:
  • LinkedHashSet: 有序、不重复、无索引(底层基于哈希表,使用双链表记录添加顺序。)
  • TreeSet:可排序、不重复、无索引(底层基于红黑树实现排序,增删改查性能较好)

1、如果希望记住元素的添加顺序,需要存储重复的元素,又要频繁的根据索引查询数据?

  • 用ArrayList集合(有序、可重复、有索引),底层基于数组的。(常用)

2、如果希望记住元素的添加顺序,且增删首尾数据的情况较多?

  • 用LinkedList集合(有序、可重复、有索引),底层基于双链表实现的。

3、如果不在意元素顺序,也没有重复元素需要存储,只希望增删改查都快?

  • 用HashSet集合(无序,不重复,无索引),底层基于哈希表实现的。 (常用)

4、如果希望记住元素的添加顺序,也没有重复元素需要存储,且希望增删改查都快?

  • 用LinkedHashSet集合(有序,不重复,无索引), 底层基于哈希表和双链表。

5、如果要对元素进行排序,也没有重复元素需要存储?且希望增删改查都快?

  • 用TreeSet集合,基于红黑树实现。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大屏-flex布局

<div class"container"><div class"title">标题</div><div class"content"><div class"item"></div><div class"item" style"width: calc((100% - 30) / 3 * 2)"><…

【Mybatis】一级缓存与二级缓存源码分析与自定义二级缓存

1.前言 缓存的本质就是内存,缓存在我们现在应用的价值是程序与数据库之间搭建的一个桥梁,提高用户的查询效率,尽量避免数据库的硬盘查询。 2.换出算法 LRU: 最不常用的对象会被换出到硬盘中(或者说最少使用的对象),通过给每个对象记录使用次数可以实现。 FIFO:先入先出,第一…

4.17作业

#include "double_link_list.h" node_p create_double_link_list() //创建双向链表 {node_p H(node_p)malloc(sizeof(node));if(HNULL){printf("空间申请失败\n");return NULL;}H->data0;H->priNULL;H->nextNULL;return H; } node_p create_node…

照片jpg格式小于50kb怎么弄?jpg压缩到指定大小

我们经常需要处理大量的图片&#xff0c;特别是在分享到社交媒体时&#xff0c;然而&#xff0c;图片文件的大小常常成为困扰我们的问题&#xff0c;尤其是当我们的设备存储空间有限时。有些平台甚至会需要将图片压缩到50kb大小&#xff0c;那么&#xff0c;如何有效地压缩图片…

学习Rust的第4天:常见编程概念

基于Steve Klabnik的《The Rust Programming Language》一书。昨天我们做了一个猜谜游戏 &#xff0c;今天我们将探讨常见的编程概念&#xff0c;例如&#xff1a; Variables 变量Constants 常数Shadowing 阴影Data Types 数据类型Functions 功能 Variables 变量 In layman ter…

HackMyVM-suidy

目录 信息收集 arp nmap WEB web信息收集 gobuster 目录批量查看 hydra ssh连接 提权 系统信息收集 提权 信息收集 arp ┌─[rootparrot]─[~/HackMyVM] └──╼ #arp-scan -l Interface: enp0s3, type: EN10MB, MAC: 08:00:27:16:3d:f8, IPv4: 192.168.9.115 St…

【网络通信基础】网络中的常见基本概念

目录 一、IP地址 二、端口号 三、协议 四、五元组 五、协议分层 1. OSI 模型 2. TCP/CP五层&#xff08;或四层&#xff09;模型 3. 网络设备所在分层 六、封装和分用 封装&#xff08;Encapsulation&#xff09; 分用&#xff08;Multiplexing&#xff09; 一、IP…

多目标环形粒子群算法和多目标遗传算法跑MOCEC2020(24个多目标测试函数,matlab代码,多个评价指标)

本号从现在起可以定制使用评估次数改进单目标群体算法&#xff0c;需要的私&#xff0c;价格贵&#xff0c;质量高。 目录&#xff1a; 一、多目标环形粒子群算法MO_Ring_PSO_SCD 二、多目标遗传算法NSGAII 三、MOCEC2020的24个多目标测试函数 四、实验结果 五、代码获取…

C语言进阶课程学习记录-函数指针的阅读

C语言进阶课程学习记录-函数指针的阅读 5个标识符含义解析技巧 本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程&#xff0c;图片全部来源于课程PPT&#xff0c;仅用于个人学习记录 5个标识符含义解析 int (*p1) (int* , int (*f) ( int* ) );定义了指针p1,指向函数&#…

javaWeb智能医疗管理系统

简介 在当今快节奏的生活中&#xff0c;智能医疗系统的崛起为医疗行业带来了一场革命性的变革。基于JavaWeb技术开发的智能医疗管理系统&#xff0c;不仅为医疗机构提供了高效、精准的管理工具&#xff0c;也为患者提供了更便捷、更个性化的医疗服务。本文将介绍一个基于SSM&a…

树莓集团产业生态建设之特色产业服务:人才项目转化中心

树莓集团在产业生态建设中&#xff0c;积极输出特色产业服务——人才项目转化中心。该中心依托数字产业园致力于推动创新创业工作&#xff0c;通过链接产业人才聚集地与树莓认证的导师库体系&#xff0c;为人才及相关课题项目提供全方位的服务。 树莓集团人才项目转化中心以人…

Python学习(四)文件操作

文件操作 想想我们平常对文件的基本操作&#xff0c;大概可以分为三个步骤(简称文件操作三步走): ① 打开文件 ② 读写文件 ③ 关闭文件 注意:可以只打开和关闭文件&#xff0c;不进行任何读写 在Python&#xff0c;使用open函数&#xff0c;可以打开一个已经存在的文件&…

IP爬虫代理服务器是什么以及为什么使用爬虫代理?

在网络抓取领域&#xff0c;爬虫代理发挥着关键作用。 但它们到底是什么&#xff1f; 从本质上讲&#xff0c;爬虫代理是位于网络抓取工具和目标网站之间的中间服务器。 该中间服务器充当盾牌&#xff0c;提供匿名性&#xff0c;并允许您访问网站并提取数据&#xff0c;而无需透…

IDEA配置Maven环境

黑马程序员JavaWeb开发教程 文章目录 如果当前有已经打开项目的话&#xff0c;File -> Close Project 到以下页面之后选择 Customize -> All settings… 配置maven的安装目录&#xff0c;maven的配置文件&#xff0c;maven的本地仓库&#xff08;修改完成之后一定要先…

mybatis进阶篇-执行CRUD操作-typeAliases别名-接口绑定

目录结构 所需jar包 https://download.csdn.net/download/weixin_44201223/89160447?spm1003.2166.3001.6637.1 1.创建数据表&#xff08;book&#xff09; # 创建book表 create table book(id int auto_increment primary key,name varchar(255) ,price double ,num int )…

Linux OpenSSH最新版9.7p1升级操作详细教程

原创声明&#xff1a;非本人许可&#xff0c;谢绝转载&#xff01; 1.背景说明 前几天与朋友闲聊中得知他朋友圈有服务器因OpenSSH漏洞遭受攻击的事情&#xff0c;OpenSSH重要性这里就不废话了&#xff0c;在网上一查&#xff0c;公布的漏洞还真不少&#xff0c;其中还有不少…

RK3588平台开发系列讲解(PCIe开发篇2)

根据原理图填写DTS 原理图是基于IO信号的视⻆来描述硬件&#xff0c;IO信号是跟PHY的index强相关的&#xff0c;前⾯提到RK3588的controller和PHY的index可能不⼀致&#xff0c;所以看原理图的时候需要特别注意这⼀点。这⾥给出⼀些填写建议&#xff0c;并通过⽰例说明如何将原…

socket通信基础讲解及示例-C

socket通信之C篇 服务端与客户端简介 socket通信服务端与客户端通信模型通信实战server&#xff08;服务端&#xff09;创建client&#xff08;客户端&#xff09;创建 函数详解创建套接字 socket绑定端口bind进入监听状态listen获取客户端连接请求accept接收网络数据read发送数…

音素与视素(Viseme)

什么是视素&#xff08;视位&#xff09; 音素(Phoneme)&#xff0c;是人类语言中能够区别意义的最小声音单位。视素(Viseme)&#xff0c;是指与某一音素相对应的嘴、舌头、下腭等可视发音器官所处的状态。Viseme是MPEG-4 标准提出来的概念。 有时Viseme也翻译为视位。下面会…

JavaEE初阶Day 10:多线程(8)

目录 Day 10&#xff1a;多线程&#xff08;8&#xff09;单例模式阻塞队列1. 生产者消费者模型1.1 生产者消费者模型解耦合1.2 生产者消费者模型削峰填谷 2. 生产者消费者代码3. 阻塞队列实现 Day 10&#xff1a;多线程&#xff08;8&#xff09; 单例模式 单例模式&#xf…