JavaSE-知識點總結

Java名詞

變量運算符接口枚舉參數註解異常包裝類多線程 集合IO流網絡編程反射LambdaAPI

源文件:.java文件,存儲Java源代碼的文件

字節碼文件:.class文件,由Java源代碼編譯後生成的.class文件,可以被JVM讀取和執行的文件。

運行Java程序,其實就是執行.class字節碼文件,由JVM把字節碼數據再轉爲二進制的機器指令執行。

數據類型

基本數據類型:8種,byte,short,int,long,float,double,char,boolean

引用數據類型:類、接口、枚舉、數組、註解

變量

變量根據數據類型的不同分爲基本數據類型的變量和引用數據類型的變量。

變量根據聲明位置不同分爲成員變量和局部變量

(A)局部變量聲明位置:

①方法的形參列表

②方法體{}中

③代碼塊{}中

成員變量聲明位置:類中,方法和代碼塊外面,按照是否有static修飾分爲:類變量(靜態變量) 和 實例變量(非靜態變量)

(B)內存存儲的位置不同

局部變量:棧

實例變量:堆

類變量:方法區

(C)生命週期

局部變量

每一個線程每一次調用都是一次新的生命週期

實例變量:每一個對象的成員變量是獨立的,和對象的生命週期一致

類變量:和類的生命週期一致

(D)作用域

局部變量:作用域非常小,從聲明它的位置開始,到它所屬的}結束,可能只屬於某個if,for,方法等

類變量:整個類中

實例變量:整個類中除了靜態方法和靜態代碼塊中不能使用

(E)修飾符

局部變量:唯一可以有的修飾符是final

成員變量:權限修飾符、static、final、....

運算符

整數與整數相除,只保留整數部分

取模結果的正負號只看被模數

++/--在前的,就先自增/自減,後取值

++/--在後的,就先取值,後自增/自減

所有的賦值運算符的=左邊一定是一個變量,而且先算右邊,然後最後把值賦值給左邊的變量

擴展賦值運算符+=右邊的計算結果的類型如果比左邊的大的話會強制類型轉換,所以結果可能有風險

比較表達式的運算結果一定只有true/false

& 只有左右兩邊都爲true,結果才爲true。

| 只要左右兩邊有一個爲true,結果就爲true。

^ 只有左右兩邊不同,結果才爲true。

! 布爾值取反

&&它和邏輯與不同的是當&&左邊爲false時,右邊就不看了。

||它和邏輯或不同的時當||左邊爲true時,右邊就不看了。

條件表達式 ? 結果表達式1 : 結果表達式2    //爲true返回1,否則返回2

位運算符:所有的位運算符的規則都是用數字的二進制補碼形式進行運算的

<< 左移動幾位,右邊補0。左移幾位就是乘以2的幾次方

>> 右移動幾位,左邊補0或1,看最高位。右移幾位就是除以2的幾次方

>>> 右移動幾位,左邊一律補0

按位與:& 運算規則,把兩個數的二進制一一對應,對應位按位與。

按位或:| 運算規則,把兩個數的二進制一一對應,對應位按位或。

按位異或:^ 運算規則,把兩個數的二進制一一對應,對應位按位或。

按位取反:~ 運算規則,把某個數的二進制,按位取反,注意:包括最高位也會取反,這個和從原碼到反碼是不一樣的。

優先級:需要先計算的就用()括起來

對象1 == 對象2    //比較的是地址,而且對象1和對象2的類型要一致或者是父子類關係,否則編譯不通過

對象  instanceof 類型 

只有當該對象屬於這個類型纔會返回true,而且要求該對象的編譯時類型必須與要判斷的類型一致或有父子類關係

引用數據類型的類型或對象,可以通過 . 來訪問屬性、方法等。

()用於強制類型轉換或優先計算強制類型轉換

 流程:解決問題的步驟

(1)順序語句:順序結構

(2)分支語句:選擇其中一個分支執行

(3)循環語句:重複執行某些代碼

 凡是有[]的都是數組

類(class)

 使用class聲明的類型都是類

【修飾符】 class 類名 【extends 父類】 【implements 父接口n】{

}

類中可以包含5個部分:

(1)成員變量

靜態成員變量:存儲類共享數據

非靜態成員變量:存儲對象獨立數據

(2)成員方法:完成功能

(3)構造器:創建對象,是實例初始化的一部分

(4)代碼塊:

靜態代碼塊:類初始化的一部分

非靜態代碼塊:實例初始化的一部分

(5)成員內部類/成員內部接口:爲外部類服務

接口(interface)

使用interface聲明的類型都是接口

【修飾符】 interface 接口 【extends 父接口們】{

}

接口中的成員有限制要求:

JDK1.8之前:

(1)公共的靜態的常量:public static final

(2)公共的抽象方法:public abstract

JDK1.8之後,增加了:

(3)公共的靜態方法:public static

(4)公共的默認方法:public default

方法重寫的要求

(1)修飾符:>=父類權限

(2)返回值類型

基本數據類型和void:必須相同

引用數據類型:<=父類類型

(3)方法名:必須相同

(4) 形參列表:必須相同

(5)拋出的異常類型:<=父類類型

(6)被重寫的方法不能是:static,final,private等

枚舉(enum)

使用enum聲明的類型都是枚舉

【修飾符】 enum 枚舉類型名 【implements 父接口們】{
}

枚舉是一種特殊的類:

(1)枚舉的首行必須是枚舉的常量對象列表;

(2)枚舉的構造器都是private

(3)枚舉的直接父類一定是java.lang.Enum類

參數

 參數就是一種傳遞數據的方式,所以參數就是一個變量,具有特殊作用的特殊位置的變量。

和參數相關的幾個名詞:

(1)形參(formal parameter)

  在聲明方法時()中的參數

(2)實參(actual parameter)

  在調用方法時()中的參數,實參是給形參賦值的,所以實參的個數、類型、順序必須與形參一一對應。

(3)有參(has parameter)

  聲明方法時有形參列表,調用方法時有實參列表

(4)無參(no parameter)

  聲明方法時沒有形參列表,調用方法時沒有實參列表

(5)命令行參數(command line parameter/ arguments)

  運行main時,給main傳的參數

  java 類名  命令行參數1  命令行參數2 ....

(6)可變參數(variable parameter)

  聲明:

  【修飾符】 返回值類型 方法名(【非可變參數部分的形參列表,】 可變參數類型... args)throws 異常列表{
    for(int i=0; i<args.length; i++){  //可變參數部分當做數組使用
      //...
    }
  }

(7)類型參數(type parameter,generic Type)

  凡是代碼中出現在<>中的類型,就是類型參數。

(8)類型形參(type parameter)

  在聲明類/接口時聲明的類型參數,也稱爲泛型形參

【修飾符】 class 類名/接口<類型形參列表>{}

【修飾符】 class 類名/接口<類型形參1 extends 父類上限 & 父接口上限>{}

  在聲明方法時聲明的類型參數

【修飾符】 <泛型形參列表> 返回值類型 方法名(【數據形參列表】)【throws 異常列表】{}
【修飾符】 <泛型形參 extends 父類上限 & 父接口上限> 返回值類型 方法名(【數據形參列表】)【throws 異常列表】{}

(9)類型實參(type arguments)

  在使用泛型類/接口時指定泛型類型的類型參數

  在使用泛型方法時傳給泛型類的變量會自動識別變量類型,即爲泛型方法實參

(10)傳參(pass parameter)

凡是實參給形參賦值都是叫做傳參。

記住:實參與形參的類型、個數、順序一一對應即可。

註解(annotation)

使用@interface聲明的類型都是註解,只要使用@標記符的都是註解

@元註解
【修飾符】 @interface 註解名{
  數據類型 參數名();
  數據類型 參數名() default 默認值;
}

(1)如果註解有配置參數,那麼在使用時,需要給配置參數賦值,除非有默認值

(2)給配置參數賦值的標準格式:參數名 = 參數值,但是如果註解的配置參數只有一個,而且名稱是value,那麼在賦值時可以省略value=

(3)如果配置參數是數組類型,那麼賦值時可以用“{多個值}”

@Override

用於檢測被修飾的方法爲有效的重寫方法,如果不是,則報編譯錯誤!

只能標記在方法上。

JUnit單元測試

  • @Test:標記在非靜態的測試方法上。需導入junit包

文檔註解:

  • @author 標明開發該類模塊的作者,多個作者之間使用,分割

  • @version 標明該類模塊的版本

  • @see 參考轉向,也就是相關主題

  • @since 從哪個版本開始增加的

  • @param 對方法中某參數的說明,如果沒有參數就不能寫

  • @return 對方法返回值的說明,如果方法的返回值類型是void就不能寫

  • @throws/@exception 對方法可能拋出的異常進行說明 ,如果方法沒有用throws顯式拋出的異常就不能寫

    • 其中 @param @return 和 @exception 這三個標記都是隻用於方法的。

    • @param的格式要求:@param 形參名 形參類型 形參說明

    • @return 的格式要求:@return 返回值類型 返回值說明

    • @exception 的格式要求:@exception 異常類型 異常說明

    • @param和@exception可以並列多個

異常(Exception)

Java異常和錯誤的根父類:java.lang.Throwable

(1)只有是這個類或它的子類的對象,才能被JVM或throw語句“拋”出

(2)也只有這個類或它的子類的對象,才能被catch給“捕獲”

(3)如果用戶需要自定義異常,那麼必須繼承Throwable或它的子類。

Java異常的分類:

  • Error:錯誤,合理的應用程序不應該試圖捕獲的異常.
  • Exception:異常,合理的應用程序應該、想要捕獲的異常。 Java異常的分類:
  • 運行時異常(非受檢異常):RuntimeException及其子類,編譯器不會提示你需要加try...catch處理
  • 編譯時異常(受檢異常):RuntimeException系列以外的,編譯器一定會要求你加try...catch處理的

不管是什麼異常,最終都要進行處理,如果不處理,會導致程序終止運行

try:嘗試執行某些代碼,看是否會發生異常

catch:嘗試捕獲某個異常,如果可以捕獲,就處理它

finally:無論try中是否有異常發生,也不管catch是否可以捕獲這個異常, 哪怕try或catch有return,都無法阻止我運行finally中的代碼。

throw:手動拋出異常對象

throws:在方法聲明時,顯式的說明該方法會拋出xx異常,提醒調用者要處理這些異常。

語法

try{
  }catch(...){
  }finally{
  //無論try中是否發生異常,也無論catch是否捕獲異常,也不管try和catch中是否有return語句,都一定會執行
}

try{
  }finally{
  //無論try中是否發生異常,也不管try中是否有return語句,都一定會執行
}

新try..catch

語法格式:

try(需要關閉的資源對象的聲明){
   業務邏輯代碼
}catch(異常類型 e){
   處理異常代碼
....

它沒有finally,也不需要程序員去關閉資源對象,無論是否發生異常,都會關閉資源對象

常見的異常類型

包裝類

char ->Character

byte -> Byte

short -> Short

int -> Integer

long -> Long

float -> Float

double -> Double

boolean -> Boolean

void -> Void

裝箱:把基本數據類型轉爲包裝類對象。

拆箱:把包裝類對象拆爲基本數據類型。

包裝類對象有緩存問題

在緩存範圍內的對象,緩衝的常量對象在方法區直接引用。沒有緩存的對象,每一個都是新new的

多線程

創建多線程的兩種方式(JavaSE階段)

1、 繼承Thread

(1)編寫線程類,繼承Thread類

(2)必須重寫public void run(){}

(3)創建自定義線程類的對象

(4)調用start()方法啓動線程

2、實現Runnable接口

(1)編寫線程類,實現Runnable接口

(2)必須重寫public void run(){}

(3)創建自定義線程類的對象

(4)通過Thread類的代理對象,調用start()方法啓動線程

  如:MyRunnable my = new MyRunnable();
    Thread t = new Thread(my);
    t.start();

線程安全問題

1、什麼情況下會有線程安全問題?   多個線程使用了共享數據

2、如何解決線程安全問題?      SE階段:synchronized

(1)同步代碼塊

  synchronized(鎖對象){
    //在一個線程執行期間,不想要被其他線程打擾的代碼,一般是一次事務的原子性操作。
  }

鎖對象:自選的,但是要保證使用共享數據的這多個線程必須共用一個鎖對象(監視器對象)

至於是否可以選用this作爲鎖對象,要看是否多個線程共用同一個this對象

(2)同步方法

  【修飾符】 synchronized 返回值類型 方法名(【形參列表】){
     //在一個線程執行期間,不想要被其他線程打擾的代碼,一般是一次事務的原子性操作。
  }

鎖對象:固定,非靜態方法就是this,靜態方法就是當前類的Class對象

多線程間的通信就是通過鎖對象調用wait()等待與鎖對象調用notify()喚醒來達到多線程間的調度

 集合

集合是一種容器,用來裝對象的容器,不能裝基本數據類型。也可以說是一種數據結構

Collection中的集合稱爲單列集合,Map中的集合稱爲雙列集合。

Iterator迭代器

元素的通用獲取方式。在取元素之前先要判斷集合中有沒有元素,如果有,就把這個元素取出來,繼續在判斷,如果還有就再取出出來。一直把集合中的所有元素全部取出。

List 集合額外提供了一個ListIterator迭代器用來專門操作 List 集合的一些方法

List

  1. List集合所有的元素是以一種線性方式進行存儲的
  2. 它是一個元素存取有序的集合。
  3. 它是一個帶有索引的集合
  4. 集合中可以有重複的元素

ArrayList、Vector 順序結構,線性的,動態數組的實現

Stock 鏈式結構,先進後出,棧結構

LinkedList 鏈式順序結構,雙端隊列,雙鏈表的實現,既可以用作FILO堆棧使用,又可以用作FIFO隊列使用。

Set

  1. Set接口是Collection的子接口,set接口沒有提供額外的方法
  2. Set 集合不允許包含相同的元素

HashSet、底層new的 HashMap

  • HashSet 按 Hash 算法來存儲集合中的元素,因此具有很好的存取和查找性能。
  • 存儲到HashSet的元素要重寫hashCode和equals方法。

LinkedHashSet 、底層new的 LinkedHashMap

  • LinkedHashSet是HashSet的子類,增加兩個屬性before和after維護了結點的前後添加順序
  • LinkedHashSet插入性能略低於 HashSet,但在迭代訪問 Set 裏的全部元素時有很好的性能。

TreeSet 底層new的TreeMap 

  • 不允許重複
  • 實現排序 自然排序或定製排序

Map

  1. Map中的集合不能包含重複的鍵,值可以重複;每個鍵只能對應一個值
  2. Map.Entry是Map接口的內部接口,實際上是將Key---->value的數據存儲在Map.Entry接口的實例中,再在Map集合中插入Map.Entry的實例化對象
  3. 判斷兩個 key 相等的標準是:兩個 key 的hashCode 值相等,並且 equals() 方法也返回 true,用作鍵的對象必須實現 hashCode 方法和 equals 方法

HashMap、Hashtable

  • 動態數組結構+鏈式結構或哈希結構, 是個散列表,其中維護了一個長度爲2的冪次方的Entry類型的數組table,數組每個元素又由鏈表或紅黑樹結構組成

LinkedHashMap

  • 是HashMap的子類,與之不同的在於LinkedHashMap維護着一個運行於所有條目的雙重鏈接列表,此鏈接列表定義了迭代順序,該迭代順序通常就是(插入順序)

TreeMap

  • 基於紅黑樹的 NavigableMap 接口實現。該映射根據其鍵的自然順序進行排序,或者根據創建映射時提供的 Comparator 進行排序,具體取決於使用的構造方法。

Properties

  • 是 Hashtable 的子類,Properties 可保存在流中或從流中加載。屬性列表中每個鍵及其對應值都是一個字符串

Collections 是一個操作 Set、List 和 Map 等集合的工具類

IO流

 File類:文件和目錄路徑名的抽象表示形式。File 類的實例是不可變

 IO流是用於數據輸入與輸出

1、四大超類,抽象類

(1)InputStream:字節輸入流

(2)OutputStream:字節輸出流

(3)Reader:字符輸入流

(4)Writer:字符輸出流

2、常見IO流

(1)文件IO流

FileInputStream:文件字節輸入流,可以讀取任意類型的文件

FileOutputStream:文件字節輸出流,可以把字節數據輸出到任意類型的文件

FileReader:文件字符輸入流,只能讀取純文本的文件。按照平臺默認的字符編碼進行解碼。

FileWriter:文件字符輸出流,只能把字符數據輸出到純文本文件。按照平臺默認的字符編碼進行編碼。

(2)緩衝IO流

BufferedInputStream:字節輸入緩衝流,給InputStream系列IO流增加緩衝效果

BufferedOutputStream:字節輸出緩衝流,給OutputStream系列IO流增加緩衝效果

BufferedReader:字符輸入緩衝流,給Reader系列IO流增加緩衝效果

String readLine():按行讀取

BufferedWriter:字符輸出緩衝流,給Writer系列IO流增加緩衝效果

void newLine():輸出換行符

void flush()

(3)編碼與解碼的轉換流

  編碼:OutputStreamWriter

可以把字符流轉爲字節流輸出,並且可以指定字符編碼。

應用場景:可將要寫入的字符源爲字節流的數據轉爲字符類型寫入並可按指定字符集再編碼成字節存儲

  解碼:InputStreamReader

可以把字節輸入流轉爲字符輸入流,並且可以指定字符編碼。

應用場景:讀取源爲字符類型的字節流可指定字符集解碼成字符流,以便閱讀

(4)數據IO流

DataInputStream:允許應用程序以與機器無關方式從底層輸入流中讀取基本 Java 數據類型。

DataOutputStream:允許應用程序以適當方式將基本 Java 數據類型寫入輸出流中。

它倆必須配對使用,讀的順序要與寫的順序一致

(5)對象IO流,同上也需配對,讀寫順序一致

ObjectOutputStream:對象序列化,輸出對象,把對象轉爲字節序列輸出

void writeObject(Object obj)

  • 所有要序列化的對象的類型都必須實現java.io.Serializable接口
  • 如果對象的屬性類型也是引用數據類型,那麼也要實現java.io.Serializable接口
  • 希望類的修改對象反序列化不產生影響,需增加一個序列化版本ID
    • private static final long serialVersionUID = 1L;
  • 如果有些屬性不想要序列化,可以加transient
  • 如果某個屬性前面有static修飾,也不參與序列化

ObjectInputStream:對象反序列化,讀取對象,把字節序列重構成Java對象

Object readObject()

(6)打印流

PrintStream、PrintWriter:println()和 print()

(7)文本掃描儀

Scanner

網絡編程

三要素:1.協議。2.IP地址。3.端口號

Socket:通信的兩端都要有Socket(也可以叫“套接字”),是兩臺機器間通信的端點。網絡通信其實就是Socket間的通信。

TCP

TCP協議是面向連接的通信協議,即傳輸數據之前,在發送端和接收端建立邏輯連接,是一種面向連接的、可靠的、基於字節流的傳輸層的通信協議,可以連續傳輸大量的數據。

服務器端

  • 調用 ServerSocket(int port) :創建一個服務器端套接字,並綁定到指定端口上。用於監聽客戶端的請求。

  • 調用 accept() :監聽連接請求,如果客戶端請求連接,則接受連接,返回通信套接字對象。

  • 調用 該Socket 類對象的 getOutputStream() 和 getInputStream () :獲取輸出流和輸入流,開始網絡數據的發送和接收。

  • 關閉Socket 對象:客戶端訪問結束,關閉通信套接字。

客戶端

  • 創建 Socket :根據指定服務端的 IP 地址或端口號構造 Socket 類對象。若服務器端響應,則建立客戶端到服務器的通信線路。若連接失敗,會出現異常。

  • 打開連接到 Socket 的輸入/ 出流: 使用 getInputStream()方法獲得輸入流,使用getOutputStream()方法獲得輸出流,進行數據傳輸

  • 按照一定的協議對 Socket 進行讀/ 寫操作:通過輸入流讀取服務器放入線路的信息(但不能讀取自己放入線路的信息),通過輸出流將信息寫入線路。

  • 關閉 Socket :斷開客戶端到服務器的連接,釋放線路

UDP

UDP協議是一種面向非連接的協議,無連接的好處就是快,省內存空間和流量,因爲維護連接需要創建大量的數據結構。UDP會盡最大努力交付數據,但不保證可靠交付,沒有TCP的確認機制、重傳機制,如果因爲網絡原因沒有傳送到對端,UDP也不會給應用層返回錯誤信息。

反射

類的加載又分爲三個階段

(1)加載:load  (2)連接:link ①驗證②準備③解析  (3)初始化:initialize(類初始化)即執行<clinit>類初始化方法

不會導致類的初始化的情況,其他都會

 (1)使用某個類的靜態的常量(static final)

 (2)通過子類調用父類的靜態變量,靜態方法,只會導致父類初始化,不會導致子類初始化,即只有聲明靜態成員的類纔會初始化

 (3)用某個類型聲明數組並創建數組對象時,不會導致這個類初始化

類加載器

(1)引導類加載器(Bootstrap Classloader)又稱爲根類加載器

(2)擴展類加載器(Extension ClassLoader)

(3)應用程序類加載器(Application Classloader)

(4)自定義類加載器

獲取Class對象的四種方式

(1)類型名.class

(2)對象.getClass()

(3)Class.forName(類型全名稱)

(4)ClassLoader的類加載器對象.loadClass(類型全名稱)

反射可獲取類型的詳細信息

可以獲取:包、修飾符、類型名、父類(包括泛型父類)、父接口(包括泛型父接口)、成員(屬性、構造器、方法)、註解(類上的、方法上的、屬性上的)

創建任意引用類型的對象兩種方式

1、直接通過Class對象來實例化(要求必須有無參構造)

2、通過獲取構造器對象來進行實例化

操作任意類型的屬性

(1)獲取該類型的Class對象 Class clazz = Class.forName("com.atguigu.bean.User");

(2)獲取屬性對象 Field field = clazz.getDeclaredField("username");

(3)設置屬性可訪問 field.setAccessible(true);

(4)創建實例對象:如果操作的是非靜態屬性,需要創建實例對象 Object obj = clazz.newInstance();

(4)設置屬性值 field.set(obj,"chai");

(5)獲取屬性值 Object value = field.get(obj);

如果操作靜態變量,那麼實例對象可以省略,用null表示

調用任意類型的方法

(1)獲取該類型的Class對象 Class clazz = Class.forName("com.atguigu.service.UserService");

(2)獲取方法對象 Method method = clazz.getDeclaredMethod("login",String.class,String.class);

(3)創建實例對象 Object obj = clazz.newInstance();

(4)調用方法 Object result = method.invoke(obj,"chai","123);

如果方法的權限修飾符修飾的範圍不可見,也可以調用setAccessible(true)

如果方法是靜態方法,實例對象也可以省略,用null代替

 Lambda

函數式編程思想:強調做什麼,而不是以什麼形式做

 只要能獲取到結果,誰去做的,怎麼做的都不重要,重視的是結果,不重視過程

函數式接口

 標記了@FunctionalInterface

自定義函數式接口:只要確保接口中有且僅有一個抽象方法即可

 Java8新增了四大類,消費型、供給型、判斷型、功能型。

Lambda表達式語法格式

(形參列表) -> {Lambda體}

說明:

  • (形參列表)它就是你要賦值的函數式接口的抽象方法的(形參列表),照抄

  • {Lambda體}就是實現這個抽象方法的方法體

  • ->稱爲Lambda操作符(減號和大於號中間不能有空格,而且必須是英文狀態下半角輸入方式)

優化:Lambda表達式可以精簡

  • 當{Lambda體}中只有一句語句時,可以省略{}和{;}

  • 當{Lambda體}中只有一句語句時,並且這個語句還是一個return語句,那麼return也可以省略,但是如果{;}沒有省略的話,return是不能省略的

  • (形參列表)的類型可以省略

  • 當(形參列表)的形參個數只有一個,那麼可以把數據類型和()一起省略,但是形參名不能省略

  • 當(形參列表)是空參時,()不能省略

方法引用與構造器引用

方法引用的語法格式:

(1)實例對象名::實例方法

(2)類名::靜態方法

(3)類名::實例方法

說明:

  • ::稱爲方法引用操作符(兩個:中間不能有空格,而且必須英文狀態下半角輸入)

  • Lambda表達式的形參列表,全部在Lambda體中使用上了,要麼是作爲調用方法的對象,要麼是作爲方法的實參。

  • 在整個Lambda體中沒有額外的數據。

構造器引用的語法格式:

  • 類名::new

  • 數組類型名::new

(1)當Lambda表達式是創建一個對象,並且滿足Lambda表達式形參,正好是給創建這個對象的構造器的實參列表。

(2) 當Lambda表達式是創建一個數組對象,並且滿足Lambda表達式形參,正好是給創建這個數組對象的長度

StreamAPI

①Stream 自己不會存儲元素。

②Stream 不會改變源對象。每次處理都會返回一個持有結果的新Stream。

③Stream 操作是延遲執行的。這意味着他們會等到需要結果的時候才執行。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章