編程語言Java——核心技術篇(四)集合類詳解

言不信者行不果,行不敏者言多滯.

目錄

4. 集合類

4.1 集合類概述

4.1.1 集合框架遵循原則

4.1.2 集合框架體系

?4.2 核心接口和實現類解析

4.2.1 Collection 接口體系

4.2.1.1 Collection 接口核心定義

4.2.1.2?List接口詳解

4.2.1.3 Set 接口詳解

4.2.1.4?Queue/Deque接口詳解

4.2.2 Map 接口體系詳解

?4.3 集合類選擇

4.3.1 集合類選擇指南

4.3.2?集合類選擇決策樹

4.4?性能優化建議

4.5 總結


續前篇:編程語言Java——核心技術篇(三)異常處理詳解-CSDN博客

4. 集合類

Java集合框架(Java Collections Framework, JCF)是Java語言中用于存儲和操作數據集合的一組接口和類。它提供了一套標準化的數據結構實現,使開發者能夠高效地處理數據。

4.1 集合類概述

4.1.1 集合框架遵循原則

集合框架的設計遵循了幾個重要原則:

  • 接口與實現分離:所有具體集合類都實現自標準接口(如List、Set、Map),這使得程序可以靈活切換不同的實現而不影響業務邏輯。

  • 算法復用:Collections工具類提供了大量通用算法(如排序、查找、反轉等),這些算法可以應用于任何實現了相應接口的集合類。

  • 性能優化:針對不同使用場景提供了多種實現,如需要快速隨機訪問選擇ArrayList,需要頻繁插入刪除選擇LinkedList。

  • 擴展性:通過迭代器模式(Iterator)和比較器(Comparator)等設計,使集合框架易于擴展和定制。

  • 類型安全:通過泛型機制在編譯期檢查類型一致性,避免了運行時的類型轉換錯誤。

4.1.2 集合框架體系

這張圖很清楚了,兩個頂級父類接口Iterable和Map,剩下的List,Set和Queue等都是兩個接口的實現子接口,在下來才是各種實現類。如果只但看各個接口之間的繼承關系還有下面這張圖:

我感覺這兩個圖可以詳細地記一下,因為適用性挺廣的,存放數據和操作都會頻繁地遇到集合類。?

?4.2 核心接口和實現類解析

4.2.1 Collection 接口體系

4.2.1.1 Collection 接口核心定義

Collection是單列集合的根接口,定義了集合的通用行為:

public interface Collection<E> extends Iterable<E> {// 基本操作int size();boolean isEmpty();boolean contains(Object o);Iterator<E> iterator();Object[] toArray();<T> T[] toArray(T[] a);// 修改操作boolean add(E e);boolean remove(Object o);// 批量操作boolean containsAll(Collection<?> c);boolean addAll(Collection<? extends E> c);boolean removeAll(Collection<?> c);boolean retainAll(Collection<?> c);void clear();// Java 8新增boolean removeIf(Predicate<? super E> filter);Spliterator<E> spliterator();Stream<E> stream();Stream<E> parallelStream();
}
4.2.1.2?List接口詳解

1. 核心特性:

  • 有序集合:元素按插入順序存儲,可通過索引精確訪問

  • 元素可重復:允許存儲相同元素(包括null)

  • 位置訪問:提供基于索引的增刪改查方法

特有方法:

// 位置訪問
E get(int index);
E set(int index, E element);
void add(int index, E element);
E remove(int index);// 搜索
int indexOf(Object o);
int lastIndexOf(Object o);// 范圍操作
List<E> subList(int fromIndex, int toIndex);// Java 8新增
default void replaceAll(UnaryOperator<E> operator);
default void sort(Comparator<? super E> c);

2. 實現類對比

對比維度ArrayListLinkedListVector
底層數據結構動態數組雙向鏈表動態數組
內存布局連續內存空間離散節點存儲連續內存空間
初始容量10 (首次添加時初始化)無固定容量概念10
擴容機制1.5倍增長 (int newCapacity = oldCapacity + (oldCapacity >> 1))無需擴容,動態增加節點2倍增長 (capacityIncrement>0時按指定值增長)
隨機訪問性能O(1) - 直接數組索引訪問O(n) - 需要遍歷鏈表O(1)
頭部插入性能O(n) - 需要移動所有元素O(1) - 修改頭節點引用O(n)
尾部插入性能O(1)攤銷 (考慮擴容)O(1) - 修改尾節點引用O(1)
中間插入性能O(n) - 平均需要移動一半元素O(n) - 需要先找到位置O(n)
刪除操作性能O(n) - 類似插入O(1) - 找到節點后只需修改引用O(n)
內存占用較少 (僅需存儲元素和數組引用)較高 (每個元素需要額外前后節點引用)與ArrayList類似
緩存友好性好 (空間局部性原理)
線程安全性非線程安全非線程安全線程安全 (方法級synchronized)
迭代器安全性快速失敗 (fail-fast)快速失敗線程安全但迭代時仍需外部同步
序列化支持自定義序列化 (transient數組+size)自定義序列化同ArrayList
最佳適用場景讀多寫少,隨機訪問頻繁寫多讀少,頻繁在頭尾操作需要線程安全的場景 (已過時)

?3. ArrayList 示例

// 創建ArrayList
List<String> arrayList = new ArrayList<>();// 添加元素
arrayList.add("Java");
arrayList.add("Python");
arrayList.add(1, "C++"); // 在指定位置插入// 訪問元素
String lang = arrayList.get(0); // "Java"// 遍歷方式1:for循環
for (int i = 0; i < arrayList.size(); i++) {System.out.println(arrayList.get(i));
}// 遍歷方式2:增強for循環
for (String language : arrayList) {System.out.println(language);
}// 遍歷方式3:迭代器
Iterator<String> it = arrayList.iterator();
while (it.hasNext()) {System.out.println(it.next());
}// 刪除元素
arrayList.remove("Python"); // 按對象刪除
arrayList.remove(0);       // 按索引刪除// 轉換為數組
String[] array = arrayList.toArray(new String[0]);// Java 8操作
arrayList.removeIf(s -> s.length() < 3); // 刪除長度小于3的元素
arrayList.replaceAll(String::toUpperCase); // 全部轉為大寫

ArrayList常用的方法都在這里了。我們可以把ArrayList就看成一個動態數組,實際上ArrayList比較適合查詢數組內地各個元素,但在增刪改上地性能較差。

4. LinkedList 示例

// 創建LinkedList
LinkedList<String> linkedList = new LinkedList<>();// 添加元素
linkedList.add("Apple");
linkedList.addFirst("Banana"); // 添加到頭部
linkedList.addLast("Orange"); // 添加到尾部
linkedList.add(1, "Grape");   // 在指定位置插入// 隊列操作
linkedList.offer("Pear");     // 添加到隊尾
String head = linkedList.poll(); // 移除并返回隊頭// 棧操作
linkedList.push("Cherry");    // 壓棧
String top = linkedList.pop(); // 彈棧// 獲取元素
String first = linkedList.getFirst();
String last = linkedList.getLast();// 遍歷方式:降序迭代器
Iterator<String> descIt = linkedList.descendingIterator();
while (descIt.hasNext()) {System.out.println(descIt.next());
}

這里刻意強調一下棧操作。LinkedList 實現了 Deque(雙端隊列)接口,因此可以作為棧(Stack)使用。棧是一種后進先出(LIFO)的數據結構,實際上就是數據接口的知識。

// 將元素推入棧頂(實際添加到鏈表頭部)入棧
LinkedList<String> stack = new LinkedList<>();
stack.push("A");  // 棧底 ← "A" → 棧頂
stack.push("B");  // 棧底 ← "A" ← "B" → 棧頂
stack.push("C");  // 棧底 ← "A" ← "B" ← "C" → 棧頂String top = stack.pop();  // 移除并返回棧頂元素 "C" 出棧
// 現在棧狀態:棧底 ← "A" ← "B" → 棧頂String peek = stack.peek(); // 返回 "B"(棧頂元素)
// 棧保持不變:棧底 ← "A" ← "B" → 棧頂
4.2.1.3 Set 接口詳解

1. 核心特性:

  • 元素唯一性:不包含重復元素(依據equals()判斷)

  • 無序性:不保證維護插入順序(TreeSet/LinkedHashSet除外)

  • 數學集合:支持并集、交集、差集等操作

2. 實現類對比

對比維度HashSetLinkedHashSetTreeSet
底層實現基于HashMap繼承HashSet,使用LinkedHashMap基于TreeMap
數據結構哈希表+鏈表/紅黑樹哈希表+鏈表+雙向鏈表紅黑樹
元素順序無序插入順序自然順序/Comparator定義順序
null值支持允許一個null元素允許一個null元素不允許null元素
基本操作復雜度平均O(1)平均O(1)O(log n)
內存開銷較低較高 (額外維護雙向鏈表)較高 (樹結構開銷)
構造方法可指定初始容量和負載因子同HashSet可提供Comparator
迭代順序不穩定插入順序穩定排序順序穩定
性能特點插入刪除極快插入刪除稍慢于HashSet插入刪除較慢但有序
額外方法提供first(), last(), subSet()等導航方法
線程安全性非線程安全非線程安全非線程安全
哈希沖突解決鏈地址法,JDK8后鏈表轉紅黑樹同HashSet不適用
擴容機制默認16→32→64... 負載因子0.75同HashSet無需擴容
比較方式equals()和hashCode()同HashSetComparable或Comparator
典型應用場景需要快速判斷元素是否存在需要保持插入順序的集合需要有序集合或范圍查詢

3.? HashSet 示例

// 創建HashSet
Set<String> hashSet = new HashSet<>();// 添加元素
hashSet.add("Java");
hashSet.add("Python");
hashSet.add("Java"); // 重復元素不會被添加// 判斷包含
boolean hasJava = hashSet.contains("Java"); // true// 刪除元素
hashSet.remove("Python");// 遍歷
for (String language : hashSet) {System.out.println(language);
}// 集合運算
Set<String> otherSet = new HashSet<>(Arrays.asList("C++", "Java", "JavaScript"));hashSet.retainAll(otherSet); // 交集
hashSet.addAll(otherSet);    // 并集
hashSet.removeAll(otherSet); // 差集

4.?LinkedHashSet示例

// 創建LinkedHashSet(保持插入順序)
Set<String> linkedHashSet = new LinkedHashSet<>();linkedHashSet.add("First");
linkedHashSet.add("Second");
linkedHashSet.add("Third");// 遍歷順序與插入順序一致
for (String item : linkedHashSet) {System.out.println(item); // 輸出順序:First, Second, Third
}// 移除并添加,順序會變
linkedHashSet.remove("Second");
linkedHashSet.add("Second");// 現在順序:First, Third, Second

LinkedHashSet能夠保持插入順序,即刪除時后面元素會自動補位,增添元素時會自動退位;但HashSet不會,不管組內元素如何變化,其他元素均不變。

5.?TreeSet示例

// 創建TreeSet(自然排序)
Set<String> treeSet = new TreeSet<>();treeSet.add("Orange");
treeSet.add("Apple");
treeSet.add("Banana");// 自動排序輸出
for (String fruit : treeSet) {System.out.println(fruit); // Apple, Banana, Orange
}// 定制排序
Set<Integer> customSort = new TreeSet<>((a, b) -> b - a); // 降序
customSort.addAll(Arrays.asList(5, 3, 9, 1));// 輸出:9, 5, 3, 1// 導航方法
TreeSet<Integer> nums = new TreeSet<>(Arrays.asList(1, 3, 5, 7, 9));Integer lower = nums.lower(5);  // 3 (小于5的最大元素)
Integer higher = nums.higher(5); // 7 (大于5的最小元素)
Integer floor = nums.floor(4);   // 3 (小于等于4的最大元素)
Integer ceiling = nums.ceiling(6); // 7 (大于等于6的最小元素)// 范圍視圖
Set<Integer> subSet = nums.subSet(3, true, 7, false); // [3, 5]
4.2.1.4?Queue/Deque接口詳解

1. Queue核心方法:

操作類型拋出異常的方法返回特殊值的方法
插入add(e)offer(e)
移除remove()poll()
檢查element()peek()

?2. 實現類對比

對比維度PriorityQueueArrayDequeLinkedList
底層結構二叉堆(數組實現)循環數組雙向鏈表
排序特性自然順序/Comparator
容量限制無界(自動擴容)可選有界(默認16)無界
null值允許不允許不允許允許
基本操作復雜度插入O(log n),獲取O(1)兩端操作O(1)兩端操作O(1),中間操作O(n)
線程安全性非線程安全非線程安全非線程安全
內存使用緊湊(數組)非常緊湊較高(節點開銷)
擴容策略小規模+50%,大規模+25%雙倍增長動態增加節點
迭代順序按優先級順序FIFO/LIFO順序插入順序
特殊方法comparator()大量列表操作方法
最佳適用場景任務調度,需要自動排序高性能棧/隊列實現需要同時作為隊列和列表使用
實現接口QueueDequeList, Deque

?3.?PriorityQueue示例

// 創建優先級隊列(自然排序)
PriorityQueue<Integer> pq = new PriorityQueue<>();pq.add(30);
pq.add(10);
pq.add(20);// 取出時會按順序
while (!pq.isEmpty()) {System.out.println(pq.poll()); // 10, 20, 30
}// 定制排序
PriorityQueue<String> customPq = new PriorityQueue<>((s1, s2) -> s2.length() - s1.length()); // 按長度降序customPq.add("Apple");
customPq.add("Banana");
customPq.add("Pear");// 輸出:Banana, Apple, Pear

2. ArrayDeque示例

// 創建ArrayDeque
Deque<String> deque = new ArrayDeque<>();// 作為棧使用
deque.push("First");
deque.push("Second");
String top = deque.pop(); // "Second"// 作為隊列使用
deque.offer("Third");
deque.offer("Fourth");
String head = deque.poll(); // "First"// 雙端操作
deque.addFirst("Front");
deque.addLast("End");
String first = deque.getFirst(); // "Front"
String last = deque.getLast();?? // "End"

4.2.2 Map 接口體系詳解

1. 核心定義

public interface Map<K,V> {// 基本操作int size();boolean isEmpty();boolean containsKey(Object key);boolean containsValue(Object value);V get(Object key);V put(K key, V value);V remove(Object key);// 批量操作void putAll(Map<? extends K, ? extends V> m);void clear();// 集合視圖Set<K> keySet();Collection<V> values();Set<Map.Entry<K, V>> entrySet();// 內部Entry接口interface Entry<K,V> {K getKey();V getValue();V setValue(V value);// Java 8新增boolean equals(Object o);int hashCode();public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey()// ...}// Java 8新增方法default V getOrDefault(Object key, V defaultValue)default void forEach(BiConsumer<? super K, ? super V> action)default V putIfAbsent(K key, V value)default boolean remove(Object key, Object value)default boolean replace(K key, V oldValue, V newValue)default V replace(K key, V value)default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function)default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)// ...
}

這里是Java的源碼,可以看到Map實際上放的是一對K-V鍵值對。

2. 實現類對比

對比維度HashMapLinkedHashMapTreeMap
繼承體系AbstractMap繼承HashMapAbstractMap
底層結構數組+鏈表/紅黑樹數組+鏈表/紅黑樹+雙向鏈表紅黑樹
鍵值順序無序插入順序/訪問順序鍵的自然順序/Comparator順序
null鍵值支持允許null鍵和null值同HashMap不允許null鍵
初始容量16同HashMap無容量概念
擴容機制2^n增長,負載因子0.75同HashMap無需擴容
基本操作復雜度平均O(1)平均O(1)O(log n)
線程安全性非線程安全非線程安全非線程安全
迭代器類型fail-fastfail-fastfail-fast
額外功能可設置訪問順序(LRU實現)導航方法(如ceilingKey)
哈希算法(h = key.hashCode()) ^ (h >>> 16)同HashMap不適用
樹化閾值鏈表長度≥8且桶數量≥64同HashMap不適用
序列化方式自定義同HashMap同HashMap
推薦場景大多數鍵值對存儲場景需要保持插入/訪問順序需要有序映射或范圍查詢

3. HashMap示例

// 創建HashMap
Map<String, Integer> hashMap = new HashMap<>();// 添加鍵值對
hashMap.put("Apple", 10);
hashMap.put("Banana", 20);
hashMap.put("Orange", 15);// 獲取值
int apples = hashMap.get("Apple"); // 10
int defaultValue = hashMap.getOrDefault("Pear", 0); // 0// 遍歷方式1:entrySet
for (Map.Entry<String, Integer> entry : hashMap.entrySet()) {System.out.println(entry.getKey() + ": " + entry.getValue());
}// 遍歷方式2:keySet
for (String key : hashMap.keySet()) {System.out.println(key);
}// 遍歷方式3:values
for (int value : hashMap.values()) {System.out.println(value);
}// Java 8操作
hashMap.forEach((k, v) -> System.out.println(k + " => " + v));
hashMap.computeIfAbsent("Pear", k -> 5); // 如果不存在則添加
hashMap.merge("Apple", 5, Integer::sum); // Apple數量增加5

4. LinkedHashMap示例

// 創建LinkedHashMap(保持插入順序)
Map<String, Integer> linkedHashMap = new LinkedHashMap<>();linkedHashMap.put("First", 1);
linkedHashMap.put("Second", 2);
linkedHashMap.put("Third", 3);// 遍歷順序與插入順序一致
linkedHashMap.forEach((k, v) -> System.out.println(k)); // First, Second, Third// 按訪問順序排序的LinkedHashMap(可用于LRU緩存)
Map<String, Integer> accessOrderMap = new LinkedHashMap<>(16, 0.75f, true);accessOrderMap.put("One", 1);
accessOrderMap.put("Two", 2);
accessOrderMap.put("Three", 3);accessOrderMap.get("Two"); // 訪問Two會使它移動到末尾// 現在順序:One, Three, Two

5. TreeMap示例

// 創建TreeMap(按鍵自然排序)
Map<String, Integer> treeMap = new TreeMap<>();treeMap.put("Orange", 5);
treeMap.put("Apple", 10);
treeMap.put("Banana", 8);// 按鍵排序輸出
treeMap.forEach((k, v) -> System.out.println(k)); // Apple, Banana, Orange// 定制排序
Map<String, Integer> reverseMap = new TreeMap<>(Comparator.reverseOrder());
reverseMap.putAll(treeMap);// 輸出順序:Orange, Banana, Apple// 導航方法
TreeMap<Integer, String> employeeMap = new TreeMap<>();
employeeMap.put(1001, "Alice");
employeeMap.put(1002, "Bob");
employeeMap.put(1003, "Charlie");Map.Entry<Integer, String> entry = employeeMap.floorEntry(1002); // 1002=Bob
Integer higherKey = employeeMap.higherKey(1001); // 1002// 范圍視圖
Map<Integer, String> subMap = employeeMap.subMap(1001, true, 1003, false); // 1001-1002

紅黑樹特性:

  1. 每個節點是紅色或黑色

  2. 根節點是黑色

  3. 所有葉子節點(NIL)是黑色

  4. 紅色節點的子節點必須是黑色

  5. 從任一節點到其每個葉子的路徑包含相同數目的黑色節點

主要是TreeMap的底層結構就是紅黑樹,這里建議惡補一下數據結構的知識——紅黑樹、鏈表、二叉堆和二叉樹等,方便理解。這里放兩個鏈接:

二叉樹和堆詳解(通俗易懂)_堆和二叉樹的區別-CSDN博客

【數據結構】紅黑樹超詳解 ---一篇通關紅黑樹原理(含源碼解析+動態構建紅黑樹)_紅黑樹的原理-CSDN博客

?

?4.3 集合類選擇

4.3.1 集合類選擇指南

  • 需要存儲鍵值對時:

    • 不需要排序:HashMap

    • 需要保持插入/訪問順序:LinkedHashMap

    • 需要按鍵排序:TreeMap

    • 需要線程安全:ConcurrentHashMap

  • 只需要存儲元素時:

    • 允許重復、需要索引:ArrayList/LinkedList

    • 不允許重復、不關心順序:HashSet

    • 不允許重復、需要保持插入順序:LinkedHashSet

    • 不允許重復、需要排序:TreeSet

  • 需要隊列功能時:

    • 普通隊列:ArrayDeque

    • 優先級隊列:PriorityQueue

    • 線程安全隊列:LinkedBlockingQueue

  • 需要線程安全時:

    • List:CopyOnWriteArrayList

    • Set:CopyOnWriteArraySet

    • Map:ConcurrentHashMap

    • Queue:LinkedBlockingQueue

4.3.2?集合類選擇決策樹

字有點小,建議點開了以后放大看 !!

決策樹文字說明:

  • 第一層決策:存儲類型

    • 鍵值對 → 進入Map分支

    • 單元素 → 進入Collection分支

  • Map分支選擇邏輯:

    • 需要排序?→?TreeMap(自然排序)或ConcurrentSkipListMap(線程安全排序)

    • 不需要排序但需要順序?→?LinkedHashMap(可配置插入順序或訪問順序)

    • 都不需要 →?HashMap(最高性能)或ConcurrentHashMap(線程安全)

  • Collection分支選擇邏輯:

    • 允許重復(List/Queue):

      • 需要索引 →?ArrayList(隨機訪問快)或LinkedList(插入刪除快)

      • 需要隊列 →?ArrayDeque(標準隊列)或PriorityQueue(優先級隊列)

      • 線程安全 →?CopyOnWriteArrayListBlockingQueue實現類

    • 不允許重復(Set):

      • 需要排序 →?TreeSetConcurrentSkipListSet

      • 需要插入順序 →?LinkedHashSet

      • 只需要去重 →?HashSet

4.4?性能優化建議

  1. 合理設置初始容量:對于ArrayList、HashMap等基于數組的集合,預先設置合理的初始容量可以減少擴容帶來的性能損耗。

  2. 選擇合適的負載因子:HashMap的負載因子(默認0.75)決定了哈希表在多少滿時擴容。更高的值節省內存但增加哈希沖突。

  3. 實現高質量的hashCode():對于作為HashMap鍵或HashSet元素的類,要確保hashCode()方法能產生均勻分布的哈希值。

  4. 考慮使用視圖:keySet()、values()等方法返回的是視圖而非新集合,可以節省內存。

  5. 注意自動裝箱開銷:對于大量基本類型數據,考慮使用專門的集合庫如Trove,避免自動裝箱帶來的性能損耗。

  6. 謹慎使用同步集合:只有在確實需要線程安全時才使用同步包裝器,否則會帶來不必要的性能損失。

  7. 利用不可變集合:對于不會修改的集合,使用Collections.unmodifiableXXX()創建不可變視圖,既安全又明確表達設計意圖。

4.5 總結

我在第一次接觸集合類的時候其實有點被搞得眼花繚亂的,因為實現類太多了我也不是特別能分得清各個核心類之間的區別;后來代碼量逐漸上來以后才能分辨請他們之間的差異。比較核心底層的東西還是得看源碼。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/92943.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/92943.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/92943.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

GaussDB 數據庫架構師(八) 等待事件(1)-概述

1、等待事件概述 等待事件&#xff1a;指當數據庫會話(session)因資源競爭或依賴無法繼續執行時&#xff0c;進入"等待"狀態&#xff0c;此時產生的性能事件即等待事件。 2、等待事件本質 性能瓶頸的信號燈&#xff0c;反映CPU,I/O、鎖、網絡等關鍵資源的阻塞情況。…

五分鐘系列-文本搜索工具grep

目錄 1??核心功能?? ??2??基本語法?? 3????常用選項 & 功能詳解?? ??4??經典應用場景 & 示例?? 5????重要的提示 & 技巧?? ??6??總結?? grep 是 Linux/Unix 系統中功能強大的??文本搜索工具??&#xff0c;其名稱源自 …

Java面試題及詳細答案120道之(041-060)

《前后端面試題》專欄集合了前后端各個知識模塊的面試題&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

【嘗試】本地部署openai-whisper,通過 http請求識別

安裝whisper的教程&#xff0c;已在 https://blog.csdn.net/qq_23938507/article/details/149394418 和 https://blog.csdn.net/qq_23938507/article/details/149326290 中說明。 1、創建whisperDemo1.py from fastapi import FastAPI, UploadFile, File import whisper i…

Visual Studio 的常用快捷鍵

Visual Studio 作為主流的開發工具&#xff0c;提供了大量快捷鍵提升編碼效率。以下按功能分類整理常用快捷鍵&#xff0c;涵蓋基礎操作、代碼編輯、調試等場景&#xff08;以 Visual Studio 2022 為例&#xff0c;部分快捷鍵可在「工具 > 選項 > 環境 > 鍵盤」中自定…

Triton Server部署Embedding模型

在32核CPU、無GPU的服務器上&#xff0c;使用Python后端和ONNX后端部署嵌入模型&#xff0c;并實現并行調用和性能優化策略。方案一&#xff1a;使用Python后端部署Embedding模型 Python后端提供了極大的靈活性&#xff0c;可以直接在Triton中運行您熟悉的sentence-transformer…

Java動態調試技術原理

本文轉載自 美團技術團隊胡健的Java 動態調試技術原理及實踐, 通過學習java agent方式進行動態調試了解目前很多大廠開源的一些基于此的調試工具。 簡介 斷點調試是我們最常使用的調試手段&#xff0c;它可以獲取到方法執行過程中的變量信息&#xff0c;并可以觀察到方法的執…

人工智能-python-OpenCV 圖像基礎認知與運用

文章目錄OpenCV 圖像基礎認知與運用1. OpenCV 簡介與安裝OpenCV 的優勢安裝 OpenCV2. 圖像的基本概念2.1. 圖像的存儲格式2.2. 圖像的表示3. 圖像的基本操作3.1. 創建圖像窗口3.2. 讀取與顯示圖像3.3. 保存圖像3.4. 圖像切片與區域提取3.5. 圖像大小調整4. 圖像繪制與注釋4.1. …

Windows電腦添加、修改打印機的IP地址端口的方法

本文介紹在Windows電腦中&#xff0c;為打印機添加、修改IP地址&#xff0c;從而解決電腦能找到打印機、但是無法打印問題的方法。最近&#xff0c;辦公室的打印機出現問題——雖然在電腦的打印機列表能找到這個打印機&#xff0c;但是選擇打印時&#xff0c;就會顯示文檔被掛起…

告別復雜配置!Spring Boot優雅集成百度OCR的終極方案

1. 準備工作 1.1 注冊百度AI開放平臺 訪問百度AI開放平臺 注冊賬號并登錄 進入控制臺 → 文字識別 → 創建應用 記錄下API Key和Secret Key 2. 項目配置 2.1 添加依賴 (pom.xml) <dependencies><!-- Spring Boot Web --><dependency><groupId>o…

「iOS」——內存五大分區

UI學習iOS-底層原理 24&#xff1a;內存五大區總覽一、棧區&#xff08;Stack&#xff09;1.1 核心特性1.2 優缺點1.3函數棧與棧幀1.3 堆棧溢出風險二、堆區&#xff08;Heap&#xff09;;2.1 核心特性2.2 與棧區對比三、全局 / 靜態區&#xff08;Global/Static&#xff09;3.…

每日一題【刪除有序數組中的重復項 II】

刪除有序數組中的重復項 II思路class Solution { public:int removeDuplicates(vector<int>& nums) {if(nums.size()<2){return nums.size();}int index 2;for (int i 2; i < nums.size();i ) {if(nums[i] ! nums[index-2]) {nums[index]nums[i];}}return ind…

兼容性問題記錄

1、dialog設置高度MATCH_PARENT全屏后&#xff0c;三星機型和好像是一加&#xff0c;會帶出頂部狀態欄&#xff0c;設置隱藏狀態欄屬性無效。解決方法&#xff1a;高度不設置為MATCH_PARENT&#xff0c;通過windowmanager.getdefaultdisplay來獲取并設置高度&#xff0c;再設置…

6.數組和字符串

在C語言中&#xff0c;數組和字符串是基礎且重要的概念。它們用于存儲和操作一系列相同類型的元素或字符序列。數組1. 數組定義與初始化數組是一系列相同類型的數據項的集合&#xff0c;這些數據項可以通過一個共同的名字來引用。數組中的每個元素都有一個索引&#xff08;也稱…

odoo代碼分析(一)

Odoo 是一套基于網絡的開放式源代碼商業應用套件,既可以作為獨立應用運行,也可以作為集成的全功能 ERP 系統使用。Odoo 平臺采用模塊化架構,允許組織根據自身需求起步,并在需求增長時擴展功能。 什么是 Odoo? Odoo 提供了一個完整的商業應用生態系統,包括: 客戶關系管…

從“人工眼”到‘智能眼’:EZ-Vision視覺系統如何重構生產線視覺檢測精度?

制造業是我國實體經濟的基礎&#xff0c;是國內經濟增長的重要引擎。制造業智能化建設是當下的必然趨勢&#xff0c;然而目前依舊有很多中小型企業因為成本原因&#xff0c;無法加快智能化制造的步伐。在智能檢測領域更是如此&#xff0c;很多企業依舊在采用人工檢測&#xff0…

Etcd原理基礎學習

etcd 是一個開源的分布式鍵值存儲系統&#xff0c;專注于提供高可用性、強一致性的數據存儲與訪問&#xff0c;廣泛應用于分布式系統的服務發現、配置管理和協調任務。以下是其核心特性和應用場景的詳細介紹。接下來就看看Etcd如何實現服務注冊&#xff0c;以及如何通過Raft算法…

【硬件-筆試面試題】硬件/電子工程師,筆試面試題-32,(知識點:模數轉換器,信噪比,計算公式,)

目錄 1、題目 2、解答 步驟一&#xff1a;明確理想 ADC 的信噪比公式 步驟二&#xff1a;推導公式的來源 步驟三&#xff1a;得出答案 3、相關知識點 一、信噪比&#xff08;SNR&#xff09;的定義 二、理想 ADC 的量化噪聲 三、滿量程正弦波信號的功率 四、信噪比公…

Redis過期數據的刪除策略是什么?有哪些?

定時刪除&#xff1a;- 每個設置了TTL的key中都會創建一個計時器&#xff0c;等到過期時間就會立即刪除- 對內存友好&#xff0c;但是會占用大量的CPU資源去處理過期數據&#xff0c;從而影響緩存的吞吐量和響應時間惰性刪除&#xff1a;- 設置了key的過期后&#xff0c;不會立…

linux dd命令詳解

dd 是一個功能強大的 Unix/Linux 命令行工具&#xff0c;用于低級別的字節流操作&#xff0c;常用于創建、復制、轉換和處理文件或設備數據。它在 macOS 和 Linux 系統上都可用&#xff0c;但在 macOS 上有一些細微差異。本文將詳細講解 dd 命令的用法&#xff0c;包括參數、常…