Java基礎面試題02

引用:(代碼隨想錄的八股轉免費了)以下為網址

卡碼筆記

本文為學習以上文章的筆記,如果有時間推薦直接去原網址

Java中的數據類型有哪些?分為哪兩大類? (考點:Java數據類型及其分類) 【簡單】

基本回答

分為 基本數據類型引用數據類型

基本數據類型

基本數據類型在內存中直接存儲值,有八種

  • 整數:byte(8位),short(16位),int(32位),long(64位)

  • 浮點數:float(32位),double(64位)

  • 字符:char(16位)

  • 布爾:boolean(1位)

引用數據類型

對對象的引用,而不是對象本身。存儲的是對象在內存中的地址。

  • 接口
  • 數組

基本數據類型(

整數:byte(8位),short(16位),int(32位),long(64位)

浮點數:float(32位),double(64位)

字符:char(16位)

布爾:boolean(1位)

引用數據類型(類? 接口? 數組

隱式類型轉換(小轉大),顯式類型轉換(大轉小)。

表達式結果的類型自動提升為所操作數據中最大的類型。

Java中的final關鍵字可以修飾什么?被final修飾后有什么特點? (考點:final關鍵字的用法) 【中等】

簡要回答
  • final作為Java中的一個關鍵字可以用來修飾 類 , 方法 ,和 變量。(但final不能修飾構造器
    1. 修飾類: 被final修飾的類不能被繼承,但該類可以去繼承別的 (沒有被final修飾的)類,例如String類和System類,它們被final修飾,是不可以被繼承的,但是它們有自己的父類——即頂層父類Object類。 被final修飾的類雖然不能被繼承,但?可以被實例化
    2. 修飾方法: 被final修飾的方法不能被子類重寫,但可以被子類繼承并使用(在滿足訪問權限規則的前提下)。當修飾方法時,?final關鍵字不能與abstract關鍵字共存;因為abstract修飾的方法是必須被非抽象子類重寫的。
    3. 修飾變量: 被final修飾的變量稱為最終變量,即常量——根據被修飾變量的定義位置又可分為成員常量和局部常量常量只能賦值一次,不能被二次更改

  • final作為Java中的一個關鍵字可以用來修飾 類 , 方法 ,和 變量。(但final不能修飾構造器
    1. 修飾類不能被繼承,但該類可以去繼承別的 (沒有被final修飾的)類可以被實例化
    2. 修飾方法不能被子類重寫,但可以被子類繼承并使用(在滿足訪問權限規則的前提下)final關鍵字不能與abstract關鍵字共存
    3. 修飾變量最終變量,即常量又可分為成員常量和局部常量常量只能賦值一次,不能被二次更改

解釋一下Java中的自動裝箱和拆箱。 (考點:自動裝箱與拆箱機制) 【簡單】

概念

自動裝箱:編譯器自動將基本數據類型轉換為對應的包裝類型

自動拆箱:編譯器自動將包裝類型轉換為對應的基本數據類型

Integer a = Integer.valueOf(10); // 自動裝箱

int b = a.intValue(); // 自動拆箱

Java中的==和equals()方法有什么區別? (考點:==與equals()的區別) 【簡單】

== 運算符
  • 用途==?運算符用于比較兩個引用是否指向同一個對象實例
  • 比較對象:當用于對象時,==?比較的是對象的內存地址,即它們是否是同一個對象。
  • 基本類型:對于基本數據類型(如?intchar?等),==?比較的是它們的值。
equals()

equals()?方法在?Object?類中定義,默認情況下,它與?==?等價(比較內存地址)。但是,許多類(如?String?和?Integer)重寫了此方法,以提供基于內容的比較。

== 運算符
  • 用途是否指向同一個對象實例。
  • 比較對象:比較的是內存地址
  • 基本類型:比較的是
equals()

equals()?方法在?Object?類中定義,默認情況下,它與?==?等價(比較內存地址)

許多類(如?String?和?Integer)重寫了此方法,以提供基于內容的比較

Java中的訪問修飾符有哪些?各自的訪問范圍是什么? (考點:Java訪問修飾符) 【簡單】

Java中有四種訪問修飾符:

一、public(公共的)

  1. 訪問范圍 ? 可以被任何類訪問,無論是在同一個包內還是不同包內的類。

二、protected(受保護的)

  1. 訪問范圍 ? 在同一個包內的類可以訪問。 ? 不同包中的子類可以訪問(這里的子類是通過繼承得到的)。

三、默認(無修飾符,也叫包級私有)

  1. 訪問范圍 ? 只能在同一個包內的類訪問。

四、private(私有的)

  1. 訪問范圍 ? 只能在定義它的類內部訪問,類外部的任何類(包括同一個包內的其他類和不同包中的子類等)都不能訪問。

public(公共的)>protected(受保護的)>默認(無修飾符,也叫包級私有)>private(私有的)

任何類-> 同一個包內的類,不同包中的子類->同一個包內的類->只在定義它的類內部訪問

Java中的靜態變量(static)和非靜態變量有什么區別? (考點:靜態變量與非靜態變量的區別) 【中等】

靜態變量
  • 靜態變量存儲在方法區的靜態存儲區,在類加載時分配內存
  • 靜態變量是全局共享的,所有的類的實例和靜態方法都可以訪問,且修改靜態變量會影響所有實例。
  • 可以通過類名.變量名的方式來訪問
非靜態變量
  • 非靜態變量存儲在堆內存中
  • 隨實例的創建而創建,隨實例的銷毀而銷毀
  • 必須通過實例對象訪問,不能直接通過類名訪問
靜態變量
  • 存儲靜態存儲區類加載時分配內存
  • 全局共享:所有的類的實例和靜態方法都可以訪問,且修改靜態變量會影響所有實例
  • 訪問方式類名.變量名
非靜態變量
  • 存儲:堆內存中
  • 隨實例的創建而創建,隨實例的銷毀而銷毀
  • 訪問方式:必須通過實例對象訪問,不能直接通過類名訪問

Java中的方法重載(Overloading)和方法覆蓋(Overriding)(重寫與方法覆蓋是同一概念的不同表述))有什么區別? (考點:方法重載與覆蓋) 【中等】

方法重載指的是在同一個類中,多個方法具有相同的名字,但參數列表不同。方法重載是編譯時多態的一種表現,它通過方法參數的不同來區分方法。

特點:
  • 方法名相同,但參數列表不同(參數個數、類型、順序)。
  • 返回值類型可以相同,也可以不同,但如果只有返回值不同,不能作為重載的依據。
  • 方法重載發生在同一個類中。

方法覆蓋是指子類重新實現父類中已經存在的方法,并且方法簽名(方法名、參數列表)保持一致。 方法覆蓋發生在繼承關系中,是運行時多態的一種體現,允許子類通過自己的實現覆蓋父類的方法。

特點:
  • 子類重寫父類的方法,方法名、參數列表、返回類型必須一致。
  • 只能發生在繼承關系中(子類繼承父類)。
  • 可以改變方法的實現,但不能改變方法簽名。
  • 運行時多態:方法的調用決定于對象的實際類型,而不是引用類型。

重載和重寫的主要區別:

特性方法重載(Overloading)方法覆蓋(Overriding)
定義在同一個類中,方法名相同,參數不同子類重新實現父類的已存在的方法
發生地點同一類中子類繼承父類時發生
方法簽名方法名相同,參數不同方法名相同,參數相同
返回類型返回類型可以不同(不作為重載的依據)返回類型必須相同(或是子類類型的子類)
訪問修飾符子類的訪問修飾符可以更寬松(但不能更嚴格)子類的訪問修飾符不能更嚴格,必須是相同或更寬松
多態類型編譯時多態運行時多態
調用方式通過方法參數來區分調用哪個方法通過對象的實際類型來調用方法

Java中的異常處理機制是怎樣的? (考點:Java異常處理機制) 【中等】

  • 編寫代碼時,將可能拋出異常的代碼放在try塊中。
  • try塊后面添加一個或多個catch塊來捕獲并處理可能發生的不同類型的異常。
  • 可選地,在try塊和catch塊之后添加一個finally塊來執行必要的清理代碼。
  • 在方法簽名中使用throws子句聲明方法可能拋出的異常。
  • 在代碼中,可以使用throw語句顯式地拋出異常。
  • 編寫代碼時,將可能拋出異常的代碼放在try塊中
  • try塊后面添加一個或多個catch塊來捕獲并處理可能發生的不同類型的異常
  • 可選地,在try塊和catch塊之后添加一個finally塊來執行必要的清理代碼
  • 在方法簽名中使用throws子句聲明方法可能拋出的異常
  • 在代碼中,可以使用throw語句顯式地拋出異常

解釋一下Java中的泛型(Generics)及其作用。 (考點:Java泛型) 【中等】

Java中的泛型(Generics)是一種通過參數化類型來增強代碼重用性和類型安全性的機制。它使得類、接口、方法能夠操作指定類型的對象,而不需要指定具體的類型。通過使用泛型,程序員可以編寫類型安全的代碼,同時避免強制類型轉換,增加了代碼的可讀性和維護性。

1. 泛型的基本概念

泛型允許你在編寫類、接口和方法時,不確定它們將操作的對象的類型,而是在實例化時指定具體的類型。你可以將泛型看作一個**“模板”**,它能在運行時確定操作的數據類型。

2. 泛型的作用
  • 類型安全:使用泛型可以讓代碼在編譯時檢查類型,避免了運行時錯誤。

  • 代碼復用:泛型允許你編寫更具通用性的代碼,可以處理不同的數據類型,而不需要為每個數據類型編寫不同的類或方法。

  • 避免強制類型轉換:使用泛型,編譯器會自動推斷類型,避免了手動進行類型轉換的麻煩。

3. 泛型的基本語法

泛型通常通過尖括號<>來指定,<>內是占位符,用來表示類型。例如:

  • 泛型類class ClassName<T>T代表一種類型。

  • 泛型方法<T> void method(T param)T是傳入方法的類型。

比喻:

假設你在開一個果汁店,你提供不同類型的果汁(橙汁、蘋果汁、葡萄汁等)。如果你不使用泛型,每次做一個新類型的果汁時,你都需要創建一個新的方法(例如做橙汁、做蘋果汁、做葡萄汁的獨立方法)。但是,如果你使用了泛型,你只需要一個通用的“果汁制作方法”,然后根據不同的果實類型來制作相應的果汁。

4. 泛型類示例

假設我們有一個容器類(比如Box),它可以存儲任何類型的對象。如果沒有泛型,我們就只能存儲特定類型的對象,且取出時需要做類型轉換。使用泛型后,容器可以存儲任何類型的對象,同時避免了類型轉換的問題。

沒有泛型的例子:
 

public class Box { private Object value; public void setValue(Object value) { this.value = value; } public Object getValue() { return value; } public static void main(String[] args) { Box box = new Box(); box.setValue("Hello"); String message = (String) box.getValue(); // 強制類型轉換 System.out.println(message); } }

這種方式雖然能存儲任何類型,但每次取出數據時都需要強制類型轉換,這容易出錯。

使用泛型的例子:
 

public class Box<T> { // 使用泛型 T private T value; public void setValue(T value) { this.value = value; } public T getValue() { return value; } public static void main(String[] args) { Box<String> box = new Box<>(); // 創建一個存儲 String 類型的 Box box.setValue("Hello"); String message = box.getValue(); // 不需要強制類型轉換 System.out.println(message); } }

在這個例子中,Box類是一個泛型類,它可以存儲任何類型的數據(通過類型參數T來指定)。通過在創建Box實例時指定類型(例如Box<String>),我們可以確保類型安全,而且不需要手動進行類型轉換。

5. 泛型方法

泛型不僅可以用于類,還可以用于方法。泛型方法允許你在方法中使用泛型參數,使得方法在不同的類型之間共享。

泛型方法示例:
 

public class GenericMethodExample { public static <T> void printArray(T[] array) { for (T element : array) { System.out.println(element); } } public static void main(String[] args) { Integer[] intArray = {1, 2, 3, 4}; String[] strArray = {"Apple", "Banana", "Cherry"}; printArray(intArray); // 輸出整數數組 printArray(strArray); // 輸出字符串數組 } }

這里的<T>表示該方法是一個泛型方法,可以接收任何類型的數組作為參數。無論是Integer類型的數組,還是String類型的數組,都可以通過這個方法進行打印。

6. 泛型的邊界(Bounded Type Parameters)

泛型類型參數可以加上邊界(Bound),限制它可以接受的類型范圍。使用extends關鍵字,你可以指定泛型的上邊界,這樣泛型參數就只能是指定類或其子類的類型。

上邊界(Upper Bounded Wildcards):
 

public class BoundedTypeExample { public static <T extends Number> void printNumbers(T[] numbers) { for (T num : numbers) { System.out.println(num); } } public static void main(String[] args) { Integer[] intArray = {1, 2, 3}; Double[] doubleArray = {1.1, 2.2, 3.3}; printNumbers(intArray); // 適用于 Integer 類型 printNumbers(doubleArray); // 適用于 Double 類型 } }

在這個例子中,<T extends Number>表示T只能是Number類或它的子類(如IntegerDouble等)。這確保了T的類型是數字類型。

7. 通配符(Wildcard)

泛型中的**通配符(Wildcard)**可以用來表示不確定的類型。例如,?表示任何類型。常見的通配符有:

  • ? extends T:表示類型是TT的子類。

  • ? super T:表示類型是TT的父類。

示例:
 

public class WildcardExample { public static void printList(List<? extends Number> list) { for (Number num : list) { System.out.println(num); } } public static void main(String[] args) { List<Integer> intList = List.of(1, 2, 3); List<Double> doubleList = List.of(1.1, 2.2, 3.3); printList(intList); // 適用于 Integer 類型 printList(doubleList); // 適用于 Double 類型 } }

這里的List<? extends Number>表示可以接受任何Number及其子類的List(如IntegerDouble等)。

8. 泛型的類型擦除

Java中的泛型是在編譯時通過類型擦除來實現的。在運行時,泛型的類型參數會被擦除,轉換為原始類型(例如,T被替換為ObjectList<T>變成了List)。因此,泛型的類型信息是不會保留到運行時的。

9. 總結
  • 泛型的作用

    • 提供類型安全的代碼。
    • 增強代碼的可重用性。
    • 避免強制類型轉換和運行時錯誤。
  • 泛型語法

    • 泛型類:class ClassName<T>
    • 泛型方法:<T> void method(T param)
    • 邊界(Bounded Type):<T extends Number>
  • 通配符? extends T表示類型是T的子類,? super T表示類型是T的父類。

泛型(Generics)是一種通過參數化類型來增強代碼重用性和類型安全性的機制。它使得

類、接口、方法能夠操作指定類型的對象,而不需要指定具體的類型。

通過使用泛型,程序員可以編寫類型安全的代碼,同時避免強制類型轉換,增加了代碼的可讀性和維護性。

1. 泛型的基本概念

泛型允許你在編寫類、接口和方法時,不確定它們將操作的對象的類型,而是在實例化時指定具體的類型。你可以將泛型看作一個**“模板”**,它能在運行時確定操作的數據類型。

2. 泛型的作用
  • 類型安全:使用泛型可以讓代碼在編譯時檢查類型,避免了運行時錯誤。

  • 代碼復用:泛型允許你編寫更具通用性的代碼,可以處理不同的數據類型,而不需要為每個數據類型編寫不同的類或方法。

  • 避免強制類型轉換:使用泛型,編譯器會自動推斷類型,避免了手動進行類型轉換的麻煩。

3. 泛型的基本語法

泛型通常通過尖括號<>來指定,<>內是占位符,用來表示類型。例如:

  • 泛型類class ClassName<T>T代表一種類型。

  • 泛型方法<T> void method(T param)T是傳入方法的類型。

4. 泛型類示例

假設我們有一個容器類(比如Box),它可以存儲任何類型的對象。如果沒有泛型,我們就只能存儲特定類型的對象,且取出時需要做類型轉換。使用泛型后,容器可以存儲任何類型的對象,同時避免了類型轉換的問題

  • 泛型的作用

    • 提供類型安全的代碼。
    • 增強代碼的可重用性。
    • 避免強制類型轉換和運行時錯誤。
  • 泛型語法

    • 泛型類:class ClassName<T>
    • 泛型方法:<T> void method(T param)
    • 邊界(Bounded Type):<T extends Number>
  • 通配符? extends T表示類型是T的子類,? super T表示類型是T的父類。

Java中的String類為什么是不可變的? (考點:String類的不可變性) 【中等】

Java中的String類是不可變的(immutable),這意味著一旦創建了一個String對象,它的值就不能被改變。這個設計帶來了很多好處,包括線程安全、性能優化和安全性等。

1. 為什么要設計成不可變?

1.1 線程安全

不可變的String類是天然線程安全的,因為它的值不能被修改。這就意味著多個線程可以共享同一個String對象,而不必擔心并發修改帶來的問題。

  • 比喻:想象你和幾個朋友一起共享一部旅行指南(String對象)。每個人都可以自由地閱讀這本書,但沒有人能在別人看書的時候悄悄改動里面的內容。所以,不會發生因為修改內容而導致爭議或錯誤的情況。
1.2 安全性

不可變對象的另一個好處是安全性。例如,String常常用于存儲用戶名、密碼、URL等敏感信息。如果String是可變的,那在某些情況下,其他代碼就有可能不小心或故意地修改它的值。而不可變的String確保了它的內容不會被改變,保障了數據的安全性。

  • 比喻:假設你在圖書館借書(String對象)。一旦借走,你就不能隨意修改書的內容,這樣其他借書的人才能放心使用。
1.3 優化性能(常量池)

Java通過字符串常量池來優化內存使用。因為String對象不可變,當你創建多個相同內容的String時,JVM會使用同一個對象而不是創建多個相同的String對象,從而節省內存。

  • 比喻:假設你在一家餐館吃飯,每次你點了一樣的菜,餐館都會直接給你一份已經做好的,而不是每次都重新做一份,這樣就避免了重復勞動和資源浪費。
1.4 提高效率

不可變的String對象可以共享,并且JVM可以對其進行各種優化(如緩存)。例如,Stringintern()方法會檢查常量池中是否已經存在相同的字符串,如果存在就返回相同的引用,這減少了內存的使用。

  • 比喻:想象你在購物時,商店有很多相同的商品,商店會在庫存中有一份相同的商品,而不是每次都去生產新商品,這樣節省了時間和資源。

2. 如何保證String不可變?

Java的String類通過以下幾個方面來實現不可變:

2.1?String類的字段是final

String類中存儲字符串內容的字段是private final char[] valuefinal關鍵字意味著這個字段只能被賦值一次,賦值后無法更改。因此,String的內容一旦設置好就無法修改。

2.2?String類沒有提供修改內容的方法

String類沒有提供可以直接修改其內容的方法,例如沒有setCharAt()append()等方法。所有對String的“修改”操作實際上都會生成一個新的String對象。例如,String類的concat()方法不會改變原始String對象,而是返回一個新的String對象。

  • 比喻:如果你正在寫一個日記(String),你不能直接在原來頁面上修改內容。每次你想修改內容時,必須在新的日記本上記錄,這樣舊的日記本內容不受影響。
2.3?String的不可變設計

每當對String進行修改時,都會生成一個新的String對象,而不是修改原來的對象。例如,調用+操作符或concat()方法連接字符串時,實際上會創建一個新的String對象。

  • 比喻:假設你想加裝飾畫到墻上(String)。雖然你可以在原有墻面上畫畫,但實際是把畫作掛在了新墻面上(新的String對象),原墻面沒有任何變化。

3.?String不可變的實現示例

 

public class StringExample { public static void main(String[] args) { String str1 = "Hello"; String str2 = str1; str1 = str1 + " World"; // 創建了一個新的String對象 System.out.println("str1: " + str1); // 輸出 "Hello World" System.out.println("str2: " + str2); // 輸出 "Hello" } }

在上面的例子中,雖然我們通過+操作符給str1增加了內容,但實際上它指向的是一個新的String對象,原始的str1對象內容沒有改變。因此,str2仍然指向原始的"Hello"

4. String的不可變性帶來的影響

4.1 性能考慮

雖然不可變性帶來了很多好處,但它也有一些缺點,尤其是在字符串頻繁修改的場景下,因為每次修改都會創建一個新的String對象。為了優化性能,通常可以使用StringBuilderStringBuffer類,它們是可變的,適合做頻繁的字符串拼接操作。

4.2 對比String和StringBuilder
 

public class StringBuilderExample { public static void main(String[] args) { StringBuilder sb = new StringBuilder("Hello"); sb.append(" World"); // 不會創建新對象,而是修改原有對象 System.out.println(sb.toString()); // 輸出 "Hello World" } }

在上面的代碼中,StringBuilder是可變的,它不會每次修改時創建新的對象,而是在原對象上進行操作,這樣可以提高效率。

  • String類是不可變的,意味著它一旦被創建就不能改變。

  • 不可變性帶來了線程安全安全性性能優化等優點。

  • String的不可變設計是通過final字段、沒有修改內容的方法、以及每次操作都會創建新的String對象來實現的。

  • 如果需要頻繁修改字符串,可以考慮使用StringBuilderStringBuffer,它們是可變的。

不可變的設計是String類的一大優勢,幫助Java程序在多線程和內存管理上變得更加高效和安全。

String、StringBuffer和StringBuilder有什么區別? (考點:String、StringBuffer與StringBuilder的區別) 【簡單】

StringStringBuffer?和?StringBuilder?是 Java 中用于處理字符串的三種類。它們之間有許多不同的特點,適用于不同的場景。

1.?String

  • 定義String?是不可變的字符序列。它的值一旦被賦值就不能改變,任何對?String?對象的操作(如連接、修改等)都會生成一個新的?String?對象。
  • 特點
    • 不可變性:一旦創建,字符串的值不能改變。任何修改字符串的操作都會生成一個新的對象,而原有的字符串對象保持不變。
    • 線程安全:由于是不可變的,不需要額外的同步機制,因此是線程安全的。
    • 內存效率問題:由于?String?是不可變的,所以它的字符串值會被多次復制,頻繁操作時可能會造成內存浪費(特別是字符串連接操作)。
  • 使用場景
    • 當字符串內容不需要頻繁改變時(例如固定內容、常量池中的字符串等),使用?String?是合適的。
    • 適合用于不需要改變的、較小的字符串處理操作。

2.?StringBuffer

  • 定義StringBuffer?是一個可以變更的字符序列,允許在原有字符序列上進行修改(比如追加、刪除字符等)。它是可變的,并且線程安全的。
  • 特點
    • 可變性StringBuffer?對象中的內容是可以改變的(例如:添加、刪除字符等)。它會直接修改原有字符數組,而不創建新的對象。
    • 線程安全StringBuffer?的方法是同步的,因此它是線程安全的,適用于多線程環境。
    • 性能:由于其線程安全性,StringBuffer?的性能相對較低,特別是在不涉及多線程的情況下,可能會比?StringBuilder?慢。
  • 使用場景
    • 當需要在多線程環境下進行字符串拼接或者修改時使用?StringBuffer
    • 在保證線程安全的情況下,需要進行字符串頻繁修改的場景(比如構建動態的字符串)。

3.?StringBuilder

  • 定義StringBuilder?與?StringBuffer?類似,也是一個可以變更的字符序列。與?StringBuffer?不同的是,StringBuilder?并不是線程安全的,適合單線程環境下使用。
  • 特點
    • 可變性StringBuilder?也可以修改其內部的字符序列,直接在原有字符數組上進行修改。
    • 線程不安全StringBuilder?的方法沒有同步,因此在多線程環境下,它不保證線程安全。
    • 性能:因為它沒有同步機制,相比?StringBuffer?來說,StringBuilder?在單線程下的性能更好,適合單線程環境中的高效字符串操作。
  • 使用場景
    • 在單線程環境下頻繁修改字符串時,使用?StringBuilder?可以獲得更好的性能。
    • 當線程安全不是問題時,并且操作頻繁時,推薦使用?StringBuilder

總結:

特性StringStringBufferStringBuilder
是否可變不可變可變可變
線程安全是 (通過同步實現線程安全)
性能性能較低(頻繁修改時不推薦)性能較低(同步操作影響性能)性能較高(適合單線程環境)
適用場景字符串不變時,常量池等使用多線程環境下需要修改字符串時使用單線程環境下頻繁修改字符串時使用

結論:

  • 如果你不需要修改字符串,使用?String
  • 如果在多線程環境下需要修改字符串,使用?StringBuffer
  • 如果在單線程環境下需要頻繁修改字符串,使用?StringBuilder

總結:

特性StringStringBufferStringBuilder
是否可變不可變可變可變
線程安全是 (通過同步實現線程安全)
性能性能較低(頻繁修改時不推薦)性能較低(同步操作影響性能)性能較高(適合單線程環境)
適用場景字符串不變時,常量池等使用多線程環境下需要修改字符串時使用單線程環境下頻繁修改字符串時使用

結論:

  • 如果你不需要修改字符串,使用?String
  • 如果在多線程環境下需要修改字符串,使用?StringBuffer
  • 如果在單線程環境下需要頻繁修改字符串,使用?StringBuilder

Java中的lambda表達式是什么?它帶來了哪些便利? (考點:Java lambda表達式) 【中等】

想象一下,你去咖啡店點了一杯咖啡。原來你得等服務員跑去廚房,然后帶著咖啡回來給你。這個過程就像傳統的代碼,你要去寫一個方法,然后傳遞給某個地方去執行。你看,整個過程慢得像烏龜。

但是,lambda 表達式就像是你告訴咖啡師:“嘿,我不想等,你直接在這兒做完就行了。” 這樣,你自己只需要告訴咖啡師“做一杯咖啡”就行,省去了不必要的繁瑣步驟。

Lambda表達式的好處就是讓代碼變得簡潔,功能也變得更靈活。

看個例子:

如果你要做一個加法運算:

傳統寫法

 

// 使用匿名類來寫 public int add(int a, int b) { return a + b; }

Lambda表達式寫法

 

// 使用Lambda表達式來寫 BinaryOperator<Integer> add = (a, b) -> a + b;

1.?Lambda表達式的基本結構

 

(參數列表) -> {方法體}

參數列表:就是你要傳給這個函數的值,比如?(a, b)。?方法體:就是具體的操作,像?a + b,它決定了這個表達式要做什么。

2.?Lambda表達式帶來的便利

  • 簡潔性:減少了冗長的代碼,像上面的加法例子,傳統方法需要很多代碼,而Lambda表達式只需要一行。
  • 可讀性:代碼變得簡潔,其他人閱讀起來更容易理解。
  • 函數式編程:讓你可以像使用“工具”一樣去操作代碼,提高了代碼的靈活性。

3.?實際應用場景

比如,Lambda 在?Java 8 的流式操作中,允許你通過一種更加直觀的方式來處理集合數據,像是篩選、映射等。

 

List<String> names = Arrays.asList("Alice", "Bob", "Charlie"); names.stream() .filter(name -> name.startsWith("A")) // 用Lambda表達式過濾 .forEach(System.out::println); // 輸出符合條件的元素

看!簡單的幾行代碼就搞定了原本復雜的過濾和遍歷操作,Lambda大大提高了代碼的簡潔度和效率。


Lambda表達式是Java 8引入的一種新的語法特性,它主要目的是實現函數式編程風格,使得代碼更加簡潔、可讀性更高,并且能夠輕松地處理一些常見的操作,特別是在集合框架和并行處理方面。

Lambda表達式的基本語法形式如下:

 

(參數) -> {表達式}

核心特點:
  • 簡潔性:Lambda允許我們直接在需要的地方傳遞行為(函數),無需冗長的匿名類或方法定義。
  • 函數式接口:Lambda表達式的目標是簡化實現函數式接口(僅有一個抽象方法的接口)的方法體,通常用于回調、事件監聽等場景。
  • 延遲計算與更強大的集合操作:與?Stream API?配合使用時,Lambda表達式能夠高效地進行集合操作,比如篩選、排序、映射等,且具有支持并行流的優勢。
應用場景:
  1. 集合操作:Java 8 引入的?Stream API,使得使用Lambda表達式可以進行過濾、映射、排序等操作,大大提高了代碼的簡潔性。
  2. 事件監聽:Lambda常用于回調或事件處理中,通過簡化代碼提高可維護性。

總的來說,Lambda表達式不僅僅是為了簡化代碼,它還提升了Java編程語言的表達能力,增強了函數式編程的特性,尤其在處理集合和并行處理時表現得尤為突出。

Java中的Optional類是什么?為什么需要它? (考點:Java Optional類及其必要性) 【中等】

簡要回答
  1. Optional類的定義
    • 包裝類:將可能為?null?的值封裝成?Optional?對象(如?Optional<String>)。
    • 明確空值意圖:通過方法名(如?isPresent()orElse())顯式表達“值可能不存在”的邏輯。
  2. Optional類的作用
    • 避免?NullPointerException:強制開發者主動處理空值,減少運行時錯誤。
    • 代碼更簡潔:鏈式調用替代多層?if (obj != null)?判空。
    • API 設計更清晰:方法簽名中明確表示返回值可能為空(如?Optional<User> findUser())。

談談JDK8新特性。(考點:JDK8新特性)【困難】

JDK 8 是 Java 的一次重要升級,引入了多個新特性,主要用于提升語言的表達能力、增強代碼的簡潔性和提高開發效率。

1.?Lambda表達式:

Lambda 表達式允許以簡潔的方式傳遞行為,它使得 Java 編程更具函數式編程風格。Lambda 表達式的基本語法是?(parameter) -> expression,它為 Java 提供了匿名方法的替代,常常用于簡化集合操作和并行流處理等。

 

List<String> list = Arrays.asList("apple", "banana", "cherry"); list.forEach(s -> System.out.println(s)); // 使用Lambda表達式簡化代碼

2.?Stream API:

Stream API 是對集合的增強,支持聲明式地進行數據處理,包括排序、過濾、映射等操作。Stream 的操作支持鏈式調用,并且可以通過?parallelStream()?輕松實現并行處理,提高大數據量處理的效率。

 

List<String> list = Arrays.asList("apple", "banana", "cherry"); long count = list.stream() .filter(s -> s.startsWith("a")) .count();

3.?Optional類:

Optional 類是為了避免 NullPointerException 的發生,作為一種容器來表示可能存在或者不存在的值。它為值存在與否提供了明確的語義,并提供了一些方法,如?orElse?和?ifPresent?來處理空值問題。

 

Optional<String> optional = Optional.ofNullable("Hello"); optional.ifPresent(s -> System.out.println(s)); // 如果值存在,打印

4.?新的日期時間API:

JDK 8 引入了新的?java.time?包(包括?LocalDate,?LocalTime,?LocalDateTime?等類),大大簡化了日期和時間的處理。新的 API 解決了老舊的?Date?類和?Calendar?類存在的線程不安全、復雜性等問題。

 

LocalDate date = LocalDate.of(2023, 10, 1); LocalDate today = LocalDate.now();

5.?默認方法(Default Methods):

默認方法是接口的一個新特性,允許在接口中定義有實現的方法,這樣接口新增方法時不會影響到實現該接口的類,減少了代碼的侵入性。

 

interface MyInterface { default void show() { System.out.println("Default method"); } } class MyClass implements MyInterface { // 無需實現show方法 }

6.?函數式接口和@FunctionalInterface

JDK 8 引入了?函數式接口?的概念,旨在支持 Lambda 表達式。函數式接口是只包含一個抽象方法的接口,可以使用?@FunctionalInterface?注解來標識,常用于與 Lambda 表達式結合使用。

 

@FunctionalInterface interface MyFunction { void apply(); }

7.?方法引用(Method References):

方法引用是 Lambda 表達式的簡化形式,允許直接引用類中的方法,增強了代碼的可讀性和簡潔性。

 

List<String> list = Arrays.asList("apple", "banana", "cherry"); list.forEach(System.out::println); // 方法引用,簡化代碼

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

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

相關文章

RabbitMQ:SpringAMQP Fanout Exchange(扇型交換機)

目錄一、案例需求二、基礎配置三、代碼實現扇形交換機也叫做廣播交換機&#xff0c;通過交換機將消息發送給所有的隊列。 生產者源碼 消費者源碼 一、案例需求 在RabbitMQ控制臺中&#xff0c;聲明隊列fanout.queue1和fanout.queue2。在RabbitMQ控制臺中&#xff0c;聲明交換…

深度解析DeepSeek V3.1 :6850 億參數開源模型如何以 71.6% 編碼得分、68 倍成本優勢重構全球 AI 競爭格局

深度解析DeepSeek V3.1 &#xff1a;6850 億參數開源模型如何以 71.6% 編碼得分、68 倍成本優勢重構全球 AI 競爭格局當DeepSeek悄然將其 6850 億參數的 V3.1 模型上傳至 Hugging Face 平臺時&#xff0c;這個看似低調的舉動卻在全球 AI 領域投下了一顆 “深水炸彈”。這款融合…

Java 大視界 -- Java 大數據在智能安防視頻監控系統中的視頻內容理解與智能預警升級(401)

Java 大視界 -- Java 大數據在智能安防視頻監控系統中的視頻內容理解與智能預警升級&#xff08;401&#xff09;引言&#xff1a;正文&#xff1a;一、傳統安防監控的 “三重困局”&#xff1a;看不全、看不懂、反應慢1.1 人工盯屏 “力不從心”1.1.1 攝像頭密度與人力的矛盾1…

ansible playbook 實戰案例roles | 實現基于node_exporter的節點部署

文章目錄一、核心功能描述二、roles內容2.1 文件結構2.2 主配置文件2.3 tasks文件內容2.4 vars文件內容免費個人運維知識庫&#xff0c;歡迎您的訂閱&#xff1a;literator_ray.flowus.cn 一、核心功能描述 這個 Ansible Role 的核心功能是&#xff1a;?自動化部署 Prometheu…

.NET Core MongoDB 查詢數據異常及解決

.NET Core 查詢 MongoDB異常消息Element _class does not match any field or property of class WebApiServer.Model.Enity.Ypxxx.圖中寫的修改實際是查詢分頁出現的異常&#xff0c;異常是查詢轉換為List<T>時出現的&#xff1a; 這個錯誤通常發生在MongoDB文檔中包含的…

政策技術雙輪驅動智慧燈桿市場擴容,塔能科技破解行業痛點

在新型城市基礎設施建設不斷加速&#xff0c;以及“雙碳”戰略持續深化這樣的雙重背景之下&#xff0c;智慧燈桿市場恰恰迎來了政策紅利得以釋放、技術出現迭代突破并且需求在持續升級的極為難得的黃金發展時期。智慧城市建設 的核心承載從國家層面所開展的全域智能化改造規劃&…

JetBrains Mono字體

好的,我們來詳細解析一下 JetBrains Mono 的 8 種主要字體風格(實際上官方提供了 9 種字重,但通常我們討論其核心風格)及其區別。 這些風格的區別主要體現在兩個方面:字重 和 字形。 核心區別:字重 字重就是字體的粗細程度。JetBrains Mono 提供了從細到極粗的多種選擇…

MySQL 分頁查詢:用 LIMIT 高效處理大量數據

MySQL 分頁查詢&#xff1a;用 LIMIT 高效處理大量數據 在實際開發中&#xff0c;當查詢結果包含成百上千條記錄時&#xff0c;一次性展示所有數據會導致加載緩慢、用戶體驗差。分頁查詢能將數據分段展示&#xff0c;既減輕服務器壓力&#xff0c;又方便用戶瀏覽。MySQL 中通過…

GraphQL 與 REST 在微服務架構中的對比與設計實踐

GraphQL 與 REST 在微服務架構中的對比與設計實踐 隨著微服務架構的普及&#xff0c;API 設計已經成為系統性能、可維護性和開發效率的關鍵。REST&#xff08;Representational State Transfer&#xff09;作為傳統的無狀態架構風格&#xff0c;擁有簡單、成熟的生態&#xff1…

WebSocket通信:sockjs與stomp.js的完美搭檔

sockjs 和 stomp.js 是 WebSocket 通信場景中功能互補的兩個庫,它們的結合能解決實際開發中的關鍵問題,因此常被一起使用。 1. 兩者的核心作用與聯系 sockjs:是一個 傳輸層庫,解決的是“如何在各種環境下建立可靠的雙向通信連接”的問題。 WebSocket 協議本身存在兼容性限…

元宇宙的網絡基礎設施:5G 與 6G 的關鍵作用

1 5G 技術對元宇宙的支撐作用1.1 高帶寬保障沉浸式內容傳輸5G 技術的超大帶寬特性為元宇宙的海量數據傳輸提供了基礎支撐。元宇宙中的沉浸式體驗依賴于高清視頻、3D 模型、實時交互數據等大容量內容&#xff0c;普通 4G 網絡的帶寬&#xff08;約 100Mbps&#xff09;難以滿足需…

【39頁PPT】大模型DeepSeek在運維場景中的應用(附下載方式)

篇幅所限&#xff0c;本文只提供部分資料內容&#xff0c;完整資料請看下面鏈接 https://download.csdn.net/download/2501_92808811/91694206 資料解讀&#xff1a;【39頁PPT】大模型DeepSeek在運維場景中的應用 詳細資料請看本解讀文章的最后內容。大模型技術在當下的科技領…

集成電路學習:什么是Template Matching模版匹配

Template Matching:模版匹配 Template Matching(模版匹配)是一種在圖像處理中廣泛使用的技術,主要用于在一幅大圖像中搜尋與給定模板圖像最相似的區域。以下是對模版匹配的詳細介紹: 一、定義與原理 模版匹配是一種最原始、最基本的模式識別方法,它通過比較模板圖…

Python零基礎30天速通(小白定制視頻教程版)

概述 還在為 Python 入門犯難&#xff1f;怕枯燥的代碼讓學習沒動力&#xff1f;別擔心&#xff01;專為零基礎小白打造的 Python 30 天速通課程 重磅登場&#xff5e;視頻資料&#xff1a;https://pan.quark.cn/s/2931af88b68a 這門課從 Python 核心基礎入手 基礎語法全覆蓋&a…

leetcode1004 最大連續1的個數

一、題目描述二、解題思路采用雙指針的方法來解決這個問題。定義變量countzero來記錄窗口內0的數量&#xff0c;當countzero大于k時&#xff0c;窗口收縮&#xff0c;left移動到窗口內第一個0的后面一個位置&#xff0c;將這個彈出來的“翻轉機會”讓給right指向的數&#xff0…

超越按鈕的操控:語音喚醒的無人機群體意識

引言&#xff1a;無人機技術發展的新方向近年來&#xff0c;無人機技術已經從單純的飛行平臺逐步發展為集感知、決策、執行于一體的智能系統。隨著人工智能技術的快速發展&#xff0c;特別是大語言模型和計算機視覺技術的突破&#xff0c;無人機正迎來新一輪智能化升級的機遇。…

【OpenGL】LearnOpenGL學習筆記12 - 網格模型繪制

上接&#xff1a;https://blog.csdn.net/weixin_44506615/article/details/150465200?spm1001.2014.3001.5501 完整代碼&#xff1a;https://gitee.com/Duo1J/learn-open-gl 接下來我們通過加載模型文件的方式來導入我們要渲染的模型&#xff0c;取代之前的硬編碼頂點的箱子 …

leetcode_238 除自身以外的數組乘積

1. 題意 除了自身外的乘積&#xff0c;題目要求不能用除法做。 2. 題解 不用除法做&#xff0c;那就用前后綴分解的方法做。 時間復雜度O(n)O(n)O(n) 兩個數組記錄前后綴乘積 class Solution { public:vector<int> productExceptSelf(vector<int>& nums) {int …

從0開始玩轉soarm101 下篇

上篇我們從0開始構建了基本的環境&#xff0c;這篇我們繼續后續的標定&#xff0c;遙操作&#xff0c;錄制數據&#xff0c;上傳&#xff0c;訓練。 環境&#xff1a;顯卡技嘉的5060&#xff0c;cpui5-13490f&#xff0c;主板技嘉b760m gaming&#xff0c;雙系統ubuntu2204&am…

學習設計模式《二十三》——橋接模式

一、基礎概念 橋接模式的本質是【分離抽象和實現】。 橋接模式的定義&#xff1a;將抽象部分與它的實現部分分離&#xff0c;使它們都可以獨立地變化。 認識橋接模式序號認識橋接模式說明1什么是橋接通俗點說就是在不同的東西之間搭一個橋&#xff0c;讓它們能夠連接起來&a…