[java数据结构] ArrayList和LinkedList介绍与使用

目录

(一) 线性表

(二) ArrayList

1. ArrayList的介绍

2. ArrayList的常见方法和使用

3. ArrayList的遍历

4. ArrayList的模拟实现

5. ArrayList的优缺点

(三) LinkedList

1. LinkedList的介绍

2. LinkedList的常见方法和使用

3. LinkedList的遍历

4. LinkedList的模拟实现

5. LinkedList的优缺点

(四) ArrayList和LinkedList的区别

总结


(一) 线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结 构,常见的线性表:顺序表、链表、栈、队列...

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物 理上存储时,通常以数组和链式结构的形式存储。如下图:

(二) ArrayList

1. ArrayList的介绍

ArrayList是Java中的一个动态数组类, 即顺序表,可以动态地增加或减少数组的大小。它是一个可以动态改变大小的数组,可以根据需要自动地增加或减少数组的大小。ArrayList可以存储任意类型的对象,包括基本数据类型和引用类型, 它实现了List接口, 具体框架图如下:

[说明]

1. ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问

2. ArrayList实现了Cloneable接口,表明ArrayList是可以clone的

3. ArrayList实现了Serializable接口,表明ArrayList是支持序列化的

4. 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者 CopyOnWriteArrayList

5. ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表

2. ArrayList的常见方法和使用

使用ArrayList可以方便地进行元素的添加、删除和查找操作,是Java中常用的集合类之一。

ArrayList类包含许多常用的方法,以下是一些常见的方法和它们的使用:

常见的方法

  • boolean add(E e):向ArrayList中尾插 一个元素e。
  • void add(int index, E element): 将 e 插入到 index 位置
  • E remove(int index):移除指定索引位置的元素。
  • E get(int index):获取指定索引位置的元素。
  • size():获取ArrayList的大小
  • E set(int index, E element): 将下标 index 位置元素设置为 element
  • void clear(): 清空
  • boolean contains(Object o):判断ArrayList是否包含指定的元素。
  • int indexOf(Object o):返回指定元素在ArrayList中第一次出现的索引。
  • int lastIndexOf(Object o): 返回指定元素在ArrayList中最后一次出现的索引。

  使用:

import java.util.ArrayList;public class ArrayListExample {public static void main(String[] args) {// 创建一个ArrayListArrayList<String> list = new ArrayList<>();// 向ArrayList中尾插元素list.add("apple");list.add("banana");list.add("orange");// 将元素插入到指定索引位置list.add(1, "grape");//遍历ArrayListSystem.out.print("打印1: ");for (String ret: list) {System.out.print(ret+" ");}System.out.println();// 移除指定索引位置的元素list.remove(2);//遍历ArrayListSystem.out.print("打印2: ");for (String ret: list) {System.out.print(ret+" ");}System.out.println();// 获取指定索引位置的元素String fruit = list.get(0);System.out.println("索引0处的水果: " + fruit);// 获取ArrayList的大小int size = list.size();System.out.println("ArrayList的大小: " + size);// 将指定索引位置的元素设置为新元素list.set(2, "cherry");// 判断ArrayList是否包含指定的元素boolean contains = list.contains("apple");System.out.println("是否包含'apple': " + contains);// 返回指定元素在ArrayList中第一次出现的索引int index = list.indexOf("banana");System.out.println("'banana'第一次出现的索引: " + index);// 返回指定元素在ArrayList中最后一次出现的索引int lastIndex = list.lastIndexOf("apple");System.out.println("'apple'最后一次出现的索引: " + lastIndex);// 清空ArrayListlist.clear();//遍历ArrayListSystem.out.print("打印3: ");for (String ret: list) {System.out.print(ret+" ");}System.out.println();}
}

3. ArrayList的遍历

ArrayList可以使用三种方式遍历:for循环+下标、foreach、使用迭代器, 代码如下:

import java.util.ArrayList;public class ArrayListExample {public static void main(String[] args) {// 创建一个ArrayList对象,它是List接口的实现类List<String> list = new ArrayList<>();// 将指定的元素添加到列表的末尾list.add("apple");list.add("banana");list.add("cherry");//for循环+下标System.out.print("for循环+下标: ");for (int i = 0; i < list.size(); i++) {System.out.print(list.get(i)+" ");}System.out.println();//foreach遍历System.out.print("foreach遍历: ");for (String ret : list) {System.out.print(ret+" ");}System.out.println();//使用迭代器System.out.print("迭代器遍历: ");Iterator<String> iter = list.iterator();while (iter.hasNext()){String ret = iter.next();System.out.print(ret+" ");}System.out.println();}
}

4. ArrayList的模拟实现
package List;import java.util.Arrays;// 自定义的ArrayList类
public class MyArrayList {public int[] arr; // 用于存储元素的数组public int size; // 记录当前数组中的元素个数public static final int Max = 10; // 默认最大容量// 构造方法,初始化数组public MyArrayList() {this.arr = new int[10];}// 打印元素public void display() {for (int i = 0; i < this.size; i++) {System.out.print(arr[i] + " ");}System.out.println();}// 增加元素public void add(int data) {if (isFull()) {arr = Arrays.copyOf(arr, arr.length * 2); // 如果数组已满,扩容为原来的两倍}arr[size++] = data;}// 判断数组是否已满public boolean isFull() {if (size == Max) {return true;}return false;}// 检查插入位置是否合法private void checkAddPos(int pos) {if (pos < 0 || pos > size) {throw new PosIndexNotLegalException("pos位置不合法");}}// 在指定位置插入元素public void add(int pos, int data) {try {checkAddPos(pos);if (isFull()) {arr = Arrays.copyOf(arr, 2 * arr.length); // 如果数组已满,扩容为原来的两倍}for (int i = size - 1; i >= pos; i--) {arr[i + 1] = arr[i]; // 元素后移}arr[pos] = data; // 在指定位置插入新元素size++;} catch (PosIndexNotLegalException e) {e.printStackTrace();}}// 判断是否包含某个元素public boolean contains(int toFind) {for (int i = 0; i < size; i++) {if (arr[i] == toFind) {return true;}}return false;}// 查找某个元素对应的位置public int indexOf(int toFind) {for (int i = 0; i < size; i++) {if (arr[i] == toFind) {return i;}}return -1; // 如果找不到返回-1}// 获取指定位置的元素public int get(int pos) {checkAddPos(pos);return arr[pos];}// 给指定位置的元素赋值public void set(int pos, int value) {checkAddPos(pos);arr[pos] = value;}// 删除第一次出现的指定元素public void remove(int toRemove) {int index = indexOf(toRemove);if (index == -1) {System.out.println("没有你要删除的数字!");return;}for (int j = index; j < size; j++) {arr[j] = arr[j + 1]; // 元素前移}size--;}// 获取顺序表长度public int size() {int ret = size;return ret;}// 清空顺序表public void clear() {size = 0; // 将元素个数置为0,实现清空操作}
}
5. ArrayList的优缺点

优点:

  1. 随机访问:由于 ArrayList 使用数组来存储元素,可以通过索引快速访问元素,性能较好,时间复杂度为 O(1)。
  2. 灵活的大小:ArrayList 的大小可以动态调整,不需要预先指定数组大小,可以根据需求动态增加或减少元素。

缺点:

  1. 插入和删除效率低:在 ArrayList 中间或开头插入或删除元素时,需要移动后续元素,时间复杂度为 O(n),性能较差。
  2. 内存开销:ArrayList 在动态扩容时需要重新分配内存并拷贝元素,可能会产生额外的内存开销。

总结

ArrayList 适合需要频繁随机访问元素、对大小变化较为频繁的场景,但在大量插入和删除操作时性能较差。

(三) LinkedList

1. LinkedList的介绍

在前面ArrayList我们知道,当在ArrayList任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后搬移,时间复杂度为O(n),效率比较低,因此ArrayList不适合做任意位置插入和删除比较多的场景。因此:java 集合中又引入了LinkedList,即链表结构。

LinkedList 是 Java 中的一个无头双向链表。实现,实现了 List 和 Deque 接口,LinkedList 内部是使用无头双向循环链表。表来存储元素,每个节点包含对前一个节点和后一个节点的引用。LinkedList 支持在任意位置进行高效的插入和删除操作,时间复杂度为 O(1)。无头双向链表结构图:

双向链表的每个节点都有 3 个属性:

  1. data : 实际存放的内容;

  2. prev : 指向前一节点的指针;

  3. next : 指向后一节点的指针。

实际中链表的结构非常多样,单向或者双向, 带头或者不带头, 循环或者非循环

虽然有这么多的链表的结构,但是我们重点掌握两种:

无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如 哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。

无头双向链表:在Java的集合框架库中LinkedList底层实现就是无头双向循环链表。

2. LinkedList的常见方法和使用

LinkedList 类实现了 List 接口,因此它包含了 List 接口定义的所有方法,例如 add、remove、get、set 等。此外,LinkedList 还包含了一些特有的方法,如 addFirst、addLast等,用于在链表的开头或结尾进行操作

常见方法

  • boolean add(E e): 在链表的末尾添加元素。
  • void addFirst(E e): 在链表的开头添加元素。
  • void addLast(E e): 在链表的末尾添加元素。
  • E get(int index): 获取指定位置的元素。
  • E set(int index, E element) 将下标 index 位置元素设置为 element
  • boolean remove(): 删除并返回链表的第一个元素。
  • String removeFirst(): 删除并返回链表的第一个元素。
  • String removeLast(): 删除并返回链表的最后一个元素。
  • int size(): 获取链表的大小。
  • boolean contains(Object o): 判断链表是否包含指定的元素。
  • int indexOf(Object o): 返回指定元素在链表中第一次出现的位置。
  • int lastIndexOf(Object o) 返回最后一个 o 的下标
  • void clear() 清空
import java.util.LinkedList;
class Main {public static void main(String[] args) {LinkedList<String> linkedList = new LinkedList<>();// 添加元素linkedList.add("A");System.out.println("添加 'A' 后的链表: " + linkedList);linkedList.addFirst("B");System.out.println("在链表开头添加 'B' 后的链表: " + linkedList);linkedList.addLast("C");System.out.println("在链表末尾添加 'C' 后的链表: " + linkedList);// 获取元素String elementAtIndex1 = linkedList.get(1);System.out.println("索引为 1 的元素: " + elementAtIndex1);// 设置元素linkedList.set(0, "D");System.out.println("将索引为 0 的元素设置为 'D' 后的链表: " + linkedList);// 删除元素String removedElement = linkedList.remove();System.out.println("删除的元素: " + removedElement);String removedFirst = linkedList.removeFirst();System.out.println("删除的第一个元素: " + removedFirst);String removedLast = linkedList.removeLast();System.out.println("删除的最后一个元素: " + removedLast);// 获取链表大小int size = linkedList.size();System.out.println("链表的大小: " + size);// 判断是否包含元素boolean contains = linkedList.contains("A");System.out.println("链表是否包含 'A': " + contains);// 获取元素的索引int index = linkedList.indexOf("B");System.out.println("'B' 在链表中的索引: " + index);// 清空链表linkedList.clear();System.out.println("清空链表后的结果: " + linkedList);}
}

3. LinkedList的遍历

可以使用foreach、迭代器来访问链表中的每个元素。 代码如下:

import java.util.LinkedList;
import java.util.Iterator;public class Main {public static void main(String[] args) {LinkedList<String> linkedList = new LinkedList<>();linkedList.add("A");linkedList.add("B");linkedList.add("C");// 使用迭代器遍历Iterator<String> iterator = linkedList.iterator();while (iterator.hasNext()) {String element = iterator.next();System.out.println("Element: " + element);}// 使用foreach遍历for (String element : linkedList) {System.out.println("Element: " + element);}}
}

4. LinkedList的模拟实现

无头单向非循环链表代码如下:

public class SingleLinkedList {// 定义节点类static class Node {public int val;public Node next;public Node(int val) {this.val = val;}}public Node head; // 链表头节点// 头插法public void addFirst(int data) {Node node = new Node(data);if (head == null) {head = node;} else {node.next = head;head = node;}}// 尾插法public void addLast(int data) {Node node = new Node(data);if (head == null) {head = node;return;} else {Node cur = head;while (cur.next != null) {cur = cur.next;}cur.next = node;}}// 任意位置插入,第一个数据节点为0号下标public void addIndex(int index, int data) {checkIndex(index);if (index == 0) {addFirst(data);return;}if (index == size()) {addLast(data);return;}Node node = new Node(data);// 找到要插入的前一个位置Node cur = prevIndex(index - 1);node.next = cur.next;cur.next = node;}private void checkIndex(int index) {if (index < 0 || index > size()) {throw new IndexNotLegalException("index位置不合法!");}}private Node prevIndex(int index) {Node cur = head;while (index > 0) {cur = cur.next;index--;}return cur;}// 查找是否包含关键字key是否在单链表当中public boolean contains(int key) {if (head == null) return false;Node cur = head;while (cur != null) {if (cur.val == key) {return true;}cur = cur.next;}return false;}// 删除第一次出现关键字为key的节点public void remove(int key) {if (head == null) return;if (head.val == key) {head = head.next;return;}Node cur = head.next;Node prev = head;while (cur != null) {if (cur.val == key) {prev.next = cur.next;return;} else {prev = cur;cur = cur.next;}}}// 删除所有值为key的节点public void removeAllKey(int key) {if (head == null) return;Node cur = head.next;Node prev = head;while (cur != null) {if (cur.val == key) {prev.next = cur.next;cur = cur.next;} else {prev = cur;cur = cur.next;}}if (head.val == key) {head = head.next;}}// 得到单链表的长度public int size() {Node cur = head;int count = 0;while (cur != null) {count++;cur = cur.next;}return count;}// 打印链表public void display() {Node cur = head;while (cur != null) {System.out.print(cur.val + " ");cur = cur.next;}System.out.println();}// 清空链表public void clear() {if (head == null) return;Node cur = head;while (cur != null) {Node curNext = cur.next;cur.next = null;cur = curNext;}head = null;}// 一道练习题  -- 单链表的逆置// 递归.单链表的逆置public Node reverseList(Node head) {if (head == null) {return head;}if (head.next == null) {return head;}Node newHead = reverseList(head.next);head.next.next = head;// 要注意的是的下一个节点必须指向∅。如果忽略了这一点,链表中会产生环,所以每反转一个,要把原来下个结点置null;head.next = null;return newHead;}// 非递归.单链表的逆置public Node reverseList1() {Node cur = head;Node prev = null;while (cur != null) {Node nextCur = cur.next;cur.next = prev;prev = cur;cur = nextCur;}return prev;}}

无头双向循环链表的实现如下:

package MyLinkedList;// 无头双向链表实现
public class MyTwoLinkedList {// 定义节点类static class ListNode {public int val;public ListNode next; //指向下一个节点public ListNode prev; //指向上一个节点public ListNode(int val) {this.val = val;}}public ListNode head; // 表示存储当前链表的头节点的引用public ListNode last; // 尾节点// 打印链表public void display() {ListNode cur = head;while (cur != null) {System.out.print(cur.val + " ");cur = cur.next;}System.out.println();}// 头插法public void addFirst(int data) {ListNode node = new ListNode(data);if (head == null) {head = node;last = node;} else {node.next = head;head.prev = node;head = node;}}// 尾插法public void addLast(int data) {ListNode node = new ListNode(data);if (head == null) {head = node;last = node;return;}last.next = node;node.prev = last;last = last.next;}// 根据索引查找节点private ListNode findIndex(int index) {ListNode cur = head;while (index > 0) {index--;cur = cur.next;}return cur;}// 任意位置插入,第一个数据节点为0号下标public void addIndex(int index, int data) {ListNode node = new ListNode(data);if (index < 0 || index > this.size()) {throw new IndexNotLegalException("双向链表index不合法!");}if (index == 0) {addFirst(data);return;}if (index == size()) {addLast(data);return;}// 获取到当前的index位置的节点的地址ListNode cur = findIndex(index);node.next = cur;cur.prev.next = node;node.prev = cur.prev;cur.prev = node;}// 查找是否包含关键字key是否在单链表当中public boolean contains(int key) {ListNode cur = head;while (cur != null) {if (cur.val == key) {return true;}cur = cur.next;}return false;}// 删除第一次出现关键字为key的节点public void remove(int key) {ListNode cur = head;while (cur != null) {if (cur.val == key) {if (cur == head) {head = head.next;if (head != null) { // 防止只有一个节点head.prev = null;}} else {cur.prev.next = cur.next;// 删除的不是尾巴节点if (last.val != key) {cur.next.prev = cur.prev;} else {last = cur.prev;}}return;}cur = cur.next;}}// 删除所有值为key的节点public void removeAllKey(int key) {ListNode cur = head;while (cur != null) {if (cur.val == key) {if (cur == head) {head = head.next;if (head != null) { // 防止只有一个节点head.prev = null;}} else {cur.prev.next = cur.next;// 删除的不是尾巴节点if (cur.next != null) {cur.next.prev = cur.prev;} else {// 删除的是尾结点last = cur.prev;}}}cur = cur.next;}}// 得到单链表的长度public int size() {ListNode cur = head;int len = 0;while (cur != null) {len++;cur = cur.next;}return len;}// 清空链表public void clear() {ListNode cur = head;while (cur != null) {ListNode nextCur = cur.next;cur.next = null;cur.prev = null;cur = nextCur;}head = null;last = null;}
}
5. LinkedList的优缺点

优点:

  1. 插入和删除操作效率高:在链表中插入和删除元素的效率很高,只需要修改节点的指针,不需要移动其他元素。
  2. 灵活性:链表可以动态地分配内存空间,可以根据需要动态地添加或删除节点。

缺点:

  1. 随机访问效率低:链表中要想访问第k个元素,需要从头节点开始顺序遍历,时间复杂度为O(n)。
  2. 占用空间多:链表中每个节点都需要额外的空间来存储指针,占用的空间比数组大。
  3. 不支持随机访问:链表不支持通过下标直接访问元素,只能通过指针进行遍历访问。

总结

LinkedList 适合需要频繁插入和删除操作、对随机访问要求不高的场景,但在需要频繁随机访问元素时性能较差。

(四) ArrayList和LinkedList的区别

ArrayList 和 LinkedList 都是 Java 中的集合类,用于存储一组元素。它们之间的主要区别在于底层的数据结构和对元素的访问方式。

ArrayList 是基于数组实现的动态数组,它提供了快速的随机访问和遍历。在 ArrayList 中,每个元素都有一个索引,可以通过索引快速访问元素,但在插入和删除元素时需要移动其他元素,因此插入和删除操作的效率较低。

LinkedList 是基于链表实现的双向链表,它提供了快速的插入和删除操作。在 LinkedList 中,每个元素都包含对前一个元素和后一个元素的引用,因此插入和删除操作的效率比较高。但是在访问元素时需要从头或尾开始遍历,因此随机访问的效率较低。

总结

如果需要频繁进行插入和删除操作,可以选择 LinkedList;如果需要频繁进行随机访问和遍历操作,可以选择 ArrayList。

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

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

相关文章

力扣每日一练(24-1-18)

经验一&#xff1a;不要把问题想复杂 Python&#xff1a; min_price float(inf)max_profit 0for price in prices:min_price min(min_price, price)max_profit max(max_profit, price - min_price)return max_profit C#&#xff1a; public int MaxProfit(int[] prices) {i…

强化学习(二)多臂老虎机 “Multi-armed Bandits”——1

将强化学习与机器学习、深度学习区分开的最重要的特征为&#xff1a;它通过训练中信息来评估所采取的动作&#xff0c;而不是给出正确的动作进行指导&#xff0c;这极大地促进了寻找更优动作的需求。 1、多臂老虎机&#xff08;Multi-armed Bandits&#xff09;问题 赌场的老虎…

WPF入门到跪下 第十一章 Prism(一)数据处理

官网&#xff1a;https://primslibrary.com 源码地址&#xff1a;https://guthub.com/PrismLibrary/prism Prism是由微软发布、维护的开源框架&#xff0c;提供了一组设计模式的实现&#xff0c;有助于编写结构良好的且可维护的XAML应用程序&#xff0c;包括MVVM、依赖注入、命…

实验三 Oracle数据库的创建和管理

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的很重要&…

HackTheBox - Medium - Linux - Health

Health Health 是一台中型 Linux 计算机&#xff0c;在主网页上存在 SSRF 漏洞&#xff0c;可利用该漏洞访问仅在 localhost 上可用的服务。更具体地说&#xff0c;Gogs 实例只能通过 localhost 访问&#xff0c;并且此特定版本容易受到 SQL 注入攻击。由于攻击者可以与 Gogs …

Redis基础知识(一)

一 Redis的数据类型 1.1 基本数据类型&#xff1a; String(字符串) Hash(哈希表) List(列表) Set(集合) ZSet(有序集合) 1.2 特殊类型 GEO(地理空间) HyperLogLog(基数统计) bitMap(位图) bitField(位域…

架构的演进

1.1单体架构 单体架构也称之为单体系统或者是单体应用。就是一种把系统中所有的功能、模块耦合在一个应用中的架构方式。 存在的问题&#xff1a; 代码耦合&#xff1a;模块的边界模糊、依赖关系不清晰&#xff0c;整个项目非常复杂&#xff0c;每次修改代码都心惊胆战迭代困…

RabbitMQ 部署与配置[CentOS7]

# RabbitMQ,Erlang 版本包对应 https://rabbitmq.com/which-erlang.html#eol-seriescd /usr/local/src# Erlang下载 # https://github.com/rabbitmq/erlang-rpm/releases https://github.com/rabbitmq/erlang-rpm/releases/download/v23.3.4.5/erlang-23.3.4.5-1.el7.x86_64.rp…

NTFS 磁盘管理器---NTFS Disk by Omi NTFS中文

NTFS Disk by Omi NTFS是一款专为Mac用户设计的NTFS磁盘管理工具。它可以帮助用户方便地访问和管理NTFS格式的硬盘、U盘、移动硬盘以及其他存储设备&#xff0c;并提供高效稳定的NTFS卷管理功能。该软件具有简单的用户界面&#xff0c;使用户能够快速访问和管理NTFS磁盘上的文件…

ChatGPT给出的前端面试考点(Vue.js)

ChatGPT给出的前端面试考点&#xff08;Vue.js&#xff09; 答案 1. Vue.js是什么&#xff1f;它的主要特点是什么&#xff1f; Vue.js是一个渐进式JavaScript框架&#xff0c;用于构建用户界面。它的主要特点包括&#xff1a; 数据绑定&#xff1a;Vue.js使用双向数据绑定&…

图灵日记之java奇妙历险记--String类

目录 String常用方法字符串构造String对象的比较字符串查找char charAt(int index)int indexOf(int ch)int indexOf(int ch, int fromIndex)int indexOf(String str)int indexOf(String str, int fromIndex)int lastIndexOf(String str)int lastIndexOf(String str, int fromIn…

OceanBase集群扩缩容

​ OceanBase 数据库采用 Shared-Nothing 架构&#xff0c;各个节点之间完全对等&#xff0c;每个节点都有自己的 SQL 引擎、存储引擎、事务引擎&#xff0c;天然支持多租户&#xff0c;租户间资源、数据隔离&#xff0c;集群运行的最小资源单元是Unit&#xff0c;每个租户在每…

OPC UA 开源库编译方法及通过OPC UA连接西门S7-1200 PLC通信并进行数据交换

前言 在现代工业自动化领域&#xff0c;OPC UA&#xff08;开放性生产控制和统一架构&#xff09;是一种广泛应用的通信协议。本文将以通俗易懂的方式解释OPC UA的含义和作用&#xff0c;帮助读者更好地理解这一概念。 一、OPC UA的定义 OPC UA全称为“开放性生产控制和统一…

Labview实现用户界面切换的几种方式---通过VI间相互调用

在做用户界面时我们的程序往往面对的对象是程序使用者&#xff0c;复杂程序如果放在同一个页面中&#xff0c;往往会导致程序冗长卡顿&#xff0c;此时通过多个VI之间的切换就可以实现多个界面之间的转换&#xff0c;也会显得程序更加的高大上。 本文所有程序均可下载&#xff…

【Python机器学习】多分类问题的不确定度

decision_function和predict_proba也适用于多分类问题。还是以鸢尾花数据集为例&#xff1a; from sklearn.ensemble import GradientBoostingClassifier from sklearn.datasets import make_circles,load_iris import numpy as np from sklearn.model_selection import train_…

【总结】Dinky学习笔记

概述 Dinky 是一个开箱即用、易扩展&#xff0c;以 Apache Flink 为基础&#xff0c;连接 OLAP 和数据湖等众多框架的一站式实时计算平台&#xff0c;致力于流批一体和湖仓一体的探索与实践 官网&#xff1a;Dinky 核心特性 沉浸式&#xff1a;提供专业的 DataStudio 功能&a…

1979-A threshold selection method from gray-level histograms

1 论文简介 《A threshold selection method from gray-level histograms》是由日本学者大津于 1979 年发表在 IEEE TRANSACTIONS ON SYSTEMS 上的一篇论文。该论文提出了一种基于图像灰度直方图的阈值化方法&#xff0c;计算简单&#xff0c;且不受图像亮度和对比度的影响&am…

64.Spring事件监听的核心机制是什么?

Spring事件监听的核心机制是什么? spring的事件监听有三个部分组成 事件(ApplicationEvent) 负责对应相应监听器 事件源发生某事件是特定事件监听器被触发的原因监听器(ApplicationListener) 对应于观察者模式中的观察者。监听器监听特定事件,并在内部定义了事件发生后的响应…

【论文阅读】ControlNet、文章作者 github 上的 discussions

文章目录 IntroductionMethodControlNetControlNet for Text-to-Image DiffusionTrainingInference Experiments消融实验定量分析 在作者 github 上的一些讨论消融实验更进一步的探索Precomputed ControlNet 加快模型推理迁移控制能力到其他 SD1.X 模型上其他 Introduction 提…

烟火检测/区域人流统计/AI智能分析网关V4如何配置通道?

TSINGSEE青犀智能分析网关&#xff08;V4版&#xff09;是一款高性能、低功耗的软硬一体AI边缘计算硬件设备&#xff0c;硬件内部署了近40种AI算法模型&#xff0c;支持对接入的视频图像进行人、车、物、行为等实时检测分析&#xff0c;并上报识别结果&#xff0c;并能进行语音…