「Java 數據結構全面解讀」:從基礎到進階的實戰指南

「Java 數據結構全面解讀」:從基礎到進階的實戰指南

數據結構是程序設計中的核心部分,用于組織和管理數據。Java 提供了豐富的集合框架和工具類,涵蓋了常見的數據結構如數組、鏈表、棧、隊列和樹等。本文將系統性地介紹這些數據結構的概念、特點以及在 Java 中的實現,并通過代碼示例進行演示。


一、數據結構基礎概念

數據結構研究的是數據的邏輯結構和物理結構,以及它們之間的關系。

1.1 數據的邏輯結構

數據的邏輯結構反映了數據元素之間的邏輯關系,而與存儲位置無關。常見邏輯結構包括:

  • 散列結構:元素之間除了“同屬一個集合”外,沒有其他關系。
  • 線性結構:元素之間存在一對一的關系,例如數組、鏈表。
  • 樹形結構:元素之間存在一對多的關系,例如二叉樹。
  • 圖形結構:元素之間存在多對多的關系。

在這里插入圖片描述

1.2 數據的物理結構

數據的物理結構描述了數據在計算機內存中的存儲方式,主要有:

  • 數組結構:元素在內存中是連續存儲的,即元素存儲在一整塊連續的存儲空間中,此時根據索引的查詢效率是非常高的,因為可以根據下標索引直接一步到位找到元素位置,如果在數組末尾添加和刪除元素效率也非常高。缺點是,如果事先申請足夠大的內存空間,可能造成空間浪費,如果事先申請較小的內存空間,可能造成頻繁擴容導致元素頻繁搬家。另外,在數組中間添加、刪除元素操作,就需要移動元素,此時效率也要打折。
  • 鏈式結構:元素在內存中是不要求連續存儲的,但是元素是封裝在結點當中的,結點中需要存儲元素數據,以及相關結點對象的引用地址。結點與結點之間可以是一對一的關系,也可以一對多的關系,比如:鏈表、樹等。遍歷鏈式結構只能從頭遍歷,對于較長的鏈表來說查詢效率不高,對于樹結構來說,查詢效率比鏈表要高一點,因為每次可以確定一個分支,從而排除其他分支,但是相對于數組來說,還是數組[下標]的方式更快。樹的實現方式有很多種,無非就是在添加/刪除效率 與 查詢效率之間權衡。
  • 索引結構:元素在內存中是不要求連續存儲的,但是需要有單獨的一個索引表來記錄每一個元素的地址,這種結構根據索引的查詢效率很高,但是需要額外存儲和維護索引表。。
  • 哈希結構:元素的存儲位置需要通過其hashCode值來計算,查詢效率也很多,但是要考慮和解決好哈希沖突問題。

數據結構和算法是一門完整并且復雜的課程
在這里插入圖片描述

二、Java 中常見的數據結構實現

Java 提供了豐富的數據結構支持,包括動態數組、鏈表、棧、隊列和樹等。這些數據結構主要通過 java.util 包中的類實現。

2.1 數組

動態數組特點

邏輯結構特點:線性結構

物理結構特點:
  • 申請內存:一次申請一大段連續的空間,一旦申請到了,內存就固定了。
  • 存儲特點:所有數據存儲在這個連續的空間中,數組中的每一個元素都是一個具體的數據(或對象),所有數據都緊密排布,不能有間隔。
例如:整型數組

在這里插入圖片描述

例如:對象數組

在這里插入圖片描述

自定義動態數組(拓展)示例代碼
package com.test.list;import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;public class MyArrayList<E> implements Iterable<E>{private Object[] all;private int total;public MyArrayList(){all = new Object[10];}public void add(E e) {ensureCapacityEnough();all[total++] = e;}private void ensureCapacityEnough() {if(total >= all.length){all = Arrays.copyOf(all, all.length + (all.length>>1));}}public void insert(int index, E value) {//是否需要擴容ensureCapacityEnough();//添加元素的下標檢查addCheckIndex(index);if(total-index > 0) {System.arraycopy(all, index, all, index+1, total-index);}all[index]=value;total++;}private void addCheckIndex(int index) {if(index<0 || index>total){throw new IndexOutOfBoundsException(index+"越界");}}public void delete(E e) {int index = indexOf(e);if(index==-1){throw new NoSuchElementException(e+"不存在");}delete(index);}public void delete(int index) {//刪除元素的下標檢查checkIndex(index);if(total-index-1 > 0) {System.arraycopy(all, index+1, all, index, total-index-1);}all[--total] = null;}private void checkIndex(int index) {if(index<0 || index>total){throw new IndexOutOfBoundsException(index+"越界");}}public void update(int index, E value) {//更新修改元素的下標檢查checkIndex(index);all[index] = value;}public void update(E old, E value) {int index = indexOf(old);if(index!=-1){update(index, value);}}public boolean contains(E e) {return indexOf(e) != -1;}public int indexOf(E e) {int index = -1;if(e==null){for (int i = 0; i < total; i++) {if(e == all[i]){index = i;break;}}}else{for (int i = 0; i < total; i++) {if(e.equals(all[i])){index = i;break;}}}return index;}public E get(int index) {//獲取元素的下標檢查checkIndex(index);return (E) all[index];}public int size() {return total;}public Iterator<E> iterator() {return new Itr();}private class Itr implements Iterator<E>{private int cursor;@Overridepublic boolean hasNext() {return cursor!=total;}@Overridepublic E next() {return (E) all[cursor++];}@Overridepublic void remove() {MyArrayList.this.delete(--cursor);}}
}
測試類
package com.test.list;import java.util.Iterator;public class TestMyArrayList {public static void main(String[] args) {MyArrayList<String> my = new MyArrayList<>();my.add("hello");my.add("java");my.add("java");my.add("world");my.add(null);my.add(null);my.add("list");my.add("data");System.out.println("元素個數:" + my.size());for (String s : my) {System.out.println(s);}System.out.println("-------------------------");System.out.println("在[1]插入JAVA移動技術棧后:");my.insert(1, "JAVA移動技術棧");System.out.println("元素個數:" + my.size());for (String s : my) {System.out.println(s);}System.out.println("--------------------------");System.out.println("刪除[1]位置的元素后:");my.delete(1);System.out.println("元素個數:" + my.size());for (String s : my) {System.out.println(s);}System.out.println("刪除null元素后:");my.delete(null);System.out.println("元素個數:" + my.size());for (String s : my) {System.out.println(s);}System.out.println("------------------------------");System.out.println("替換[3]位置的元素為JAVA移動技術棧后:");my.update(3, "JAVA移動技術棧");System.out.println("元素個數:" + my.size());for (String s : my) {System.out.println(s);}System.out.println("替換java為JAVA后:");my.update("java", "JAVA");System.out.println("元素個數:" + my.size());for (String s : my) {System.out.println(s);}System.out.println("------------------------------------");System.out.println("是否包含java:" +my.contains("java"));System.out.println("java的位置:" + my.indexOf("java"));System.out.println("haha的位置:" + my.indexOf("haha"));System.out.println("[0]位置元素是:" + my.get(0));System.out.println("------------------------------------");System.out.println("刪除字符串長度>4的元素后:");Iterator<String> iterator = my.iterator();while(iterator.hasNext()) {String next = iterator.next();if(next != null && next.length()>4) {iterator.remove();}}System.out.println("元素個數:" + my.size());for (String string : my) {System.out.println(string);}}
}

2.2 鏈表

鏈表特點
  • 數據存儲在結點中,結點通過指針連接。
  • 插入和刪除效率高,查詢效率低。
  • Java 提供了 LinkedList 類實現鏈表,支持雙向鏈表。

在這里插入圖片描述

示例代碼
import java.util.LinkedList;public class LinkedListExample {public static void main(String[] args) {LinkedList<String> linkedList = new LinkedList<>();linkedList.add("A");linkedList.add("B");linkedList.add("C");System.out.println(linkedList); // 輸出:[A, B, C]}
}

2.3 棧

棧特點

  • 先進后出(FILO)后進先出(LIFO):最后插入的元素最先被移除。
  • 棧只是邏輯結構,其物理結構可以是數組,也可以是鏈表,即棧結構分為順序棧和鏈式棧。
  • 核心類庫中的棧結構有 StackLinkedListStack 就是順序棧,它是 Vector 的子類,而 LinkedList 是鏈式棧。
核心操作方法
  • peek():查看棧頂元素,不彈出。
  • pop():彈出棧頂元素。
  • push(E e):壓入棧頂。
示例代碼
import java.util.Stack;public class StackExample {public static void main(String[] args) {Stack<Integer> stack = new Stack<>();stack.push(10);stack.push(20);stack.push(30);System.out.println(stack.pop()); // 輸出:30System.out.println(stack.peek()); // 輸出:20}
}
自定義單鏈表(拓展)
package com.test.list;import java.util.Iterator;public class MyOneWayLinkedList<E>  implements Iterable<E>{private Node head;private int total;public void add(E e){Node newNode = new Node(e, null);if(head == null){head = newNode;}else{Node node = head;while(node.next!=null){node = node.next;}node.next = newNode;}total++;}private Node[] findNodes(Object obj){Node[] result = new MyOneWayLinkedList.Node[2];Node node = head;Node find = null;Node beforeFind = null;if(obj == null){while(node != null){if(node.data == null){find = node;break;}beforeFind = node;node = node.next;}}else{while(node != null){if(obj.equals(node.data)){find = node;break;}beforeFind = node;node = node.next;}}result[0] = beforeFind;result[1] = find;return result;}public void delete(Object obj){Node[] nodes = findNodes(obj);Node beforeFind = nodes[0];Node find = nodes[1];if(find != null){if(beforeFind == null){head = find.next;}else {beforeFind.next = find.next;}total--;}}private Node findNode(Object obj){return findNodes(obj)[1];}public boolean contains(Object obj){return findNode(obj) != null;}public void update(E old, E value) {Node find = findNode(old);if(find != null){find.data = value;}}public int size() {return total;}@Overridepublic Iterator<E> iterator() {return new Itr();}private class Itr implements Iterator<E>{private Node node = head;@Overridepublic boolean hasNext() {return node != null;}@Overridepublic E next() {E value = node.data;node = node.next;return value;}}private class Node{E data;Node next;Node(E data, Node next) {this.data = data;this.next = next;}}
}
測試類
package com.test.list;public class TestMyOneWayLinkedList{public static void main(String[] args) {MyOneWayLinkedList<String> my = new MyOneWayLinkedList<>();my.add("hello");my.add("world");my.add(null);my.add(null);my.add("java");my.add("java");System.out.println("一共有:" + my.size());System.out.println("所有元素:");for (String s : my) {System.out.println(s);}System.out.println("-------------------------------------");System.out.println("查找java,null,haha的結果:");System.out.println(my.contains("java"));System.out.println(my.contains(null));System.out.println(my.contains("haha"));System.out.println("-------------------------------------");System.out.println("替換java,null后:");my.update("java","JAVA");my.update(null,"chai");System.out.println("所有元素:");for (String s : my) {System.out.println(s);}System.out.println("-------------------------------------");System.out.println("刪除hello,JAVA,null后:");my.delete("hello");my.delete("JAVA");my.delete(null);System.out.println("所有元素:");for (String s : my) {System.out.println(s);}}
}

自定義雙鏈表(拓展)

package com.test.list;import java.util.Iterator;public class MyLinkedList<E> implements Iterable<E>{private Node first;private Node last;private int total;public void add(E e){Node newNode = new Node(last, e, null);if(first == null){first = newNode;}else{last.next = newNode;}last = newNode;total++;}public int size(){return total;}public void delete(Object obj){Node find = findNode(obj);if(find != null){if(find.prev != null){find.prev.next = find.next;}else{first = find.next;}if(find.next != null){find.next.prev = find.prev;}else{last = find.prev;}find.prev = null;find.next = null;find.data = null;total--;}}private Node findNode(Object obj){Node node = first;Node find = null;if(obj == null){while(node != null){if(node.data == null){find = node;break;}node = node.next;}}else{while(node != null){if(obj.equals(node.data)){find = node;break;}node = node.next;}}return find;}public boolean contains(Object obj){return findNode(obj) != null;}public void update(E old, E value){Node find = findNode(old);if(find != null){find.data = value;}}@Overridepublic Iterator<E> iterator() {return new Itr();}private class Itr implements Iterator<E>{private Node node = first;@Overridepublic boolean hasNext() {return node!=null;}@Overridepublic E next() {E value = node.data;node = node.next;return value;}}private class Node{Node prev;E data;Node next;Node(Node prev, E data, Node next) {this.prev = prev;this.data = data;this.next = next;}}
}

自定義雙鏈表測試

package com.test.list;public class TestMyLinkedList {public static void main(String[] args) {MyLinkedList<String> my = new MyLinkedList<>();my.add("hello");my.add("world");my.add(null);my.add(null);my.add("java");my.add("java");System.out.println("一共有:" + my.size());System.out.println("所有元素:");for (String s : my) {System.out.println(s);}System.out.println("-------------------------------------");System.out.println("查找java,null,haha的結果:");System.out.println(my.contains("java"));System.out.println(my.contains(null));System.out.println(my.contains("haha"));System.out.println("-------------------------------------");System.out.println("替換java,null后:");my.update("java","JAVA");my.update(null,"chai");System.out.println("所有元素:");for (String s : my) {System.out.println(s);}System.out.println("-------------------------------------");System.out.println("刪除hello,JAVA,null后:");my.delete("hello");my.delete("JAVA");my.delete(null);System.out.println("所有元素:");for (String s : my) {System.out.println(s);}}
}

2.4 隊列

隊列特點

隊列是邏輯結構,其物理結構可以是數組,也可以是鏈表。隊列有普通隊列、雙端隊列、并發隊列等等,核心類庫中的隊列實現類有很多(后面會學到很多),LinkedList 是雙端隊列的實現類。

Queue 除了基本的 Collection 操作外,隊列還提供其他的插入、提取和檢查操作。每個方法都存在兩種形式:一種拋出異常(操作失敗時),另一種返回一個特殊值(nullfalse,具體取決于操作)。Queue 實現通常不允許插入 null 元素,即使在允許 null 的實現中,也不應該將 null 插入到隊列中,因為 null 也用作某些方法的特殊返回值,表明隊列不包含元素。

拋出異常返回特殊值
插入add(e)offer(e)
移除remove()poll()
檢查element()peek()
雙端隊列(Deque)

Deque,名稱 deque 是“double ended queue(雙端隊列)”的縮寫,通常讀為“deck”。此接口定義在雙端隊列兩端訪問元素的方法。提供插入、移除和檢查元素的方法。每種方法都存在兩種形式:一種形式在操作失敗時拋出異常,另一種形式返回一個特殊值(nullfalse,具體取決于操作)。Deque 接口的實現類有 ArrayDequeLinkedList,它們一個底層是使用數組實現,一個使用雙向鏈表實現。

第一個元素(頭部)最后一個元素(尾部)
拋出異常特殊值拋出異常特殊值
插入addFirst(e)offerFirst(e)addLast(e)offerLast(e)
移除removeFirst()pollFirst()removeLast()pollLast()
檢查getFirst()peekFirst()getLast()peekLast()

此接口擴展了 Queue 接口。在將雙端隊列用作隊列時,將得到 FIFO(先進先出)行為。將元素添加到雙端隊列的末尾,從雙端隊列的開頭移除元素。從 Queue 接口繼承的方法完全等效于 Deque 方法,如下表所示:

**Queue** 方法等效 **Deque** 方法
add(e)addLast(e)
offer(e)offerLast(e)
remove()removeFirst()
poll()pollFirst()
element()getFirst()
peek()peekFirst()

雙端隊列也可用作 LIFO(后進先出)堆棧。應優先使用此接口而不是遺留 Stack 類。在將雙端隊列用作堆棧時,元素被推入雙端隊列的開頭并從雙端隊列開頭彈出。堆棧方法完全等效于 Deque 方法,如下表所示:

堆棧方法等效 **Deque** 方法
push(e)addFirst(e)
pop()removeFirst()
peek()peekFirst()

結論:Deque 接口的實現類既可以用作 FILO 堆棧使用,又可以用作 FIFO 隊列使用。

示例代碼
import java.util.LinkedList;
import java.util.Queue;public class QueueExample {public static void main(String[] args) {Queue<String> queue = new LinkedList<>();queue.add("A");queue.add("B");queue.add("C");System.out.println(queue.poll()); // 輸出:ASystem.out.println(queue.peek()); // 輸出:B}
}

2.5 二叉樹

二叉樹特點
  • 每個節點最多有兩個子節點。
  • Java 提供了 TreeMapTreeSet 類實現基于紅黑樹的有序集合。
示例代碼
import java.util.TreeMap;public class TreeMapExample {public static void main(String[] args) {TreeMap<Integer, String> treeMap = new TreeMap<>();treeMap.put(1, "One");treeMap.put(2, "Two");treeMap.put(3, "Three");System.out.println(treeMap); // 輸出:{1=One, 2=Two, 3=Three}}
}
普通二叉樹:
public class BinaryTree<E>{private TreeNode root; //二叉樹的根結點private int total;//結點總個數private class TreeNode{//至少有以下幾個部分TreeNode parent;TreeNode left;E data;TreeNode right;public TreeNode(TreeNode parent, TreeNode left, E data, TreeNode right) {this.parent = parent;this.left = left;this.data = data;this.right = right;}}
}

TreeMap紅黑樹:

public class TreeMap<K,V> {private transient Entry<K,V> root;private transient int size = 0;static final class Entry<K,V> implements Map.Entry<K,V> {K key;V value;Entry<K,V> left;Entry<K,V> right;Entry<K,V> parent;boolean color = BLACK;/*** Make a new cell with given key, value, and parent, and with* {@code null} child links, and BLACK color.*/Entry(K key, V value, Entry<K,V> parent) {this.key = key;this.value = value;this.parent = parent;}}
}

三、總結與建議

Java 提供了對常見數據結構的完整支持,無論是基礎的數組、鏈表,還是復雜的樹、隊列,都可以通過標準庫輕松實現。在實際開發中,應根據場景選擇合適的數據結構:

  • 快速隨機訪問:選擇 ArrayList
  • 頻繁插入和刪除:選擇 LinkedList
  • 先進后出:選擇 Stack
  • 先進先出:選擇 Queue
  • 有序存儲:選擇 TreeMapTreeSet

通過對這些數據結構的深入理解和靈活運用,可以顯著提升程序的性能和可維護性。

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

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

相關文章

LeetCode - 初級算法 數組(旋轉數組)

旋轉數組 這篇文章討論如何通過編程實現數組元素的旋轉操作。 免責聲明:本文來源于個人知識與公開資料,僅用于學術交流。 描述 給定一個整數數組 nums,將數組中的元素向右輪轉 k 個位置,其中 k 是非負數。 示例: 輸入: nums = [1,2,3,

c#集合詳解-Dictionary、List、Queue、Stack等

目錄 一&#xff0c;非泛型集合 1&#xff0c;ArrayList &#xff08;1&#xff09;創建和初始化ArrayList() &#xff08;2&#xff09;常用方法 ①Add(value) ②AddRange(value) ③Insert(index,value) ④Remove(value) ⑤RemoveAt(index) ⑥clear() ⑦Contains(v…

記一次網閘部署經歷

1.在成功獲取某大廠偉思網閘設備&#xff0c;并與客戶就現有網絡架構&#xff08;包括防火墻與交換機&#xff09;進行了詳盡的溝通與評估后&#xff0c;我們團隊精心構思并提出了一個創新的實施方案——采用透明網橋模式。這一模式以其獨特的優勢&#xff0c;即無需對客戶現有…

SpringCloud(一)--SpringCloud簡介

一. 引言 ? 在微服務架構日益盛行的今天&#xff0c;Spring Cloud憑借其簡單易用、功能強大的特性&#xff0c;成為了眾多開發者的首選。本文僅為學習所用&#xff0c;聯系侵刪。 二. SpringCloud概述 2.1 定義 ? Spring Cloud是一系列框架的有序集合&#xff0c;它巧妙地…

SQLALchemy如何將SQL語句編譯為特定數據庫方言

最近在一個使用fastapitortoise-orm的項目中&#xff0c;需要將orm的語句編譯成特定數據庫方言&#xff0c;但是查詢了官方文檔及一些資料卻找不到合適的方法論&#x1f614;&#xff0c;于是乎我就把目光放到了sqlalchemy身上&#xff0c;東找西找給我找著了。話不多說&#x…

廬山派K230學習日記2 MicroPython基礎

MicroPython文檔&#xff1a; https://docs.micropython.org/ MicroPython是編程語言 Python3 的精簡高效實現&#xff0c;語法和 Python3 保持一致&#xff0c;但只實現了 Python 標準庫的一小部分&#xff0c;并且經過優化&#xff0c;適用于物聯網 (IoT)、消費電子和嵌入式…

《計算機組成及匯編語言原理》閱讀筆記:p177-p177

《計算機組成及匯編語言原理》學習第 13 天&#xff0c;p177-p177 總結&#xff0c;總計 1 頁。 一、技術總結 1.real mode A programming model where the program has access to the entire capability of the machine, bypassing security and memory management. Useful…

2000-2020年各省財政一般預算支出面板數據

2000-2020年各省財政一般預算支出面板數據 1、時間&#xff1a;2000-2020年 2、來源&#xff1a;國家統計局 3、指標&#xff1a;年份、省份、地方財政一般預算支出 4、范圍&#xff1a;31省 指標解釋&#xff1a;地方財政一般預算支出?是指地方ZF根據預算安排&#xff0…

python小項目:給復制出來的段落前添加星號

給復制出來的段落前添加星號 最終效果二、實現步驟2.1 編寫python腳本2.2 批處理腳本2.3 運行腳本 三、用到知識3.1 pyperclip 模塊 最終效果 說明&#xff1a;復制四段內容&#xff08;段落實際不做限制&#xff09;&#xff0c;在windows終端輸入 bulletPointAdder&#xff0…

【LeetCode Hot100 二分查找】搜索插入位置、搜索二維矩陣、搜索旋轉排序數組、尋找兩個正序數組的中位數

二分查找 搜索插入位置搜索二維矩陣在排序數組中查找元素的第一個和最后一個位置尋找旋轉排序數組中的最小值搜索旋轉排序數組尋找兩個正序數組的中位數&#xff08;hard&#xff09; 搜索插入位置 給定一個排序數組和一個目標值&#xff0c;在數組中找到目標值&#xff0c;并…

24.Java 新特性擴展(重復注解、類型注解)

一、重復注解 1、基本介紹 自從 JDK 5 引入注解以來&#xff0c;注解的使用開始流行&#xff0c;在各個框架中被廣泛使用 不過注解有一個很大的限制&#xff0c;在同一個地方不能多次使用同一個注解 JDK 8 引入了重復注解的概念 2、具體實現 &#xff08;1&#xff09;自…

后端java開發路由接口并部署服務器(四)

一、安裝IntelliJ IDEA&#xff0c;安裝包下載 1、官網下載 2、網盤資源 安裝包下載完成后進行傻瓜式下一步安裝就可以了 打開IntelliJ IDEA&#xff0c;輸入網盤資源文件內容 三、漢化處理 插件搜索chinese&#xff0c;就會找到相應的插件安裝重啟軟件即可 四、新建后端j…

Vue.js 表單驗證實戰:一個簡單的登錄頁面

修改日期備注2025.1.2初版 一、前言 Vue.js 學習第一天——學會一個帶有簡單表單驗證的登錄頁面。通過這個項目&#xff0c;會對 Vue.js 的核心概念有了更深入的理解&#xff0c;加深掌握如何運用 Vue 的一些強大特性來實現動態交互和數據處理。 二、項目的基本結構 首先&a…

MySQL 鎖那些事

Q1 : MySQL有哪些鎖,功能是什么,如何項目中使用?Q2 : 行鎖是如何實現的?什么情況下會使用行鎖?Q3 : 四種事務隔離形式的行鎖有什么不一樣?讀未提交讀提交可重復讀串行 Q4 : MySQL 的讀寫都是怎樣加鎖的?Q5 : 需要注意什么? Q1 : MySQL有哪些鎖,功能是什么,如何項目中使用…

國產文本編輯器EverEdit - 批量轉碼轉換行符

1 批量轉碼&轉換行符 1.1 應用場景 如果用戶批量在Windows編輯文件&#xff0c;要上傳到異構系統&#xff0c;如&#xff1a;Linux&#xff0c;則需要批量轉換編碼和換行符&#xff0c;此時可以使用EverEdit的批量轉碼功能。 1.2 使用方法 選擇主菜單文檔 -> 批量轉碼…

Java實現下載excel模板,并實現自定義下拉框

GetMapping("excel/download")ApiOperation(value "模板下載")public void getUserRecordTemplate(HttpServletResponse response, HttpServletRequest request) throws IOException {OutputStream outputStream response.getOutputStream();InputStream…

成立一家無人機培訓機構需要哪些基礎配置

成立一家無人機培訓機構&#xff0c;需要一系列基礎配置來確保教學質量、學員安全以及機構的正常運營。以下是根據公開發布的信息整理出的關鍵基礎配置&#xff1a; 一、場地配置 1. 飛行場&#xff1a;提供一個安全、寬敞的室外飛行環境&#xff0c;面積最好大于三千平米&…

交換機性能詳解

1. 背板帶寬 只有模塊化交換機&#xff08;擁有可擴展插槽&#xff0c;可靈活改變端口數量&#xff09;才有這個概念&#xff0c;固定端換機是沒有這個概念的。并且固定端換機的背板容量和交換容量大小是相等的。 背板帶寬是交換機的總數據處理能力&#xff0c;由硬件架構設…

讀“將計算性能調高到極致的基點秘訣”的嘗試

看到一篇文章&#xff0c;說最近閱讀LAMMPS源碼&#xff0c;悟出了很多道理。在計算性能優化這塊&#xff0c;源代碼作者很多寫法我最初不以為意&#xff0c;后來發現是作者有意為之&#xff0c;就是為了把計算性能優化到極致。做計算仿真軟件&#xff0c;也特別需要注意這些吧…

Gitea代碼倉服務搭建

特點與優勢 輕量級:Gitea是一個輕量級的Git服務,提供了快速、穩定的代碼托管和協作開發環境。它資源占用低,適合在資源受限的環境中運行。易于安裝和部署:Gitea提供了簡單易用的安裝和部署方式,支持多種安裝方式,包括二進制文件、Docker容器等,并提供了詳細的文檔和配置…