Java 類集初探

来源:https://www.cnblogs.com/wangyuyang1016/archive/2019/07/20/11219121.html
-Advertisement-
Play Games

類集 類集:主要功能就是Java數據結構的實現(java.util) 類集就是動態對象數組(鏈表也是動態數組) Collection 介面 Collection是整個類集之中單值保存的最大 父介面 。即:每一次僅可以向集合中保存一個對象 在Collection定義的常用操作方法 常用操作方法 向集合 ...


類集

  • 類集:主要功能就是Java數據結構的實現(java.util)
  • 類集就是動態對象數組(鏈表也是動態數組)

Collection 介面*

  • Collection是整個類集之中單值保存的最大 父介面 。即:每一次僅可以向集合中保存一個對象
public interface Collection<E>
extends Iterable<E>
  • 在Collection定義的常用操作方法

常用操作方法

  • 向集合中保存數據
public  boolean add(E e);
  • 追加一個集合
public boolean addAll(Collection<? extends E>c);
  • 清空集合(根元素為null)
public void clear();
  • 判斷是否有指定的內容
public boolean contains(Object o);
  • 判斷是否為空集合
public boolean isEmpty();
  • 刪除對象
public boolean remove(Object o);
  • 取得元素個數
public int size();
  • 以對象數組保存集合
public Object [] toArray();
  • 為Iterator介面實例化
public Iterator<E> iterator();

contains() 和 remove() 一定要依靠 equals() 的支持;

List子介面

  • List子介面是Collection介面中最常用的子介面;
  • List對Collection介面進行了功能的擴充;

常用操作

  • 取得索引編號的內容
public E get(int index);
  • 修改索引的內容
public E set(int index , E element);
  • 為LisIterator介面實例化對象
public ListIterator<E> listIterator();

List屬於介面,如果想使用介面進行操作,就必須存在子類;使用 ArrayList 子類實現(和Vector子類)

ArrayList子類

    public static void main(String [] args) throws IOException {
        List<String> all = new ArrayList<String>();
        System.out.println("size:" + all.size() + "Null:" + all.isEmpty());
        all.add("Hello");
        all.add("Hello");
        all.add("World");
        System.out.println("size:" + all.size() + "Null:" + all.isEmpty());
        // Collection介面定義了size()方法取得集合長度
        // List子介面增加了 get() 方法,可取取得所有的數據
        for (int x = 0 ; x < all.size() ; x++) {
            String str = all.get(x);
            System.out.println(str);
        }
    }
}

通過對ArrayList()子類的使用分析在:List集合中所保存的數據是按照保存的順序存放的,而且允許重覆數據;List子介面有get()方法,可以獲得集合中指定序列的內容

  • 為Collection介面實例化
public class TestDemo {
    public static void main(String [] args) throws IOException {
        Collection<String> all = new ArrayList<String>();
        System.out.println("size:" + all.size() + "Null:" + all.isEmpty());
        all.add("Hello");
        all.add("Hello");
        all.add("World");
        System.out.println("size:" + all.size() + "Null:" + all.isEmpty());
        Object[] obj = all.toArray();//變為對象數組讀取數據
        for (int x = 0 ; x < obj.length ; x ++) {
            System.out.println(obj[x].toString());
        }
        /*for (int x = 0 ; x < all.size() ; x++) {
            String str = all.get(x);// 由於Collection類中沒有get()方法所以無法使用
            System.out.println(str);
        }*/
    }
}
  • List保存對象
class Book {
    private String title ; 
    private double price ;
    public Book(String title , double price) {
        this.price = price;
        this.title = title;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true ; 
        }
        if (obj == null) {
            return false;
        }
        if(!(obj instanceof Book)) {
            return false ; 
        }
        Book book = (Book) obj;
        if (this.title.equals(book.title) && this.price == book.price){
            return true;
        }
        return false;
    }
    @Override
    public String toString() {
        return this.title + "\t" + this.price + "\n";
    }
}

public class TestDemo {
    public static void main(String [] args) {
        List<Book> all = new ArrayList<Book>();
        all.add(new Book("Java",11.1));
        all.add(new Book("python",22.2));
        all.add(new Book("C/C++",33.3));
        all.add(new Book("PHP",44.4));
        // 切記:remove和contains方法需要在類中覆寫equls()類
        all.remove(new Book("PHP",44.4));
        System.out.println(all);
    }
}

Vector子類(舊)

  • 區別:

    Vector子類採用同步處理,線程安全;而ArrayList子類則採用非線程安全的非同步處理機制。ArrayList支持Iterator、ListIterator、foreach輸出,而Vector還支持Enumeration。

總結:

  • List中的數據保存順序就是數據的添加順序
  • List集合中允許保存有重覆的元素
  • List子介面比Collection擴充了get()、set()方法
  • List大多使用ArrayList子類進行操作

Set 子介面

Set子介面只是簡單點額繼承了Collection介面,並沒有效仿List介面對原介面的功能方法進行擴充。

  • 常見子類:HashSet、TreeSet

  • 觀察 HashSet 子類:

public class TestDemo {
    public static void main(String [] args) {
        Set<String> all = new HashSet<String>();
        all.add("Hello");
        all.add("Hello");//不保存重覆的數據
        all.add("World");
        all.add("HUAWEI");
        System.out.println(all + ">>>" + all.size());
    }
}

通過觀察發現:Set集合下沒有重覆的數據元素(Set 子介面的特征)即:HashSet 子類特征屬於 無序排列

  • 觀察 TreeSet子類:
public class TestDemo {
    public static void main(String [] args) {
        Set<String> all = new TreeSet<String>();
        all.add("Hello");
        all.add("Hello");//不保存重覆的數據
        all.add("World");
        all.add("Array");
        System.out.println(all + ">>>" + all.size());
    }
}

分析得出:TreeSet子類沒有重覆數據,以及所保存的內容預設自動升序排序。

數據排序問題

class Book implements Comparable<Book>{
    private String title ; 
    private double price ; 
    public Book(String title , double price) {
        this.title = title;
        this.price = price;
    }
    @Override
    public String toString() {
        return this.title + "\t" + this.price;
    }
    /*
     * 集合本質上就是動態對象數組,而動態的對象數組排序使用的是比較器
     * 所以我們使用comparable比較器
     * 
     * 由於存在重覆的元素,compareTo會認為是同一個對象,(Set子介面的特性)
     * 所以 set子介面的重覆判讀就是依靠Comparable
     * 為此我們可以使用String的compareTo方法進行同對象的比較
     */
    @Override
    public int compareTo(Book o) {
        if (this.price > o.price) {
            return 1;   
        } else if(this.price < o.price) {
            return -1;
        } else {
            // 我們調用String類的compareTo方法來比較
            return this.title.compareTo(o.title);
        }
    }
}

public class TestDemo {
    public static void main(String [] args) {
        Set<Book> all = new TreeSet<Book>();
        all.add(new Book("Java",11.1));
        all.add(new Book("Java",11.1));     //信息完全重覆
        all.add(new Book("php",11.1));      //信息部分重覆
        all.add(new Book("Python",33.3));   //信息完全不重覆
        System.out.println(all);
    }
}

通過觀察發現,Comparable介面支持了TreeSet類的重覆數據的判斷,並不支持對HashSet類的重覆數據的判讀

重覆元素問題

通過上述的各段代碼發現:Comparable介面(比較器)只負責對TreeSet子類的重覆元素的判斷;(依靠comparTo()方法,如若發現數據相同則判斷為是同樣的對象元素,則 return 0;)

如果要判斷數據元素的重覆,只能依靠Object中的方法:

  • 取得哈希碼
public int hashCode();
  • 對象比較
public boolean equals(Object obj);

代碼:

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        long temp;
        temp = Double.doubleToLongBits(price);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        result = prime * result + ((title == null) ? 0 : title.hashCode());
        return result;
    }


    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Book other = (Book) obj;
        if (Double.doubleToLongBits(price) != Double.doubleToLongBits(other.price))
            return false;
        if (title == null) {
            if (other.title != null)
                return false;
        } else if (!title.equals(other.title))
            return false;
        return true;
    }
  • 總結:

    在不考慮排序問題情況下,判斷元素是否重覆,依靠Object方法中的 hashCode() 和 equals()

總結:

  • 在開發中,Set子介面不建議首選,如果使用也是首選建議HashSet類;
  • Comparable 比較器普遍應用於Java理論中

集合輸出

Collection、List、Set三個介面,List介面是最有利於輸出操作的(ArrayList子類),故此集合的輸出:

Iterator*:迭代輸出

public interface Iterator<E> {
    public boolean hasNext();
    public E next<E>();
} 

Iterator是一個介面,如若取得介面的實例化需要依靠Collection介面iterator()方法

public Iterator<E> iterator();// java.util.Collection
public class TestDemo {
    public static void main(String [] args) {
        Set<String> all = new HashSet<String>();//Set子介面
        all.add("Mirror");
        all.add("wangyuyang");
        all.add("wangyuyang");
        Iterator<String> iter = all.iterator();// 實例化介面
        while (iter.hasNext()) { //判斷是否為空
            String str = iter.next();// 獲取元素數據
            System.out.println(str);
        }
    }
}

Set的特性會自動不保留重覆數據,並無序輸出

public class TestDemo {
    public static void main(String [] args) {
        List<String> all = new ArrayList<String>();//List子介面
        all.add("Mirror");
        all.add("wangyuyang");
        all.add("wangyuyang");
        Iterator<String> iter = all.iterator();// 實例化介面
        while (iter.hasNext()) { //判斷是否為空
            String str = iter.next();// 獲取元素數據
            System.out.println(str);
        }
    }
}

顯示添加的所有元素並原樣添加的順序輸出

  • 集合的輸出問題:

    在遇到集合的輸出問題是,完全可以直接使用Iterator介面進行輸出

ListIterator:雙向迭代

  • Iterator本身只具備”由前向後“的輸出,而 ListLterator 子介面則支持雙向迭代。

  • 判斷是否有前一個元素:(逆向)

public boolean hasPreviout();
  • 取得前一個元素:(逆向)
public E previous();
  • 實例ListIterator介面的List方法:
public ListIterator<E> listIterator();
public class TestDemo {
    public static void main(String [] args) {
        List<String> all = new ArrayList<String>();//Set子介面
        all.add("A");
        all.add("B");
        all.add("C");
        System.out.println("正向迭代輸出");
        ListIterator<String> iter = all.listIterator();
        while (iter.hasNext()) { //判斷是否為空
            String str = iter.next();// 獲取元素數據
            System.out.println(str);
        }
        System.out.println("***********");
        System.out.println("逆向迭代輸出");
        while(iter.hasPrevious()) {
            System.out.println(iter.previous());
        }
    }
}

上常式序實現了雙向迭代的功能;利用hasNet()方法判斷是否為空,next()方法輸出元素內容,實現正向迭代輸出;利用ListIterator介面中的hasPrevious()和Previous()方法來實現逆向迭代輸出。

  • 註意:

如果利用ListIterator介面實現逆向迭代輸出,就需要先進行正向迭代輸出;也就是說在實現逆向迭代輸出前必須實現正向迭代輸出。

Enumeration:枚舉輸出

Enumeration 和 Vector類同時發佈的輸出介面;早期的Vector類定義的集合就需要Enumeration 來輸出。

  • 介面定義
public interface Enumberation<E>{
    public boolean hasMoreElements(); //判斷是否有下一個元素
    public E nextElement(); // 獲取當前元素內容
}
  • 實例化 Enumeration介面對象,只能依靠 Vector子類
public Enumeration<E> elements() // 取得Enumeration介面對象
public class TestDemo {
    public static void main(String [] args) {
        Vector<String> all = new Vector<String>();//Set子介面
        all.add("A");
        all.add("B");
        all.add("C");
        Enumeration<String> enu = all.elements();
        while(enu.hasMoreElements()) {
            System.out.println(new String(enu.nextElement()));
        }
    }
}

foreach 輸出

public class TestDemo {
    public static void main(String [] args) {
        List<String> all = new ArrayList<String>();//Set子介面
        all.add("A");
        all.add("B");
        all.add("C");
        for (String str : all) {
            System.out.println(str);
        }
    }
}

Map介面

Collection每次都會保存一個對象,而Map介面主要負責一對對象的信息。

主要操作方法

  • 向集合中保存數據
public V put(K key , V value);
  • 根據Key查找Value
public V get(Object key);
  • 將Map結合轉化為Set集合
public Set<Map Entry<K,V>> entrySet();
  • 取出所有Key值
public Set<K> keySet();
  • 常用子類:
    • HashMap
    • Hashtable

觀察HashMap

public class TestDemo {
    public static void main(String [] args) {
        Map<String,Integer> map = new HashMap<String,Integer>();
        map.put("壹", 1);
        map.put("貳", 2);
        map.put("叄", 3);
        map.put("叄", 33);
        System.out.println(map);
    }
}

通過代碼分析可以發現:HashMap實現的輸出是無序的;發現的重覆的Key會進行覆蓋,使用新的內容key的value覆蓋原來的value

  • get方法的應用
public class TestDemo {
    public static void main(String [] args) {
        Map<String,Integer> map = new HashMap<String,Integer>();
        map.put("壹", 1);
        map.put("貳", 2);
        map.put(null, 3);
        System.out.println(map.get("壹")); //返回 1
        System.out.println(map.get("陸"));//key不存在返回 null
        System.out.println(map.get(null));// 返回 3
    }
}

通過HashMap和get()方法的代碼觀察發現,Map主要的目的是實現數據的信息的查找,Collection主要的目的是實現信息數據的輸出。

  • 取得所有的key值:
public class TestDemo {
    public static void main(String [] args) {
        Map<String,Integer> map = new HashMap<String,Integer>();
        map.put("壹", 1);
        map.put("貳", 2);
        map.put("叄", 3);
        Set<String> set = map.keySet();// 取得key
        Iterator<String> iter = set.iterator();
        while(iter.hasNext()) {
            System.out.println(iter.next());//輸出全部的key
        }
    }
}

觀察Hashtable

public class TestDemo {
    public static void main(String [] args) {
        Map<String,Integer> map = new Hashtable<String, Integer>();
        map.put("壹", 1);
        map.put("貳", 2);
        map.put("叄", 3);
        System.out.println(map);
    }
}

通過設置key或value為Null值來比較Hashtable和HashMap兩個子類之間區別:Hashtable子類不允許存在null值,而HashMap允許Key或Value中為null值。*

Iterator輸出的問題(重點)

  • 涉及到集合的輸出,一定要使用Iterator進行輸出;而Map介面中未定義返回Iterator介面對象的方法,故此Map數據使用Iterator輸出就需要將Map集合轉換為Set集合。

  • 在Collection介面中,Iterator得到的是一個Collection完整的對象;而Map則不同了,但是Map.put()向集合中存一對數據的時候,會自動的封裝為Map.Entry介面對象

public static interface Map.Entry<K,V>;//(等同於一個外部介面)
  • Map.Entry介面操作方法
    • getkey():獲取Key值
    • getValue():獲取Value值

在Map中保存的實際上是被Map.Entry介面包裝的一個對象,Map.Entry介面的對象包裝的是:Key和Value值對數據元素。

  • 如上述,Iterator如取出輸出的數據實取得是一個對象(Collection介面中就是實質上取得Collection的對象),而在Map介面中,則是取出一個Map.Entry介面對象,然後在得出Key和Value。
  • 在Map定義了一種將Map集合轉為Set的方法:
public Set<Map.Entry<K,V>> entrySet();
  • 轉為Set集合後,就可以調用Iterator輸出。

  • 利用Map介面EntrySet()方法將Map結合變為Set集合 ——> 利用Set結合中的iterator()方法將Set進行Iterator輸出 ——> 每一次取出的Set元素都是Map.Entrty介面對象,利用此對象進行Key與Value的取出

利用Iterator實現Map介面的輸出 *

public class TestDemo {
    public static void main(String [] args) {
        Map<String,Integer> map = new Hashtable<String, Integer>();
        map.put("壹", 1);
        map.put("貳", 2);
        map.put("叄", 3);
        // 將Map集合變為Set結合
        Set<Map.Entry<String, Integer>> set = map.entrySet();
        // 將Set集合實例化iterator介面對象
        Iterator<Map.Entry<String, Integer>> iter = set.iterator();
        while(iter.hasNext()) {
            // 因為iter內容保存的是Map.Entry介面的對象,所以利用Map.Entry對象將Key和Value取出
            Map.Entry<String, Integer> men = iter.next();
            System.out.println(men.getKey() + "==" + men.getValue());
        }
    }
}

Map集合中的Key

使用的Map集合,Key的類型可以自定義;那麼這個自定義的類型必須覆寫Object類之中的hashCode() 和 equals()方法,因為只有依靠這兩個方法,才可以判斷是否元素重覆。【首先的Key類型是String,儘量不要使用自定義的對象類型去定義key;因為String類中預設了hashCode() 和 equals()】

class Book{
    private String title ; 
    public Book(String title) {
        this.title = title;
    }
    @Override
    public String toString() {
        return this.title;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((title == null) ? 0 : title.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Book other = (Book) obj;
        if (title == null) {
            if (other.title != null)
                return false;
        } else if (!title.equals(other.title))
            return false;
        return true;
    }
    
}

public class TestDemo {
    public static void main(String [] args) {
        Map<Book,String> map = new HashMap<Book, String>();
        map.put(new Book("java"),new String ("開發"));
        System.out.println(map.get(new Book("java")));
    }
}

或者:

public class TestDemo {
    public static void main(String [] args) {
        Map<String,Book> map = new HashMap<String, Book>();
        map.put(new String ("開發"),new Book("java"));
        System.out.println(map.get(new String("開發")));
    }
}
public class TestDemo {
    public static void main(String [] args) {
        Map<String,Book> map = new HashMap<String, Book>();
        map.put("開發",new Book("java"));
        System.out.println(map.get("開發"));
    }
}

總結

  • Map集合保存數據更有利與查找,而Collection保存數據是為了輸出
  • Map使用Iterator介面輸出步驟:……
  • HashMap可以保存Null,Hashtable不可以保存null。
  • 可以不可以重覆,一旦出現重覆會覆蓋原有內容(更新Key的Value值)

Stack子類

Stack 表示:棧操作;棧是一種先進後出的數據結構;而Stack是Vector的子類。

public class Stack<E>
extends Vector<E>

需要註意:Stack雖是Vector子類,可是不會使用Vector方法。

Stack棧操作:

  • 入棧:
public E push(E item);
  • 出棧:
public E pop();
  • 實現入棧、出棧操作
public class TestDemo {
    public static void main(String [] args) {
        Stack<String> all = new Stack<String>();
        all.push("A");
        all.push("B");
        all.push("C");
        all.push("D");
        System.out.println(all.pop());
        System.out.println(all.pop());
        System.out.println(all.pop());
        System.out.println(all.pop());
    }
}

如果棧中數據已經全部執行出棧而依舊繼續執行出棧pop操作,則報錯:空棧異常(棧中無數據則無法出棧執行操作)

Properties子類

Collections工具類

  • 向集合中追加一組數據
public static <T> boolean addAll(Collection<E> c,……);
public class TestDemo {
    public static void main(String [] args) {
        List<String> all = new ArrayList<String>();
        Collections.addAll(all, "A","B","C","D");
        System.out.println(all);
    }
}

Collections工具類是負責給集合操作介面Collection提供輔助的操作方法


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.學生類的使用: 結果: 2.手機類的使用: 結果: ...
  • 一、概述  前面的文章中提到,如果我們要調用其它應用的服務,只能夠通過 RestTemplate 的方式,這在我們實際的開發中很不方便。那麼有沒有類似於 Dubbo 中 @Reference 這樣的註解直接調用呢?這就是我們今天要講的 Spring Cloud Feign。  S ...
  • "Relative Sort Array" Example 1: Constraints: arr1.length, arr2.length include include using namespace std; class Solution { public: vector relativeSo ...
  • package model; /*22:37 2019/7/20*/ /* top class的修飾符組合 abstract final public 2 * 2 * 2 warning: abstract final 衝突 最終,共有2*(2*2-1)=6種修飾符組合用於top class */ ... ...
  • 1、包裝類簡介 我們都知道Java是面向對象編程語言,包含了8種基本數據類型,但是這8種基本數據類型並不支持面向對象的特征,它們既不是類,也不能調用方法。這在實際使用時存在很多的不便,比如int類型需要轉換成字元串,為瞭解決這個不足。然後就出現了包裝類,顧名思義,就是將這些基本數據類型封裝在類中,並 ...
  • 運行時數據區   1. 程式計數器 (Program Counter)   每個線程獨占自己的程式計數器。如果當前執行的方式不是native的,那程式計數器保存JVM正在執行的位元組碼指令的地址,如果是native的,那程式計數器的值是undefined。 &e ...
  • 1.獲取類中的成員屬性信息 運行結果: 2.反射操作成員屬性內容: 運行結果: 如果不解除封裝,會拋如下異常: 3.獲取指定屬性類型: 運行結果: ...
  • jdk源碼每日一讀 (一) java.lang.Object 1. 類說明 Object是java繼承體系的根,是每一個類的基類,所有的類都實現了Object類的所有方法。 2.重要方法 3. 分析 1. getClass方法 getClass方法的返回值是Class對象,它返回的是對象消除靜態類型 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...