【數據結構與算法】ArrayList 和 順序表

文章目錄

  • 🌲List
  • 🌲1. 線性表
  • 🌲2. 順序表
    • 🌿2.1 MyArrayList
      • 2.1.1 類中重寫所有接口方法
      • 1.新增元素
      • 2.在pos位置新增元素(指定位置)
      • 3.判定是否包含了某個特定元素
      • 4.查找特定元素對應的位置
      • 5.獲取pos下標的元素
      • 6.給pos位置的元素替換成value
      • 7.刪除數據
      • 8.獲取順序表長度
      • 9.清空順序表
      • 10.打印順序表
      • 需要的自定義異常
  • 🌲3.ArrayList 簡介
  • 🌲4. ArrayList 的使用
    • 🌿4.1 ArrayList 的構造
    • 🌿4.2 ArrayList常見操作
    • 🌿4.3 ArrayList的遍歷
    • 🌿4.4 ArrayList的擴容機制(java8源碼實現講解)
  • 🌲5. ArrayList的具體使用
    • 🌿5.1 刪除字符 (要求使用集合)
    • 🌿5.2 楊輝三角
    • 🌿5.3 撲克牌洗牌
  • 6.🌸ArrayList的問題

在正式學習順序表前,先簡單了解一下 List

🌲List

在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述

🌲1. 線性表

線性表(linear list)是n個具有相同特性的數據元素的有限序列。 線性表是一種在實際中廣泛使用的數據結構,常見的線性表:順序表、鏈表、棧、隊列…

線性表在邏輯上是線性結構,也就說是連續的一條直線。但是在物理結構上并不一定是連續的,線性表在物理上存儲時,通常以數組和鏈式結構的形式存儲

在這里插入圖片描述

🌲2. 順序表

順序表是用一段物理地址連續的存儲單元依次存儲數據元素的線性結構,一般情況下采用數組存儲。在數組上完成數據的增刪查改

順序表底層是一個數組,為什么不直接操作數組就好了,還需要單獨寫個類?

在這里插入圖片描述

這個數組里有幾個有效數據?-----6個

在這里插入圖片描述

在Java里數組沒有元素默認為0,判斷的時候遇到0就停止,然后總數就是元素個數,那如果這6個元素中加了一個0呢?還是6個元素,但是數組認為只有5個元素,這就是為什么我們需要順序表

在使用ArrayList之前,我們自己實現一個順序表,方便我們更加深入的理解順序表,才能熟練使用它

🌿2.1 MyArrayList

public class MyArrayList implements IList {public int[] array;public int usedSize;//成員變量默認為0public static final int DEFAULT_CAPACITY = 10;public MyArrayList() {this.array = new int[DEFAULT_CAPACITY];}

成員變量包含數組,數組里的有效元素個數,數組長度(可以使用final修飾讓數據不被改變)
###🌿 2.1.1 接口IList

//10個方法
public interface IList {// 新增元素,默認在數組最后新增public void add(int data);// 在 pos 位置新增元素public void add(int pos, int data);// 判定是否包含某個元素public boolean contains(int toFind);// 查找某個元素對應的位置public int indexOf(int toFind);// 獲取 pos 位置的元素public int get(int pos);// 給 pos 位置的元素設為 valuepublic void set(int pos, int value);//刪除第一次出現的關鍵字keypublic void remove(int toRemove);// 獲取順序表長度public int size();// 清空順序表public void clear();// 打印順序表,注意:該方法并不是順序表中的方法,為了方便看測試結果給出的public void display();
}

注意:接口中的方法默認為public abstract 修飾

這些是我們要實現的所有方法,自己實現一遍,能更好的理解ArrayList

2.1.1 類中重寫所有接口方法

1.新增元素

// 新增元素,默認在數組最后新增
public void add(int data) { //默認在尾部插入數據//判滿if(isFull()){grow();//擴容}this.array[this.usedSize]=data;this.usedSize++;}public void grow(){this.array= Arrays.copyOf(this.array,2*this.array.length);}public boolean isFull(){return this.usedSize== array.length;}

默認在數組尾部新增

①需要判斷數組是否是滿的,滿的就需要擴容,
②不滿的話就進行元素插入,判斷數組滿不滿狀態的函數實現
③最后數組長度+1

2.在pos位置新增元素(指定位置)

public void add(int pos, int data) { //插入到指定位置//pos合法性try{checkPos(pos);if(isFull()){grow();//擴容}//挪動數據for (int i = usedSize-1; i >=pos ; i--) {array[i+1]=array[i];}array[pos]=data;this.usedSize++;}catch (PosIllegal e){System.out.println("插入元素pos位置不合法");e.printStackTrace();//提示異常位置}}private void checkPos(int pos) throws PosIllegal{if(pos < 0 || pos > usedSize) { //注意:usedSize能插入,只要前驅存在就可以插入throw new PosIllegal("Pos位置不合法!!");}}

①先判斷pos位置合法性,既不能是負數,又必須要有前驅信息的支持
②判斷數組元素是否滿了,繼續調用isFull()函數
③我們插入數據的時候,需要先把插入元素后面的元素都往后挪一位,挪數據實現從數組的最后一個元素開始往后挪,一次挪到當pos位置空出,沒有元素的時候即可
④挪完數據之后,我們把pos位置賦值為data,并且把數組大小擴容一位,方便再進行新增元素

3.判定是否包含了某個特定元素

 public boolean contains(int toFind) {for (int i = 0; i <this.usedSize ; i++) {if(array[i]==toFind){return true;}}return false;}

4.查找特定元素對應的位置

// 查找某個元素對應的位置
public int indexOf(int toFind) {for (int i = 0; i < this.usedSize; i++) {if(this.elem[i] == toFind){return i;}}return -1;
}

5.獲取pos下標的元素

private void checkPos2(int pos) throws PosIllegal{if(pos < 0 || pos >= usedSize) {throw new PosIllegal("Pos位置不合法!!");}}private void checkEmpty() {if(isEmpty()) {throw new EmptyException("順序表為空!");}}public boolean isEmpty(){return  usedSize==0;}@Overridepublic int get(int pos) {try{checkEmpty();checkPos2(pos);return array[pos];}catch (PosIllegal e){System.out.println("插入位置pos不合法");e.printStackTrace();}catch (EmptyException e){System.out.println("順序表位空");e.printStackTrace();}return -1;}

①先判斷pos位置合法性
②判斷數組是否為空(可有可無)

6.給pos位置的元素替換成value

①先要進行合法性判斷再替換

 public void set(int pos, int value) { //更新   pos位置更新為valuetry{checkEmpty();checkPos2(pos); array[pos]=value;}catch (PosIllegal e){System.out.println("插入位置pos不合法");e.printStackTrace();}catch (EmptyException e){System.out.println("順序表位空");e.printStackTrace();}}

7.刪除數據

 public void remove(int toRemove) {try{checkEmpty();int pos=indexOf(toRemove);if (pos==-1)return ;for (int i = pos; i <this.usedSize-1 ; i++) {array[i]=array[i+1];}this.usedSize--;}catch (EmptyException e){e.printStackTrace();}}

①順序表不為空
②順序表當中有我們要刪除的元素
③找到它的下標
④把i+1的值賦給i,i還要小于usedSize-1(只要涉及到刪除數據,如果是引用數據類型,那么就要把elem[i] = null;否則就會發生內存泄漏)

8.獲取順序表長度

// 獲取順序表長度
public int size() {return this.usedSize;
}

9.清空順序表

// 清空順序表
public void clear() {//因為是基本類型,所以置為0即可this.usedSize = 0;/*當它是引用類型時for (int i = 0; i < this.usedSize; i++) {this.elem[i] = null;}this.usedSize = 0;*/
}

①基本類型置為0即可,若是引用類型則循環打印置為null,再置為0

注意:
此處可以把elem置為null可以嗎?可以,但是很暴力,數組直接被回收了,順序表只執行了一次就沒了,再次使用的時候還需開辟新的數組,相當于我們每次使用的時候還需new一次,很麻煩也沒必要

10.打印順序表

public void display() {for (int i = 0; i < this.usedSize; i++) {System.out.print(array[i]+" ");}/*這里面所有都是 0for (int x : array) {System.out.print(x+" ");}*/}
}

需要的自定義異常

在這里面添加,獲取pos下標不合法的時候我們也可以寫我們需要的異常類來更好的實現我們需要的異常,實現異常的拋出是我們賦值命名的異常名:

public class MyArrayListEmptyException extends RuntimeException{public MyArrayListEmptyException(){}public MyArrayListEmptyException(String message){super(message);}
}
public class MyArraylistIndexOutofException extends RuntimeException{public MyArraylistIndexOutofException(){}public MyArraylistIndexOutofException(String message){super(message);}
}

好,自己實現一遍順序表是不是思路清晰了很多,我們正式進入順序表介紹

🌲3.ArrayList 簡介

在集合框架中,ArrayList是一個普通的類,實現了List接口,具體框架圖如下:
在這里插入圖片描述

  1. ArrayList是以泛型方式實現的,使用時必須要先實例化
  2. ArrayList實現了RandomAccess接口,表明ArrayList支持隨機訪問
  3. ArrayList實現了Cloneable接口,表明ArrayList是可以clone的
  4. ArrayList實現了Serializable接口,表明ArrayList是支持序列化的
  5. 和Vector不同,ArrayList不是線程安全的,在單線程下可以使用,在多線程中可以選擇Vector或者CopyOnWriteArrayList
  6. ArrayList底層是一段連續的空間,并且可以動態擴容,是一個動態類型的順序表

🌲4. ArrayList 的使用

🌿4.1 ArrayList 的構造

在這里插入圖片描述
進入ArrayList的源碼,我們來詳細了解

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述
提問:都是空數組,那我們main函數中add的值都是存在哪里的?

答:add函數過程中會擴容1.5倍 下面我們講到擴容機制再詳細說

在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述

方法一ArrayList()不帶參數的構造方法的使用:

ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(1);//往數組最后的一個位置存元素
arrayList.add(2);
arrayList.add(3);
arrayList.add(4);
System.out.println(arrayList);//用字符串的形式打印出來所有的元素
System.out.println(arrayList.size());//獲取當前有效數據的個數
System.out.println(arrayList.get(1));//獲取指定下標的元素

方法二的使用:

ArrayList<Integer> arrayList2 = new ArrayList<>(arrayList);
arrayList2.add(99);
arrayList2.add(199);
System.out.println(arrayList2);

arrayList2承接了arrayList1的數據(使用其他的集合 來構造當前的List,底層源碼實現是數組的拷貝)

方法三的使用:

ArrayList<Integer> arrayList3 = new ArrayList<>(15)

指定初始化數組容量大小

在源碼的實現里:
①:第一次add的時候,我們底層的數組才變成了10,如果只是調用了不帶參數的構造方法,默認還是0
②:grow函數就是擴容函數,擴容的方式是1.5倍的擴容

例如整體的舉例使用:

public static void main(String[] args) {// ArrayList創建,推薦寫法// 構造一個空的列表List<Integer> list1 = new ArrayList<>();// 構造一個具有10個容量的列表List<Integer> list2 = new ArrayList<>(10);list2.add(1);list2.add(2);list2.add(3);// list2.add("hello"); // 編譯失敗,List<Integer>已經限定了,list2中只能存儲整形元素// list3構造好之后,與list中的元素一致ArrayList<Integer> list3 = new ArrayList<>(list2);// 避免省略類型,否則:任意類型的元素都可以存放,使用時將是一場災難List list4 = new ArrayList();list4.add("111");list4.add(100);
}

🌿4.2 ArrayList常見操作

在這里插入圖片描述

add方法

ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(0,1);
arrayList.add(1,2);
arrayList.add(2,99);
System.out.println(arrayList);

需要注意的是:在我們實現元素插入賦值的時候,前驅必須存在

addAll方法:

ArrayList<Integer> arrayList2 = new ArrayList<>();
arrayList2.addAll(arrayList);
arrayList2.add(19);System.out.println(arrayList2);

在這里插入圖片描述

remove方法:

public class Main{public static void main(String[] args) {MyArrayList array=new MyArrayList();ArrayList<Integer> list=new ArrayList<Integer>();list.add(0,1);list.add(1,2);list.add(2,3);list.add(3,4);list.add(4,5);ArrayList<Integer> list2=new ArrayList<Integer>();list2.addAll(list);list2.add(99999999);list2.remove(new Integer(5));System.out.println(list2);}
}

在這里插入圖片描述
lastIndexOf方法:

int index = arrayList.lastIndexOf(new Integer(99));
System.out.println(index);

subList方法 和 set方法:

ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(0,1);
arrayList.add(1,2);
arrayList.add(2,99);
arrayList.add(3,199);
arrayList.add(4,299);
System.out.println(arrayList);List<Integer> list = arrayList.subList(1,3);//區間左閉右開
System.out.println(list);

相當于字符串的截取,區間左閉右開
這里面我們如果把list里面的數值改變了,是否會影響原來的arraylist數組呢?-----會改變
在這里插入圖片描述

🌿4.3 ArrayList的遍歷

ArrayList 可以使用三種方式遍歷:for循環+下標、foreach、使用迭代器

public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);// 使用下標+for遍歷for (int i = 0; i < list.size(); i++) {System.out.print(list.get(i) + " ");}System.out.println();// 借助foreach遍歷for (Integer integer : list) {  //也可以用int 這個過程相當于拆箱System.out.print(integer + " ");}System.out.println();Iterator<Integer> it = list.listIterator();while(it.hasNext()){System.out.print(it.next() + " ");}System.out.println();}

兩種迭代器打印代碼如下:

在這里插入圖片描述
在這里插入圖片描述

注意:

  1. ArrayList最常使用的遍歷方式是:for循環+下標 以及 foreach
  2. 迭代器是設計模式的一種,后序容器接觸多了在仔細學一學,講一講

感興趣的同學可以在IDEA中點到源碼,讀源碼學習

🌿4.4 ArrayList的擴容機制(java8源碼實現講解)

我們這里用的是 java8 源碼,更好理解,java17 重寫了,但是效果并不影響

ArrayList是一個動態類型的順序表,即:在插入元素的過程中會自動擴容

Object[] elementData; // 存放元素的空間
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; // 默認空間為0
private static final int DEFAULT_CAPACITY = 10; // 默認容量大小
public boolean add(E e) {ensureCapacityInternal(size + 1); // Increments modCount!!elementData[size++] = e;return true;
}
private void ensureCapacityInternal(int minCapacity) {ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);}return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {modCount++;// overflow-conscious codeif (minCapacity - elementData.length > 0)grow(minCapacity);
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) {// 獲取舊空間大小int oldCapacity = elementData.length;// 預計按照1.5倍方式擴容int newCapacity = oldCapacity + (oldCapacity >> 1);// 如果用戶需要擴容大小 超過 原空間1.5倍,按照用戶所需大小擴容if (newCapacity - minCapacity < 0)newCapacity = minCapacity;// 如果需要擴容大小超過MAX_ARRAY_SIZE,重新計算容量大小if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);// 調用copyOf擴容elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {// 如果minCapacity小于0,拋出OutOfMemoryError異常if (minCapacity < 0)throw new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}

總結:
檢測是否真正需要擴容,如果是調用grow準備擴容
預估需要庫容的大小
①初步預估按照1.5倍大小擴容
②如果用戶所需大小超過預估1.5倍大小,則按照用戶所需大小擴容
③真正擴容之前檢測是否能擴容成功,防止太大導致擴容失敗使用copyOf進行擴容
④.授予copeOf進行擴容

🌲5. ArrayList的具體使用

🌿5.1 刪除字符 (要求使用集合)

在這里插入圖片描述
在這里插入圖片描述

🌿5.2 楊輝三角

楊輝三角

在這里插入圖片描述
我們把圖形抽象為一個直角三角形

在這里插入圖片描述
要求的返回值是這樣的–二維數組
在這里插入圖片描述

在這里插入圖片描述
ret是整個數組

public List<List<Integer>> generate(int numRows) {List<List<Integer>> ret=new ArrayList<>();//第一行List<Integer> list0=new ArrayList<>();list0.add(1);ret.add(list0);//從第2行開始求每個元素for (int i = 1; i <numRows ; i++) {List<Integer> curRow = new ArrayList<>();//每一行curRow.add(1);  //第一列//中間List<Integer> preRow = ret.get(i - 1);//獲得上一行for (int j = 1; j < i; j++) {int val1 = preRow.get(j);int val2 = preRow.get(j - 1);curRow.add(val1 + val2);}//尾巴curRow.add(1);ret.add(curRow);}return ret;//返回目標數組}
}

🌿5.3 撲克牌洗牌

自己寫一副撲克牌

①:完成剛買牌的順序打印出來
②:我們再完成洗牌隨機打亂順序
③:三個人輪流每個人揭5張牌
④:輸出最后剩余的牌

1.我們需要先單獨創建一個Card類,定義花色和數字,添加構造方法以及getter和setter方法,重寫ToString方法

class Card {private String suit;private int rank;public Card(String suit, int rank) {this.suit = suit;this.rank = rank;}public String getSuit() {return suit;}public void setSuit(String suit) {this.suit = suit;}public int getRank() {return rank;}public void setRank(int rank) {this.rank = rank;}@Overridepublic String toString() {return "[ " + suit+" "+rank+" ]";}
}

2.牌按照花色和順序打印出來,再把花色和序號拼接在一起組成每個牌每個花色

public static final String[] suits = {"?","?","?","?"};public static List<Card> buyCard() {List<Card> desk = new ArrayList<>();for (int i = 0; i < 4; i++) {for (int j = 1; j <= 13 ; j++) {String suit = suits[i];Card card = new Card(suit,j);desk.add(card);}}return desk;
}

3.洗牌使用random類中的nextInt函數并且交換每個元素的下標,讓它遍歷的時候隨機和其他元素下標交換,讓下標隨機數取元素長度里的任何一個下標,正向遍歷也可以,反向遍歷更好

public static void shuffle(List<Card> cardList) {for (int i = cardList.size()-1; i > 0 ; i--) {Random random = new Random();int index = random.nextInt(i);swap(cardList,i,index);}
}
private static void swap(List<Card> cardList,int i,int j) {Card tmp = cardList.get(i);cardList.set(i,cardList.get(j));cardList.set(j,tmp);
}

4.三個人每個人都輪流揭五張牌,最后揭的牌需要刪除,方便后面我們打印剩余的牌

for (int i = 0; i < 5; i++) {for (int j = 0; j < 3; j++) {//每次揭牌都去獲取 cardList的0下標的數據【刪除】Card card = cardList.remove(0);List<Card> hand = hands.get(j);hand.add(i,card);//這里使用add 不能是set/*hands.get(j).add(card);*/}
}

5.當我們此時打印cardList就是剩余的牌了,然后把所有的代碼執行結果打印出來

附上代碼:

CardDemo

public class CardDemo {public static final String[] suits = {"?","?","?","?"};public List<Card> buyCard() {List<Card> cardList = new ArrayList<>();for (int i = 1; i <= 13; i++) {for (int j = 0; j < 4; j++) {int rank = i;String suit = suits[j];Card card = new Card(suit,rank);cardList.add(card);}}return cardList;}public void shuffle(List<Card> cardList) {Random random = new Random();for (int i = cardList.size()-1; i > 0 ; i--) {int index = random.nextInt(i);swap(cardList,i,index);}}private void swap(List<Card> cardList,int i,int j) {/*Card tmp =  cardList[i];cardList[i] = cardList[j];cardList[j] = tmp;*/Card tmp = cardList.get(i);cardList.set(i,cardList.get(j));cardList.set(j,tmp);}public List<List<Card>> play(List<Card> cardList) {List<Card> hand0 = new ArrayList<>();List<Card> hand1 = new ArrayList<>();List<Card> hand2 = new ArrayList<>();List<List<Card>> hand = new ArrayList<>();hand.add(hand0);hand.add(hand1);hand.add(hand2);for (int i = 0; i < 5; i++) {for (int j = 0; j < 3; j++) {Card card = cardList.remove(0);//怎么把對應的牌 放到對應的人的手里面hand.get(j).add(card);}}return hand;}
}

Card

public class Card {private String suit;private int rank;public Card(String suit, int rank) {this.suit = suit;this.rank = rank;}@Overridepublic String toString() {/*return "Card{" +"suit='" + suit + '\'' +", rank=" + rank +'}';*/return "{"+suit + rank +"} ";}
}

Main

public static void main(String[] args) {CardDemo cardDemo = new CardDemo();//1. 買52張牌List<Card> cardList = cardDemo.buyCard();System.out.println(cardList);//2. 洗牌cardDemo.shuffle(cardList);System.out.println(cardList);//3. 3個人 每個人 輪流揭牌5張List<List<Card>> ret = cardDemo.play(cardList);for (int i = 0; i < ret.size(); i++) {System.out.println("第"+(i+1)+"個人的牌:"+ret.get(i));}System.out.println("剩下的牌:");System.out.println(cardList);}

6.🌸ArrayList的問題

  1. ArrayList底層使用連續的空間,任意位置插入或刪除元素時,需要將該位置后序元素整體往前或者往后搬移,故時間復雜度為O(N)
  2. 增容需要申請新空間,拷貝數據,釋放舊空間。會有不小的消耗。
  3. 增容一般是呈2倍的增長,勢必會有一定的空間浪費。例如當前容量為100,滿了以后增容到200,我們再繼續插入了5個數據,后面沒有數據插入了,那么就浪費了95個數據空間

這些問題該如何解決呢?

使用鏈表就可以解決

下一篇文章揭曉鏈表的神奇應用

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

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

相關文章

OceanBase 推出單機版 ,為中小規模業務提供高性價比方案

近日&#xff0c;OceanBase正式推出了全新的單機版數據庫。這款產品基于OceanBase自主研發的單機分布式一體化架構&#xff0c;具有精簡的架構設計和出色的兼容性&#xff0c;能夠為中小規模業務場景提供高性價比的數據庫解決方案&#xff0c;充分滿足客戶在不同業務規模下的多…

如何在 Vue 3 中實現百度地圖位置選擇器組件

如何在 Vue 3 中實現百度地圖位置選擇器組件 前言 在開發前端應用時&#xff0c;地圖選擇器是一個非常常見的需求。尤其是在一些需要用戶選擇地址的場景&#xff0c;如電商平臺、旅游網站、酒店預定等&#xff0c;百度地圖組件能提供準確的地理位置服務。在本文中&#xff0c…

Python中如何用正則表達式精準匹配IP地址?

在網絡編程和數據處理時&#xff0c;我們經常需要從文本中提取或驗證IP地址。Python的正則表達式(re模塊)是完成這個任務的利器。但你知道怎么寫才能準確匹配各種合法的IP地址嗎&#xff1f;今天我們就來詳細探討這個問題。 為什么需要IP正則表達式&#xff1f; 假設你正在分…

spring--聲明式事務

聲明式事務 1、回顧事務 要么都成功&#xff0c;要么都失敗&#xff01; 事務在項目開發中&#xff0c;十分重要&#xff0c;涉及數據的一致性問題 確保完整性和一致性 事務ACID&#xff1a; 原子性&#xff1a;事務是原子性操作&#xff0c;由一系列動作組成&#xff0c;…

Kotlin 學習-集合

/*** kotlin 集合* List:是一個有序列表&#xff0c;可通過索引&#xff08;下標&#xff09;訪問元素。元素可以在list中出現多次、元素可重復* Set:是元素唯一的集合。一般來說 set中的元素順序并不重要、無序集合* Map:&#xff08;字典&#xff09;是一組鍵值對。鍵是唯一的…

WPF 五子棋項目文檔

WPF 五子棋項目文檔 1. 項目概述 本項目是一個使用 Windows Presentation Foundation (WPF) 技術棧和 C# 語言實現的桌面版五子棋&#xff08;Gomoku&#xff09;游戲。它遵循 MVVM&#xff08;Model-View-ViewModel&#xff09;設計模式&#xff0c;旨在提供一個結構清晰、可…

計算機操作系統——死鎖(詳細解釋和處理死鎖)

系列文章目錄 計算機操作系統-計算機系統中的死鎖 文章目錄 系列文章目錄前言一、資源問題&#xff1a; 計算機系統當中的死鎖&#xff1a; 二、死鎖的定義、必要條件和處理方法&#xff1a; 1.死鎖的定義&#xff1a;2.產生死鎖的必要條件&#xff1a;3.處理死鎖的方法&#…

Springboot項目正常啟動,訪問資源卻出現404錯誤如何解決?

我在自己的springboot項目中的啟動類上同時使用了SprinBootApplication和ComponentScan注解, 雖然項目能夠正常啟動,但是訪問資源后,返回404錯誤,隨后在啟動類中輸出bean,發現controller創建失敗: 而后我將ComponentScan去掉后資源就能訪問到了. 原因 SprinBootApplication本身…

第十五屆藍橋杯C/C++B組省賽真題講解(分享去年比賽的一些真實感受)

試題A——握手問題 一、解題思路 直接用高中學的排列組合思路 二、代碼示例 #include<bits/stdc.h> using namespace std; int fun(int n) {int sum0;for(int i0;i<n;i){for(int ji1;j<n;j)sum; } return sum; } int main() {cout<<fun(50)-fun(7); }三、…

動態規劃(6)——01背包問題

歡迎來到博主的專欄&#xff1a;算法解析 博主ID&#xff1a;代碼小號 文章目錄 牛客網——【模板】01背包題目解析題目1算法原理題目1題解代碼。問題2算法原理問題2題解代碼01背包問題的滾動數組優化 牛客網——【模板】01背包 題目解析 關于I/O相關的東西博主就不多贅述了&a…

TQTT_KU5P開發板教程---實現流水燈

文檔實現功能介紹 本文檔是學習本開發板的基礎&#xff0c;通過設置計數器使led0到led7依次閃爍&#xff0c;讓用戶初步認識vivado基本的開發流程以及熟悉項目的創建。本開發板的所有教程所使用的軟件都是vivado2024.1版本的。可以根據網上的教程下載與安裝。 硬件資源 此次教程…

Spring 中的 @Cacheable 緩存注解

1 什么是緩存 第一個問題&#xff0c;首先要搞明白什么是緩存&#xff0c;緩存的意義是什么。 對于普通業務&#xff0c;如果要查詢一個數據&#xff0c;一般直接select數據庫進行查找。但是在高流量的情況下&#xff0c;直接查找數據庫就會成為性能的瓶頸。因為數據庫查找的…

SEER: Self-Aligned Evidence Extraction for Retrieval-AugmentedGeneration

一、動機 如何從檢索到的段落中提取證據&#xff0c;以降低計算成本并提升最終的RAG性能&#xff0c;然而這一問題仍然具有挑戰性。 現有方法 嚴重依賴于基于啟發式的增強&#xff0c;面臨以下幾個問題&#xff1a; &#xff08;1&#xff09;由于手工制作的上下文過濾&…

毫米波測試套裝速遞!高效賦能5G/6G、新材料及智能超表面(RIS)研發

德思特&#xff08;Tesight&#xff09;作為全球領先的測試測量解決方案提供商&#xff0c;始終致力于為前沿技術研發提供高精度、高效率的測試工具。 針對毫米波技術在高頻通信、智能超表面&#xff08;RIS&#xff09;、新材料等領域的快速應用需求&#xff0c;我們推出毫米…

三維激光測量助力企業檢測效率提升3倍

智能制造與數字化浪潮席卷下&#xff0c;三維掃描技術已成為工業檢測領域不可或缺的工具。面對傳統檢測手段的精度瓶頸與效率局限&#xff0c;三維掃描儀&#xff0c;以毫米級精度、非接觸式測量與超高速掃描三大核心優勢&#xff0c;為汽車制造、航空航天、消費電子等行業的品…

SQL:Normalization(范式化)

目錄 Normalization&#xff08;范式化&#xff09; 為什么需要 Normalization&#xff1f; &#x1f9e9; 表格分析&#xff1a; 第一范式&#xff08;1NF&#xff09; 什么是第一范式&#xff08;First Normal Form&#xff09;&#xff1f; 第二范式&#xff08;2NF&am…

#MES系統運維問題分析思路

一套適用于90% MES運維現場問題的排查分析思維模型&#xff0c;叫做&#xff1a; &#x1f50d; MES系統問題分析七步法&#xff08;現場實戰適用&#xff09; ? 第一步&#xff1a;明確問題現象&#xff08;What&#xff09; 問題要說清楚&#xff0c;“不能操作”這種模糊描…

達夢數據庫-學習-18-ODBC數據源配置(Linux)

一、環境信息 名稱值CPU12th Gen Intel(R) Core(TM) i7-12700H操作系統CentOS Linux release 7.9.2009 (Core)內存4G邏輯核數2DM版本1 DM Database Server 64 V8 2 DB Version: 0x7000c 3 03134284194-20240703-234060-20108 4 Msg Versi…

js 效果展示 拿去練手

自學完整功能&#xff0c;拿去練手。 鼠標移動放大 通過網盤分享的文件&#xff1a;圖片放大 鏈接: https://pan.baidu.com/s/1w8SjtKi4kUNDnZtRDfYMeQ?pwd95p6 提取碼: 95p6 通過網盤分享的文件&#xff1a;圖片動畫效果 鏈接: https://pan.baidu.com/s/1Pjphx-Cc4HQQNNujr…

使用 TFIDF+分類器 范式進行企業級文本分類(二)

1.開場白 上一期講了 TF-IDF 的底層原理&#xff0c;簡單講了一下它可以將文本轉為向量形式&#xff0c;并搭配相應分類器做文本分類&#xff0c;且即便如今的企業實踐中也十分常見。詳情請見我的上一篇文章 從One-Hot到TF-IDF&#xff08;點我跳轉&#xff09; 光說不練假把…