Java集合(全)

Java提供了多种集合框架类,每种都有不同的特性和用途。以下是Java中常见的集合类:

1、List(列表):

ArrayList

ArrayList 是 Java 集合框架中的一个常用类,实现了动态数组的数据结构。与传统的数组相比,ArrayList 具有动态调整大小的能力,可以方便地进行元素的添加、删除和访问。以下是关于 ArrayList 的介绍和使用方法:

特点:

1、动态数组: ArrayList 是基于动态数组的实现,可以动态地增加或减少元素的数量。

2、随机访问: 通过索引可以快速随机访问列表中的元素。

3、自动扩容: 当元素数量超过当前容量时,ArrayList 会自动扩展容量以适应更多的元素。

4、支持泛型: ArrayList 支持泛型,可以存储任意类型的对象。

基本使用:

1、创建 ArrayList 对象:

import java.util.ArrayList;// 创建一个空的 ArrayList
ArrayList<String> arrayList = new ArrayList<>();// 创建带有初始容量的 ArrayList
ArrayList<Integer> intList = new ArrayList<>(10);

2、添加元素:

arrayList.add("Java");
arrayList.add("Python");
arrayList.add("C++");

3、访问元素:

String firstElement = arrayList.get(0);
System.out.println("First Element: " + firstElement);

4、删除元素:

arrayList.remove("Python");

5、迭代 ArrayList:

for (String element : arrayList) {System.out.println(element);
}

6、获取 ArrayList 的大小:

int size = arrayList.size();
System.out.println("Size: " + size);

注意事项:

1、ArrayList 是非同步的,不适合在多线程环境中使用。如果需要在多线程环境中使用,可以考虑使用 Vector 或者使用 Collections.synchronizedList 方法使 ArrayList 变为同步的。

2、如果需要在中间插入或删除元素频繁的场景,可能会使用 LinkedList 更为高效。

ArrayList 是 Java 集合框架中最常用的类之一,适用于许多不同的应用场景,从简单的列表到更复杂的数据结构。

LinkedList

LinkedList 是 Java 集合框架中的一个类,它实现了双向链表的数据结构。与 ArrayList 不同,LinkedList 不是基于动态数组实现的,而是通过节点之间的链接来组织元素。以下是关于 LinkedList 的介绍和使用方法:

特点:

1、双向链表: 每个节点包含数据元素和对前后节点的引用,使得在链表中可以双向遍历。

2、动态插入和删除: 由于链表的结构,LinkedList 在中间插入或删除元素的操作比 ArrayList 更为高效。

3、非同步: LinkedList 不是同步的,不适合在多线程环境中直接使用。在多线程环境中,可以使用 Collections.synchronizedList 方法包装它,或者考虑使用 LinkedBlockingDeque 等并发集合。

基本使用:

1、创建 LinkedList 对象:

import java.util.LinkedList;// 创建一个空的 LinkedList
LinkedList<String> linkedList = new LinkedList<>();

2、添加元素:

linkedList.add("Java");
linkedList.add("Python");
linkedList.add("C++");

3、在指定位置插入元素:

linkedList.add(1, "JavaScript");

4、访问元素:

String firstElement = linkedList.getFirst();
System.out.println("First Element: " + firstElement);

5、删除元素:

linkedList.remove("Python");

6、迭代 LinkedList:

for (String element : linkedList) {System.out.println(element);
}

7、获取 LinkedList 的大小:

int size = linkedList.size();
System.out.println("Size: " + size);

8、使用迭代器逆向遍历:

ListIterator<String> iterator = linkedList.listIterator(linkedList.size());
while (iterator.hasPrevious()) {String element = iterator.previous();System.out.println(element);
}

注意事项:

1、LinkedList 在需要频繁插入、删除元素或双向遍历的场景中表现更为出色。

2、如果对元素的随机访问较多,可以考虑使用 ArrayList。

3、在大多数情况下,考虑使用 List 接口来声明变量,以便可以更轻松地更改底层实现。例如:

List<String> list = new LinkedList<>();  // 或者 List<String> list = new ArrayList<>();

LinkedList 在某些特定的应用场景下非常有用,但在其他场景中可能不如 ArrayList 效率高。
选择使用哪个取决于你的具体需求和对性能的要求。

Vector

Vector 是 Java 集合框架中的一个传统类,它实现了动态数组的数据结构,与 ArrayList 类似。然而,与 ArrayList 不同的是,Vector 是同步的,因此其方法都是线程安全的。以下是关于 Vector 的介绍和使用方法:

特点:

1、同步性: Vector 是同步的,这意味着它的方法都是线程安全的。在多线程环境中,可以确保多个线程不会同时修改 Vector 对象。

2、动态数组: Vector 是基于动态数组的数据结构,可以动态地增加或减少元素的数量。

3、初始容量和增长因子: Vector 可以在创建时指定初始容量,它还具有一个增长因子,用于在需要时自动增加容量。

基本使用:

1、创建 Vector 对象:

import java.util.Vector;// 创建一个空的 Vector
Vector<String> vector = new Vector<>();// 创建指定初始容量的 Vector
Vector<Integer> intVector = new Vector<>(10);

2、添加元素:

vector.add("Java");
vector.add("Python");
vector.add("C++");

3、访问元素:

String firstElement = vector.get(0);
System.out.println("First Element: " + firstElement);

4、删除元素:

vector.remove("Python");

5、迭代 Vector:

for (String element : vector) {System.out.println(element);
}

6、获取 Vector 的大小和容量:

int size = vector.size();
int capacity = vector.capacity();
System.out.println("Size: " + size);
System.out.println("Capacity: " + capacity);

7、同步访问:

由于 Vector 是同步的,可以在多线程环境中安全使用,但在单线程环境下使用 ArrayList 可能更高效。

注意事项:

1、由于同步的开销,除非需要线程安全,否则建议使用 ArrayList 或者其他非同步的集合类。

2、如果需要在中间插入或删除元素频繁的场景,可能会使用 LinkedList 更为高效。

总的来说,Vector 在现代 Java 开发中不常用,因为它的同步性能开销相对较高,而且有更现代的替代品,如 ArrayList 和 LinkedList,它们在大多数情况下更为常见和高效。

Stack

Stack 是 Java 集合框架中的一个类,它实现了后进先出(LIFO)的堆栈数据结构。Stack 继承自 Vector 类,因此它保留了 Vector 的同步性,但由于其特定的用途,通常建议使用更现代的 Deque 接口的实现类 LinkedList 代替 Stack。以下是关于 Stack 的介绍和使用方法:

特点:

1、后进先出(LIFO): Stack 是一种后进先出的数据结构,即最后添加的元素最先被移除。

2、继承自 Vector: Stack 类继承自 Vector,因此具有 Vector 的同步性。

基本使用:

1、创建 Stack 对象:

import java.util.Stack;// 创建一个空的 Stack
Stack<String> stack = new Stack<>();

2、压栈和弹栈:

stack.push("Java");
stack.push("Python");
stack.push("C++");// 弹出栈顶元素
String topElement = stack.pop();
System.out.println("Top Element: " + topElement);

3、查看栈顶元素:

String peekElement = stack.peek();
System.out.println("Top Element (without removing): " + peekElement);

4、判断栈是否为空:

boolean isEmpty = stack.isEmpty();
System.out.println("Is Stack Empty? " + isEmpty);

5、获取栈的大小:

int size = stack.size();
System.out.println("Stack Size: " + size);

注意事项:

1、Stack 的同步性使得在多线程环境中可以安全使用,但如果不需要同步,推荐使用 LinkedList 作为栈的替代品。

2、在现代 Java 编程中,更常用的做法是使用 Deque 接口的实现类 LinkedList 来实现栈的功能,因为它提供了更多灵活性和性能。

下面是使用 LinkedList 实现栈的示例:

import java.util.LinkedList;// 创建一个空的栈
LinkedList<String> stack = new LinkedList<>();// 压栈
stack.push("Java");
stack.push("Python");
stack.push("C++");// 弹栈
String topElement = stack.pop();
System.out.println("Top Element: " + topElement);

总体而言,在现代 Java 编程中,推荐使用 Deque 接口的实现类 LinkedList 或者 ArrayDeque 来实现栈的功能。

2、Set(集合):

HashSet

HashSet 是 Java 集合框架中的一个类,它实现了 Set 接口,基于哈希表实现。以下是关于 HashSet 的介绍和使用方法:

特点:

1、无序性: HashSet 不保证元素的顺序,即你添加元素的顺序不一定就是元素被存储的顺序。

2、唯一性: HashSet 中不能包含重复的元素。如果尝试将重复的元素添加到 HashSet 中,添加操作将被忽略。

3、基于哈希表: HashSet 使用哈希表来存储元素,因此具有快速的查找性能。

基本使用:

1、创建 HashSet 对象:

import java.util.HashSet;// 创建一个空的 HashSet
HashSet<String> hashSet = new HashSet<>();

2、添加元素:

hashSet.add("Java");
hashSet.add("Python");
hashSet.add("C++");

3、判断元素是否存在:

boolean containsJava = hashSet.contains("Java");
System.out.println("Contains Java? " + containsJava);

4、删除元素:

hashSet.remove("Python");

5、获取 HashSet 的大小:

int size = hashSet.size();
System.out.println("HashSet Size: " + size);

6、迭代 HashSet:

for (String element : hashSet) {System.out.println(element);
}

注意事项:

1、由于 HashSet 是基于哈希表实现的,元素的存储顺序是不确定的。如果需要有序性,可以考虑使用 LinkedHashSet。

2、HashSet 对元素的唯一性的判断是通过元素的 hashCode 和 equals 方法来完成的。因此,如果你在自定义类中使用 HashSet,确保正确实现了 hashCode 和 equals 方法。

3、HashSet 不是同步的,如果需要在多线程环境中使用,可以考虑使用 Collections.synchronizedSet 方法包装它,或者使用 ConcurrentHashSet。

HashSet 是在很多场景下都很有用的集合类,特别是在需要快速查找不重复元素的情况下。

LinkedHashSet

LinkedHashSet 是 Java 集合框架中的一个类,它是 HashSet 的一个子类,实现了 Set 接口。与 HashSet 不同的是,LinkedHashSet 维护元素的插入顺序,因此它提供了有序性。以下是关于 LinkedHashSet 的介绍和使用方法:

特点:

1、有序性: LinkedHashSet 会按照元素的插入顺序维护元素的顺序。因此,迭代 LinkedHashSet 时会按照插入的顺序返回元素。

2、唯一性: 与 HashSet 类似,LinkedHashSet 中不能包含重复的元素。

基本使用:

1、创建 LinkedHashSet 对象:

import java.util.LinkedHashSet;// 创建一个空的 LinkedHashSet
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();

2、添加元素:

linkedHashSet.add("Java");
linkedHashSet.add("Python");
linkedHashSet.add("C++");

3、判断元素是否存在:

boolean containsJava = linkedHashSet.contains("Java");
System.out.println("Contains Java? " + containsJava);

4、删除元素:

linkedHashSet.remove("Python");

5、获取 LinkedHashSet 的大小:

int size = linkedHashSet.size();
System.out.println("LinkedHashSet Size: " + size);

6、迭代 LinkedHashSet:

for (String element : linkedHashSet) {System.out.println(element);
}

注意事项:

1、LinkedHashSet 维护插入顺序的特性使得它适用于需要按照元素插入的顺序进行迭代的场景。

2、LinkedHashSet 不是同步的,如果需要在多线程环境中使用,可以考虑使用 Collections.synchronizedSet 方法包装它,或者使用 ConcurrentLinkedHashSet。

总体而言,LinkedHashSet 是在需要按照插入顺序保持元素的场景中很有用的集合类。

TreeSet

TreeSet 是 Java 集合框架中的一个类,它实现了 SortedSet 接口,是基于红黑树(Red-Black Tree)实现的有序集合。以下是关于 TreeSet 的介绍和使用方法:

特点:

1、有序性: TreeSet 会按照元素的自然顺序或者通过提供的比较器(Comparator)进行排序。
因此,迭代 TreeSet 时会按照升序顺序返回元素。

2、唯一性: 与 Set 接口相同,TreeSet 中不能包含重复的元素。

基本使用:

1、创建 TreeSet 对象:

import java.util.TreeSet;// 创建一个空的 TreeSet
TreeSet<String> treeSet = new TreeSet<>();

2、添加元素:

treeSet.add("Java");
treeSet.add("Python");
treeSet.add("C++");

3、判断元素是否存在:

boolean containsJava = treeSet.contains("Java");
System.out.println("Contains Java? " + containsJava);

4、删除元素:

treeSet.remove("Python");

5、获取 TreeSet 的大小:

int size = treeSet.size();
System.out.println("TreeSet Size: " + size);

6、迭代 TreeSet:

for (String element : treeSet) {System.out.println(element);
}

自定义排序:

TreeSet 可以通过提供一个比较器(Comparator)来实现自定义排序。例如,如果要按照字符串长度降序排序,可以创建一个比较器并传递给 TreeSet 的构造函数:

import java.util.TreeSet;
import java.util.Comparator;public class CustomComparatorExample {public static void main(String[] args) {// 创建一个基于字符串长度的降序排序的 TreeSetTreeSet<String> customTreeSet = new TreeSet<>(Comparator.comparing(String::length).reversed());// 添加元素customTreeSet.add("Java");customTreeSet.add("Python");customTreeSet.add("C++");// 迭代 TreeSetfor (String element : customTreeSet) {System.out.println(element);}}
}

注意事项:

1、如果元素是自定义类的对象,确保该类实现了 Comparable 接口或者在创建 TreeSet 时提供了比较器,以便 TreeSet 知道如何对元素进行排序。

2、TreeSet 的排序是基于元素的自然顺序或者提供的比较器,因此元素类型必须是可比较的。

3、TreeSet 不是同步的,如果需要在多线程环境中使用,可以考虑使用 Collections.synchronizedSortedSet 方法包装它,或者使用 ConcurrentSkipListSet。

TreeSet 在需要有序集合的场景中非常有用,尤其是当你需要按照自然顺序或者自定义的顺序迭代元素时。

3、Map(映射):

HashMap

HashMap 是 Java 集合框架中的一个类,它实现了 Map 接口,用于存储键值对。以下是关于 HashMap 的介绍和使用方法:

特点:

1、键值对存储: HashMap 存储的是键值对(key-value pair),每个键都映射到一个值。

2、无序性: HashMap 中的键值对没有固定的顺序,即你添加键值对的顺序不一定就是它们被存储的顺序。

3、唯一性: HashMap 中的键是唯一的,一个键只能对应一个值。但值可以重复。

4、基于哈希表: HashMap 使用哈希表实现,通过键的哈希码来快速定位键值对的存储位置,从而实现高效的查找、插入和删除操作。

基本使用:

1、创建 HashMap 对象:

import java.util.HashMap;
import java.util.Map;// 创建一个空的 HashMap
HashMap<String, Integer> hashMap = new HashMap<>();

2、添加键值对:

hashMap.put("Java", 1);
hashMap.put("Python", 2);
hashMap.put("C++", 3);

3、获取值:

int javaValue = hashMap.get("Java");
System.out.println("Java's value is: " + javaValue);

4、判断键是否存在:

boolean containsJava = hashMap.containsKey("Java");
System.out.println("Contains Java? " + containsJava);

5、删除键值对:

hashMap.remove("Python");

6、获取 HashMap 的大小:

int size = hashMap.size();
System.out.println("HashMap Size: " + size);

7、迭代 HashMap:

for (Map.Entry<String, Integer> entry : hashMap.entrySet()) {System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}

注意事项:

1、HashMap 不是同步的,如果需要在多线程环境中使用,可以考虑使用 Collections.synchronizedMap 方法包装它,或者使用 ConcurrentHashMap。

2、由于 HashMap 中的键值对没有固定的顺序,如果需要有序性,可以考虑使用 LinkedHashMap。

总体而言,HashMap 是在很多场景下都非常有用的集合类,特别是在需要键值对存储和快速查找的情况下。

LinkedHashMap

LinkedHashMap 是 Java 集合框架中的一个类,它实现了 Map 接口,是 HashMap 的一个具体实现。与 HashMap 不同的是,LinkedHashMap 在内部使用双向链表维护插入顺序或者访问顺序,使得它可以保留元素的插入顺序或者访问顺序。以下是关于 LinkedHashMap 的介绍和使用方法:

特点:

1、有序性: LinkedHashMap 可以保留元素的插入顺序或者访问顺序。通过构造函数可以选择使用插入顺序或者访问顺序。

2、基于哈希表和链表: LinkedHashMap 内部使用哈希表来存储键值对,并通过双向链表来维护元素的顺序。

3、性能: 与 HashMap 类似,LinkedHashMap 具有快速的查找性能,但相对于 HashMap,在迭代时元素的顺序是有序的。

基本使用:

1、创建 LinkedHashMap 对象:

import java.util.LinkedHashMap;
import java.util.Map;// 创建一个空的 LinkedHashMap,按照插入顺序
LinkedHashMap<String, Integer> linkedHashMap = new LinkedHashMap<>();

2、添加键值对:

linkedHashMap.put("Java", 1);
linkedHashMap.put("Python", 2);
linkedHashMap.put("C++", 3);

3、获取值:

int javaValue = linkedHashMap.get("Java");
System.out.println("Java's value is: " + javaValue);

4、判断键是否存在:

boolean containsJava = linkedHashMap.containsKey("Java");
System.out.println("Contains Java? " + containsJava);

5、删除键值对:

linkedHashMap.remove("Python");

6、获取 LinkedHashMap 的大小:

int size = linkedHashMap.size();
System.out.println("LinkedHashMap Size: " + size);

7、迭代 LinkedHashMap:

for (Map.Entry<String, Integer> entry : linkedHashMap.entrySet()) {System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}

构造函数选择顺序:

1、LinkedHashMap 的构造函数允许你选择使用插入顺序或者访问顺序。默认情况下是按照插入顺序:

LinkedHashMap<K, V> linkedHashMap = new LinkedHashMap<>();

2、如果需要按照访问顺序:

LinkedHashMap<K, V> linkedHashMap = new LinkedHashMap<>(16, 0.75f, true);

上述构造函数的第三个参数设置为 true 表示按照访问顺序。当使用 get 方法访问某个键时,该键会被移到双向链表的末尾,保持最近访问的元素在链表尾部。

总体而言,LinkedHashMap 在需要保留元素插入顺序或者访问顺序的场景中非常有用。如果你需要在迭代时保持元素的有序性,可以选择使用 LinkedHashMap。

TreeMap

TreeMap 是 Java 集合框架中的一个类,它实现了 SortedMap 接口,是基于红黑树(Red-Black Tree)实现的有序映射。以下是关于 TreeMap 的介绍和使用方法:

特点:

1、有序性: TreeMap 中的键值对是按照键的自然顺序或者通过提供的比较器进行排序的。因此,迭代 TreeMap 时会按照升序顺序返回键值对。

2、唯一性: 与 Map 接口相同,TreeMap 中的键是唯一的,一个键只能对应一个值。

3、基于红黑树: TreeMap 内部使用红黑树数据结构,这是一种自平衡的二叉查找树。这使得 TreeMap 具有较好的查找、插入和删除性能。

基本使用:

1、创建 TreeMap 对象:

import java.util.TreeMap;// 创建一个空的 TreeMap
TreeMap<String, Integer> treeMap = new TreeMap<>();

2、添加键值对:

treeMap.put("Java", 1);
treeMap.put("Python", 2);
treeMap.put("C++", 3);

3、获取值:

int javaValue = treeMap.get("Java");
System.out.println("Java's value is: " + javaValue);

4、判断键是否存在:

boolean containsJava = treeMap.containsKey("Java");
System.out.println("Contains Java? " + containsJava);

5、删除键值对:

treeMap.remove("Python");

6、获取 TreeMap 的大小:

int size = treeMap.size();
System.out.println("TreeMap Size: " + size);

7、迭代 TreeMap:

for (String key : treeMap.keySet()) {System.out.println("Key: " + key + ", Value: " + treeMap.get(key));
}

自定义排序:

TreeMap 允许在创建时提供一个比较器(Comparator),以便进行自定义排序。例如,如果要按照字符串长度降序排序:

import java.util.TreeMap;
import java.util.Comparator;public class CustomComparatorExample {public static void main(String[] args) {// 创建一个基于字符串长度的降序排序的 TreeMapTreeMap<String, Integer> customTreeMap = new TreeMap<>(Comparator.comparing(String::length).reversed());// 添加键值对customTreeMap.put("Java", 1);customTreeMap.put("Python", 2);customTreeMap.put("C++", 3);// 迭代 TreeMapfor (String key : customTreeMap.keySet()) {System.out.println("Key: " + key + ", Value: " + customTreeMap.get(key));}}
}

注意事项:

1、如果元素是自定义类的对象,确保该类实现了 Comparable 接口或者在创建 TreeMap 时提供了比较器,以便 TreeMap 知道如何对元素进行排序。

2、TreeMap 的排序是基于键的自然顺序或者提供的比较器,因此键的类型必须是可比较的。

3、TreeMap 不是同步的,如果需要在多线程环境中使用,可以考虑使用 Collections.synchronizedSortedMap 方法包装它,或者使用 ConcurrentSkipListMap。

TreeMap 在需要有序映射的场景中非常有用,尤其是当你需要按照自然顺序或者自定义顺序迭代键值对时。

HashTable

HashTable 是 Java 集合框架中的一个类,它实现了 Map 接口,提供了键值对的存储和检索。HashTable 是早期的 Java 集合实现之一,但在 Java Collections Framework 中已经被更先进的 HashMap 取代。尽管如此,了解 HashTable 仍然有其价值。

特点:

1、同步性: HashTable 是线程安全的,所有的方法都是同步的。这是通过在每个方法上添加 synchronized 关键字来实现的。因此,多个线程可以安全地同时访问 HashTable。

2、不允许空键或空值: HashTable 不允许空键(key)或空值(value),如果尝试插入空键或空值,会抛出 NullPointerException。

3、基于拉链法的哈希表: HashTable 内部使用拉链法来解决哈希冲突,即在哈希表的每个位置上维护一个链表。

基本使用:

1、创建 HashTable 对象:

import java.util.Hashtable;
import java.util.Map;// 创建一个空的 HashTable
Hashtable<String, Integer> hashTable = new Hashtable<>();

2、添加键值对:

hashTable.put("Java", 1);
hashTable.put("Python", 2);
hashTable.put("C++", 3);

3、获取值:

int javaValue = hashTable.get("Java");
System.out.println("Java's value is: " + javaValue);

4、判断键是否存在:

boolean containsJava = hashTable.containsKey("Java");
System.out.println("Contains Java? " + containsJava);

5、删除键值对:

hashTable.remove("Python");

6、获取 HashTable 的大小:

int size = hashTable.size();
System.out.println("HashTable Size: " + size);

7、迭代 HashTable:

for (Map.Entry<String, Integer> entry : hashTable.entrySet()) {System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}

注意事项:

1、HashTable 是线程安全的,但在多线程环境下使用可能会导致性能问题,因为所有的方法都是同步的。在现代的 Java 中,通常推荐使用 HashMap 代替 HashTable,后者的同步性能开销较大。

2、HashTable 不允许空键或空值,如果需要支持空键或空值,可以考虑使用 HashMap。

3、考虑到 HashTable 的性能和一些限制,通常更推荐使用 HashMap 或者 ConcurrentHashMap,它们提供了更好的性能和更丰富的功能。

尽管 HashTable 不再是首选的集合实现,了解它的特点对于理解 Java 集合框架的演变和一些基本的同步概念仍然有帮助。

4、Queue(队列):

PriorityQueue

PriorityQueue 是 Java 集合框架中的一个类,它实现了一个优先级队列(priority queue)。优先级队列是一种特殊的队列,其中的元素按照其优先级进行排序。在 PriorityQueue 中,优先级由元素的比较器或元素自身的自然顺序决定。以下是关于 PriorityQueue 的介绍和使用方法:

特点:

1、优先级排序: PriorityQueue 维护了一个基于堆的完全二叉树,树中的每个节点表示队列中的一个元素。元素按照其优先级排列,根节点具有最高优先级。

2、堆实现: 在默认情况下,PriorityQueue 是一个最小堆(Min Heap)。可以通过提供自定义的比较器来创建最大堆(Max Heap)。

基本使用:

1、创建 PriorityQueue 对象:

import java.util.PriorityQueue;// 创建一个默认的最小堆 PriorityQueue
PriorityQueue<Integer> minHeap = new PriorityQueue<>();

2、添加元素:

minHeap.add(5);
minHeap.add(3);
minHeap.add(8);

3、获取并移除队列头部的元素:

int head = minHeap.poll();
System.out.println("Head of the minHeap: " + head);

4、获取但不移除队列头部的元素:

int peek = minHeap.peek();
System.out.println("Peek of the minHeap: " + peek);

5、自定义比较器:

import java.util.PriorityQueue;
import java.util.Comparator;// 创建一个最大堆 PriorityQueue,提供自定义比较器
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Comparator.reverseOrder());

自定义对象的比较:

如果要在 PriorityQueue 中存储自定义对象,确保对象实现了 Comparable 接口或者在创建 PriorityQueue 时提供了比较器。

import java.util.PriorityQueue;public class CustomObjectExample {public static void main(String[] args) {// 创建一个 Priority Queue 存储自定义对象PriorityQueue<Person> personQueue = new PriorityQueue<>();// 添加 Person 对象personQueue.add(new Person("Alice", 25));personQueue.add(new Person("Bob", 30));personQueue.add(new Person("Charlie", 22));// 获取并移除头部的 Person 对象Person headPerson = personQueue.poll();System.out.println("Head of the personQueue: " + headPerson.getName() + ", Age: " + headPerson.getAge());}
}class Person implements Comparable<Person> {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}@Overridepublic int compareTo(Person other) {// 按照年龄升序排序return Integer.compare(this.age, other.age);}
}

在上述示例中,Person 类实现了 Comparable 接口,并在 compareTo 方法中定义了对象之间的比较规则。这使得 Person 对象可以按照年龄升序排序。

LinkedList

略...

ArrayDeque

ArrayDeque 是 Java 集合框架中的一个双端队列(double-ended queue)。它实现了 Deque 接口,提供了对队列两端进行高效操作的方法。以下是关于 ArrayDeque 的介绍和使用方法:

特点:

1、底层数据结构: ArrayDeque 使用可调整大小的数组作为其底层数据结构,可以根据需要动态调整数组的大小。

2、双端队列: ArrayDeque 是一个双端队列,允许在队列的两端进行添加(push)和移除(pop)操作。它还支持在队列的头部和尾部进行插入和删除操作。

3、不限制容量: 与传统的队列不同,ArrayDeque 不限制容量。它可以根据需要动态调整大小,因此在实际使用中无需关心容量问题。

基本使用:

1、创建 ArrayDeque 对象:

import java.util.ArrayDeque;// 创建一个空的 ArrayDeque
ArrayDeque<String> arrayDeque = new ArrayDeque<>();

2、添加元素:

在队列尾部添加元素:

arrayDeque.add("Element1");
arrayDeque.add("Element2");

在队列头部添加元素:

arrayDeque.addFirst("FirstElement");

在队列尾部添加元素:

arrayDeque.addLast("LastElement");

3、获取并移除元素:

从队列头部获取并移除元素:

String firstElement = arrayDeque.pollFirst();

从队列尾部获取并移除元素:

String lastElement = arrayDeque.pollLast();

4、获取但不移除元素:

获取队列头部的元素(不移除):

String peekFirstElement = arrayDeque.peekFirst();

获取队列尾部的元素(不移除):

String peekLastElement = arrayDeque.peekLast();

应用场景:

1、双端队列操作: 当需要在队列两端执行高效的插入、删除和获取元素操作时,ArrayDeque 是一个很好的选择。

2、无限容量队列: ArrayDeque 不限制容量,因此适用于需要不断添加元素而无需担心容量问题的情况。

3、栈的实现: 由于 ArrayDeque 具有栈的特性,可以用它来实现栈的功能。使用 addFirst 和 pollFirst 方法可以模拟栈的操作。

ArrayDeque<Integer> stack = new ArrayDeque<>();
stack.addFirst(1);    // 入栈
int topElement = stack.pollFirst();  // 出栈

ArrayDeque 提供了一种灵活而高效的双端队列实现,适用于多种场景。它是 Deque 接口的一个实现,因此具备队列和栈的特性。在选择集合类时,根据具体的需求和操作模式选择适当的实现类是很重要的。

5、Deque(双端队列):

ArrayDeque

略...

LinkedList

略...

6、Collection(集合接口):

List

略...

Set

略...

Queue

略...

7、Concurrent集合:

ConcurrentHashMap

ConcurrentHashMap 是 Java 集合框架中的一个线程安全的哈希表实现,它继承自 HashMap 类,实现了 ConcurrentMap 接口。相比于 HashMap,ConcurrentHashMap 提供了更高的并发性,特别适用于多线程环境。以下是关于 ConcurrentHashMap 的介绍和使用方法:

特点和优势:

1、线程安全性: ConcurrentHashMap 是线程安全的,多个线程可以同时读取和写入而不会导致数据不一致。

2、分段锁: ConcurrentHashMap 使用了分段锁机制,将整个数据集分成多个段(Segment),每个段相当于一个小的 HashMap,不同的段可以独立进行读写操作,提高并发性能。

3、高并发读: 由于读操作并不会涉及到锁,所以多个线程可以同时读取。

4、低并发写: 写操作只涉及到段级别的锁,多个线程可以同时写入不同的段,从而提高写入操作的并发性。

基本用法:

1、创建 ConcurrentHashMap 对象:

import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;// 创建一个 ConcurrentHashMap
Map<String, Integer> concurrentHashMap = new ConcurrentHashMap<>();

2、添加元素:

concurrentHashMap.put("Key1", 1);
concurrentHashMap.put("Key2", 2);

3、获取元素:

int value = concurrentHashMap.get("Key1");

4、删除元素:

concurrentHashMap.remove("Key2");

5、遍历元素:

for (Map.Entry<String, Integer> entry : concurrentHashMap.entrySet()) {System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}

6、其他操作:

ConcurrentHashMap 还提供了一些其他方法,如 putIfAbsent、replace 等,用于更复杂的操作。

应用场景:

1、高并发读写: 当需要在多线程环境下进行高并发的读写操作时,ConcurrentHashMap 是一个很好的选择。

2、分布式场景: 由于 ConcurrentHashMap 的分段锁机制,它在分布式场景中也能够提供较好的性能。

在并发环境中,ConcurrentHashMap 是一个非常有用的工具,可以有效地提高多线程环境下的性能和并发控制。

ConcurrentLinkedQueue

ConcurrentLinkedQueue 是 Java 集合框架中的一个线程安全的队列实现,它实现了 Queue 接口。它的设计目标是在多线程环境中提供高效的并发操作。以下是关于 ConcurrentLinkedQueue 的介绍和使用方法:

特点和优势:

1、线程安全性: ConcurrentLinkedQueue 是线程安全的,支持并发读写操作,无需额外的同步。

2、基于非阻塞算法: ConcurrentLinkedQueue 的实现基于非阻塞算法,采用一种称为 "Michael and Scott" 的无锁算法,不使用锁来保护共享数据,而是使用 CAS(Compare And Swap)操作。

3、高并发性: 在多线程环境中,ConcurrentLinkedQueue 提供了高效的并发性能,特别适用于高并发读写的场景。

基本用法:

1、创建 ConcurrentLinkedQueue 对象:

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;// 创建一个 ConcurrentLinkedQueue
Queue<String> concurrentLinkedQueue = new ConcurrentLinkedQueue<>();

2、添加元素:

concurrentLinkedQueue.offer("Element1");
concurrentLinkedQueue.offer("Element2");

3、获取并移除元素:

String element = concurrentLinkedQueue.poll();

4、获取但不移除元素:

String peekedElement = concurrentLinkedQueue.peek();

5、遍历元素:

for (String element : concurrentLinkedQueue) {System.out.println(element);
}

6、获取队列大小:

int size = concurrentLinkedQueue.size();

7、其他操作:

ConcurrentLinkedQueue 还提供了一些其他方法,如 remove、contains 等,用于更复杂的操作。

应用场景:

1、生产者-消费者模式: ConcurrentLinkedQueue 可以用于实现生产者-消费者模式,其中多个线程可以安全地在队列中添加和获取元素。

2、无界队列: ConcurrentLinkedQueue 是一个无界队列,适用于需要不断添加元素而无需担心容量问题的场景。

3、高并发读写: 当需要在多线程环境中进行高并发读写操作时,ConcurrentLinkedQueue 是一个很好的选择。

在多线程环境中,ConcurrentLinkedQueue 提供了一种高效的队列实现,特别适用于需要高并发性能的场景。

ConcurrentSkipListMap

ConcurrentSkipListMap 是 Java 集合框架中的一个线程安全的、有序的 Map 实现,它实现了 ConcurrentNavigableMap 接口。ConcurrentSkipListMap 基于跳跃表(Skip List)数据结构,提供了高效的并发访问能力。以下是关于 ConcurrentSkipListMap 的介绍和使用方法:

特点和优势:

1、线程安全性: ConcurrentSkipListMap 是线程安全的,支持并发读写操作。

2、有序性: ConcurrentSkipListMap 的键是有序的,它们按照自然顺序或者通过比较器进行排序。

3、高并发性: 在多线程环境中,ConcurrentSkipListMap 提供了高效的并发性能,适用于高并发读写的场景。

4、支持导航操作: ConcurrentSkipListMap 实现了 ConcurrentNavigableMap 接口,提供了一系列导航方法,如 ceilingKey、floorKey 等。

基本用法:

1、创建 ConcurrentSkipListMap 对象:

import java.util.concurrent.ConcurrentSkipListMap;
import java.util.Map;// 创建一个 ConcurrentSkipListMap
Map<String, Integer> concurrentSkipListMap = new ConcurrentSkipListMap<>();

2、添加元素:

concurrentSkipListMap.put("Key1", 1);
concurrentSkipListMap.put("Key2", 2);

3、获取元素:

int value = concurrentSkipListMap.get("Key1");

4、删除元素:

concurrentSkipListMap.remove("Key2");

5、遍历元素:

for (Map.Entry<String, Integer> entry : concurrentSkipListMap.entrySet()) {System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}

6、导航操作:

// 获取大于等于给定键的最小键
String ceilingKey = concurrentSkipListMap.ceilingKey("Key1");// 获取小于等于给定键的最大键
String floorKey = concurrentSkipListMap.floorKey("Key2");

7、其他操作:

ConcurrentSkipListMap 还提供了一些其他方法,如 higherKey、lowerKey 等,用于更复杂的导航操作。

应用场景:

1、有序映射: 当需要在多线程环境中维护一个有序的键值对集合时,ConcurrentSkipListMap 是一个很好的选择。

2、高并发读写: 当需要在多线程环境中进行高并发读写操作时,ConcurrentSkipListMap 是一个适用的实现。

3、导航操作: 当需要进行一些导航操作,如查找大于等于给定键的最小键等,ConcurrentSkipListMap 提供了相应的方法。

在需要有序、并发安全的键值对集合时,ConcurrentSkipListMap 提供了一种高效的实现。

CopyOnWriteArrayList

CopyOnWriteArrayList 是 Java 集合框架中的一个线程安全的 List 实现,它通过在修改操作时创建底层数组的副本来实现线程安全。这个副本用于写操作,而读操作仍然在原数组上进行。由于读写分离,CopyOnWriteArrayList 在读多写少的场景中具有较好的性能。以下是关于 CopyOnWriteArrayList 的介绍和使用方法:

特点和优势:

1、线程安全性: CopyOnWriteArrayList 是线程安全的,支持并发读写操作。

2、写时复制: 在写操作时,CopyOnWriteArrayList 会创建底层数组的副本,因此写操作不会影响正在进行的读操作。

3、适用于读多写少: 由于读写分离的特性,CopyOnWriteArrayList 在读多写少的场景中性能较好。

基本用法:

1、创建 CopyOnWriteArrayList 对象:

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;// 创建一个 CopyOnWriteArrayList
List<String> copyOnWriteArrayList = new CopyOnWriteArrayList<>();

2、添加元素:

copyOnWriteArrayList.add("Element1");
copyOnWriteArrayList.add("Element2");

3、获取元素:

String element = copyOnWriteArrayList.get(0);

4、删除元素:

copyOnWriteArrayList.remove("Element1");

5、遍历元素:

for (String element : copyOnWriteArrayList) {System.out.println(element);
}

6、其他操作:

CopyOnWriteArrayList 还提供了一些其他方法,如 addAll、clear 等,用于更复杂的操作。

应用场景:

1、读多写少: CopyOnWriteArrayList 适用于读多写少的场景,其中写操作的频率较低。

2、读写分离: 当需要在多线程环境中同时进行读写操作时,CopyOnWriteArrayList 提供了一种简单而有效的线程安全解决方案。

3、不要求实时更新: 由于写操作并不会立即影响到正在进行的读操作,适用于不要求实时更新的场景。

在使用 CopyOnWriteArrayList 时,需要注意它的一些特性,如写时复制带来的内存开销,以及读取时可能看到过时的数据。因此,选择是否使用 CopyOnWriteArrayList 取决于具体的应用场景和需求。

CopyOnWriteArraySet

CopyOnWriteArraySet 是 Java 集合框架中的一个线程安全的 Set 实现,它是通过使用 CopyOnWriteArrayList 来实现的。它保证了在迭代过程中不会抛出 ConcurrentModificationException 异常,因为写操作会在新的副本上进行,而读操作则在原有的集合上进行。以下是关于 CopyOnWriteArraySet 的介绍和使用方法:

特点和优势:

1、线程安全性: CopyOnWriteArraySet 是线程安全的,支持并发读写操作。

2、写时复制: 在写操作时,CopyOnWriteArraySet 会创建底层数组的副本,因此写操作不会影响正在进行的读操作。

3、不抛异常: 在迭代过程中,即使集合发生了修改,也不会抛出 ConcurrentModificationException 异常。

基本用法:

1、创建 CopyOnWriteArraySet 对象:

for (String element : copyOnWriteArraySet) {System.out.println(element);
}
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;// 创建一个 CopyOnWriteArraySet
Set<String> copyOnWriteArraySet = new CopyOnWriteArraySet<>();

2、添加元素:

copyOnWriteArraySet.add("Element1");
copyOnWriteArraySet.add("Element2");

3、删除元素:

copyOnWriteArraySet.remove("Element1");

4、遍历元素:

for (String element : copyOnWriteArraySet) {System.out.println(element);
}

5、获取集合大小:

int size = copyOnWriteArraySet.size();

6、其他操作:

CopyOnWriteArraySet 还提供了一些其他方法,如 addAll、clear 等,用于更复杂的操作。

应用场景:

1、读多写少: CopyOnWriteArraySet 适用于读多写少的场景,其中写操作的频率较低。

2、读写分离: 当需要在多线程环境中同时进行读写操作时,CopyOnWriteArraySet 提供了一种简单而有效的线程安全解决方案。

3、不抛异常的迭代: 如果需要在迭代过程中不抛出 ConcurrentModificationException 异常,可以考虑使用 CopyOnWriteArraySet。

在实际使用时,需要根据业务需求和性能要求来选择合适的集合类型。

8、其他:

BitSet

BitSet 是 Java 集合框架中的一种用于位操作的集合类。它以位为单位表示集合中的元素,可以有效地存储和操作大量的位信息。主要用于处理一系列的开关状态或者标记。以下是关于 BitSet 的介绍和使用方法:

创建 BitSet 对象:

import java.util.BitSet;// 创建一个 BitSet,默认大小为64位
BitSet bitSet = new BitSet();

基本操作:

1、设置位:

bitSet.set(2); // 将索引2处的位设置为true

2、清除位:

bitSet.clear(5); // 将索引5处的位设置为false

3、获取位状态:

boolean isSet = bitSet.get(3); // 获取索引3处的位状态

4、翻转位:

bitSet.flip(4); // 翻转索引4处的位,即从true变为false,或从false变为true

5、获取位数(位的总数):

int numberOfBits = bitSet.size(); // 获取位的总数

6、获取设置为true的位数:

int numberOfSetBits = bitSet.cardinality(); // 获取设置为true的位数

7、按位与、按位或、按位异或等位运算:

BitSet anotherBitSet = new BitSet();
anotherBitSet.set(2);// 按位与
bitSet.and(anotherBitSet);// 按位或
bitSet.or(anotherBitSet);// 按位异或
bitSet.xor(anotherBitSet);

8、其他操作:

BitSet 还提供了许多其他的位操作方法,如 andNot、nextSetBit、nextClearBit 等。

应用场景:

1、位图索引: BitSet 可以用于实现位图索引,用于快速查找某个元素是否存在。

2、标记状态: 用于标记某个状态的开关,例如网络端口的占用状态、任务完成状态等。

3、压缩存储: 在一些特定场景下,BitSet 可以用于压缩存储大量的布尔型信息。

示例:

import java.util.BitSet;public class BitSetExample {public static void main(String[] args) {BitSet bitSet = new BitSet();// 设置位bitSet.set(1);bitSet.set(3);// 获取位状态System.out.println(bitSet.get(1)); // 输出 trueSystem.out.println(bitSet.get(2)); // 输出 false// 翻转位bitSet.flip(2);System.out.println(bitSet.get(2)); // 输出 true// 获取位数System.out.println(bitSet.size()); // 输出 64// 获取设置为true的位数System.out.println(bitSet.cardinality()); // 输出 3}
}

BitSet 是一个用于位操作的强大工具,特别适用于需要高效存储和操作大量位信息的场景。在使用时,根据具体的需求选择合适的位操作方法。

Properties

Properties 类是 Java 集合框架中的一个特殊的类,用于处理属性文件。它继承自 Hashtable 类,因此具备了 Hashtable 的一些特性,但主要用于管理键值对形式的配置信息。以下是关于 Properties 的介绍和使用方法:

创建 Properties 对象:

import java.util.Properties;// 创建一个 Properties 对象
Properties properties = new Properties();

添加和获取属性:

1、添加属性:

// 添加属性
properties.setProperty("key1", "value1");
properties.setProperty("key2", "value2");

2、获取属性:

// 获取属性值
String value = properties.getProperty("key1");
System.out.println(value); // 输出 "value1"

3、读取和写入属性文件:

从文件读取属性:

import java.io.FileInputStream;
import java.io.IOException;// 从文件读取属性
try (FileInputStream input = new FileInputStream("config.properties")) {properties.load(input);
} catch (IOException e) {e.printStackTrace();
}

将属性写入文件:

import java.io.FileOutputStream;
import java.io.IOException;// 将属性写入文件
try (FileOutputStream output = new FileOutputStream("config.properties")) {properties.store(output, "This is a comment");
} catch (IOException e) {e.printStackTrace();
}

4、默认值:

// 获取属性值,如果属性不存在,返回默认值
String value = properties.getProperty("key3", "default");
System.out.println(value); // 输出 "default"

5、遍历属性:

// 遍历所有属性
for (String key : properties.stringPropertyNames()) {String value = properties.getProperty(key);System.out.println(key + ": " + value);
}

6、应用场景:

1、配置文件管理: 主要用于读取和写入配置文件,存储应用程序的配置信息。

2、国际化: 在国际化中,可以使用 Properties 存储不同语言的文本。

3、属性映射: 用于管理键值对形式的属性,类似于字典。

Properties 类是处理配置文件和属性映射的便捷工具,在许多 Java 应用程序中广泛用于管理配置信息。

这些集合类提供了各种不同的数据结构和性能特性,以满足不同的需求。根据你的具体需求和使用情境,你可以选择适当的集合类来存储和管理数据。

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

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

相关文章

【现场问题】datax中write部分为Oracle的时候插入clolb类型字段,插入的数据为string且长度过场问题

datax的Oraclewriter 报错显示查询报错展示查找datax中的数据插入模块 报错显示 occurred during batching: ORA-01704: string literal too long 查询报错展示 基本上查到的都是这样的&#xff0c;所以锁定是clob的字段类型的问题&#xff0c;而且是只有Oracle出问题&#…

觉非科技发布【轻地图高速NOA智驾方案】|地平线,觉非科技,MobileDrive超捷生态协作实现技术落地

11月10日&#xff0c;2023世界新汽车技术合作生态展期间&#xff0c;觉非科技正式发布了基于地平线征程系列以及MobileDrive超捷规控系统的【轻地图高速NOA智驾解决方案】。该方案首次实现了从芯片能力输出、到数据闭环建设、再到规控部署的产业生态链协作与打通&#xff0c;为…

docker部署容器化mysql5.7

部署MySQL 本教程将指导您如何在Docker环境中部署MySQL数据库&#xff0c;并展示如何通过外部MySQL客户端与之交互。 步骤 1: 准备环境 首先&#xff0c;我们需要在本地环境中创建必要的文件夹结构来存储MySQL的配置、日志和数据。 # 在终端创建mysql文件夹及其子文件夹 mk…

微信小程序漏洞之accesskey泄露

更新时间&#xff1a;2023年09月08日09:42:52 1. Accesskey泄露漏洞 这篇文章里面都是以我个人的视角来进行的&#xff0c;因为一些原因&#xff0c;中间删了一些东西&#xff0c;肯定有很多不正确的地方&#xff0c;希望大家能理解&#xff0c;也能指正其中的错误。 在以前…

VCR库代码示例

1. 首先&#xff0c;我们需要在代码中添加对VCR库的引用&#xff1a; ruby require vcr require rest-client 2. 然后&#xff0c;我们需要创建一个VCR录制器&#xff0c;以便我们可以记录实际的HTTP请求和响应&#xff1a; ruby VCR.use_cassette(download_video, record:…

虚拟机CentOS 8 重启后不能上网

情况说明&#xff1a;原本虚拟机是可以上网的&#xff0c;然后嘚一下&#xff0c;重启后&#xff0c;连接不上网络&#xff0c;完了&#xff0c;上网查找一堆质料&#xff0c;我的连接方式是桥接模式&#xff08;复制物理网络连接状态&#xff09;。 好&#xff0c;有人说是vmn…

@Validated和@Valid 区别

Spring Validation验证框架对参数的验证机制提供了Validated&#xff08;Spring’s JSR-303规范&#xff0c;是标准JSR-303的一个变种&#xff09;&#xff0c;javax提供了Valid&#xff08;标准JSR-303规范&#xff09;&#xff0c; 配合BindingResult可以直接提供参数验证结…

通配符SSL证书

通配符SSL证书是一种特殊的数字证书&#xff0c;用于在互联网上建立安全的连接&#xff0c;其特点是可以保护多个子域名&#xff0c;并且具有很高的兼容性和扩展性。本文将详细介绍通配符SSL证书的相关概念、优点和应用等。 首先&#xff0c;我们需要了解什么是SSL证书。 SSL证…

未整理的知识链接

【scala】下划线用法总结 【scala】下划线用法总结_scala 下划线-CSDN博客 Spark Sql Row 的解析 Spark Sql Row 的解析 - 简书 spark dataframe foreach spark dataframe foreach_mob64ca12f0cf8f的技术博客_51CTO博客 spark- Dataframe基本操作-查询 https://blog.csdn.n…

Spring 循环依赖

文章目录 内容总结循环依赖循环依赖的解决方案设计模拟循环依赖解决循环依赖的关键 缓存仍然存在问题 代理 解决代理问题的关键 提前AOP仍然存在问题 AOP全部提前与Bean创建流程设计严重不符 解决违背设计问题的关键 尽量提前而非全部提前仍然存在问题 多重循环 内容总结 循环…

33、Flink 的Table API 和 SQL 中的时区

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

MATLAB Simulink和SMART PLC水箱液位高度PID控制(联合仿真)

SMART PLC 向导PID的详细介绍请查看下面文章链接: S7-200 SMART PLC PID向导详细介绍(如何实现P、PD、PID控制器)-CSDN博客文章浏览阅读1k次。这篇博客主要介绍SMART PLC PID向导的使用,PID控制相关的其它内容请查看专栏系列文章,常用链接如下:SMART PLC PID负压控制(过程…

海外ASO优化之谷歌商店的评论优化

应用商店中的评分和评论&#xff0c;显示我们的应用程序的受欢迎程度以及用户对该应用程序的看法。评分和评论是以前或者是现在的用户分享的经验和公开的反馈。 1、提高应用评分评论。 高评分的应用可以从应用商店内的搜索流量中获得更多的点击量&#xff0c;通过推荐和推荐获…

SMART PLC 和S7-1200PLC MODBUSTCP通信速度测试

SMART PLC MODBUSTCP通信详细介绍请参看下面文章链接: S7-200SMART PLC ModbusTCP通信(多服务器多从站轮询)_matlab sumilink 多个modbustcp读写_RXXW_Dor的博客-CSDN博客文章浏览阅读6.4k次,点赞5次,收藏10次。MBUS_CLIENT作为MODBUS TCP客户端通过S7-200 SMART CPU上的…

Python开源项目VQFR——人脸重建(Face Restoration),模糊清晰、划痕修复及黑白上色的实践

Python Anaconda 的安装等请参阅&#xff1a; Python开源项目CodeFormer——人脸重建&#xff08;Face Restoration&#xff09;&#xff0c;模糊清晰、划痕修复及黑白上色的实践https://blog.csdn.net/beijinghorn/article/details/134334021 VQFR也是 腾讯 LAB 的作品&…

【uniapp】确认弹出框,选择确定和取消

代码如下&#xff1a; <view style"display: flex; justify-content: space-around;"><button class"button" click"submit">t提交</button> </view>submit(){let thatthisuni.showModal({title: 提示&#xff1a;,con…

NSS [HUBUCTF 2022 新生赛]checkin

NSS [HUBUCTF 2022 新生赛]checkin 判断条件是if ($data_unserialize[username]$username&&$data_unserialize[password]$password)&#xff0c;满足则给我们flag。正常思路来说&#xff0c;我们要使序列化传入的username和password等于代码中的两个同名变量&#xff0…

【工程部署】在RK3588上部署OCR(文字检测识别)(DBNet+CRNN)

硬件平台&#xff1a; 1、firefly安装Ubuntu系统的RK3588&#xff1b; 2、安装Windows系统的电脑一台&#xff0c;其上安装Ubuntu18.04系统虚拟机。 参考手册&#xff1a;《00-Rockchip_RKNPU_User_Guide_RKNN_API_V1.3.0_CN》 《RKNN Toolkit Lite2 用户使用指南》 1、文…

mapreduce-maven--30.串联所有单词的字串

项目对象模型&#xff08;Project Object Model&#xff0c;POM&#xff09;&#xff1a;Maven使用POM文件来描述项目的结构、依赖和构建设置。POM是一个XML文件&#xff0c;位于项目根目录下&#xff0c;并包含项目的基本信息、构建设置、依赖管理等。 依赖管理&#xff1a;M…

Unity DOTS系列之System中如何使用SystemAPI.Query迭代数据

最近DOTS发布了正式的版本, 我们来分享一下System中如何基于SystemAPI.Query来迭代World中的数据&#xff0c;方便大家上手学习掌握Unity DOTS开发。 SystemAPI.Query的使用 System有两种&#xff0c;一种是Unmanaged 的ISystem,一种是managed 的SystemBase,这两种System都可…