Java值得使用Lambda的8個場景合集
前言
可能對不少人來說,Lambda顯得陌生又復雜,覺得Lambda會導致代碼可讀性下降,詬病Lambda語法,甚至排斥。
其實所有的這些問題,在嘗試并熟悉后,可能都不是問題。
對Lambda持懷疑態(tài)度的人,也許可以采取漸進式使用Lambda的策略。在一些簡單和低風險的場景下先嘗試使用Lambda,逐漸增加Lambda表達式的使用頻率和范圍。
畢竟2023年了,JDK都出了那么多新版本,是時候試試Lambda了!
耐心看完,你一定有所收獲。
1. 對集合進行遍歷和篩選
使用Lambda表達式結合Stream API可以在更少的代碼量下實現(xiàn)集合的遍歷和篩選,更加簡潔和易讀。
原來的寫法:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
for (Integer num : numbers) {
if (num % 2 == 0) {
System.out.println(num);
}
}優(yōu)化的Lambda寫法:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.stream()
.filter(num -> num % 2 == 0)
.forEach(System.out::println);2. 對集合元素進行排序
使用Lambda表達式可以將排序邏輯以更緊湊的形式傳遞給sort方法,使代碼更加簡潔。
原來的寫法:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
Collections.sort(names, new Comparator<String>() {
public int compare(String name1, String name2) {
return name1.compareTo(name2);
}
});優(yōu)化的Lambda寫法:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
names.sort((name1, name2) -> name1.compareTo(name2));3. 集合的聚合操作
Lambda表達式結合Stream API可以更優(yōu)雅地實現(xiàn)對集合元素的聚合操作,例如求和、求平均值等。
原來的寫法:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = 0;
for (Integer num : numbers) {
sum += num;
}優(yōu)化的Lambda寫法:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.reduce(0, Integer::sum);4. 條件過濾和默認值設置
使用Lambda的Optional類可以更加優(yōu)雅地處理條件過濾和默認值設置的邏輯。
原來的寫法:
String name = "Alice";
if (name != null && name.length() > 0) {
System.out.println("Hello, " + name);
} else {
System.out.println("Hello, Stranger");
}Lambda寫法:
String name = "Alice";
name = Optional.ofNullable(name)
.filter(n -> n.length() > 0)
.orElse("Stranger");
System.out.println("Hello, " + name);5. 簡化匿名內部類
可以簡化代碼,同時提高代碼可讀性。
舉個創(chuàng)建Thread的例子,傳統(tǒng)方式使用匿名內部類來實現(xiàn)線程,語法較為冗長,而Lambda表達式可以以更簡潔的方式達到相同的效果。
原來的寫法:
new Thread(new Runnable() {
public void run() {
System.out.println("Thread is running.");
}
}).start();Lambda寫法:
new Thread(() -> System.out.println("Thread is running.")).start();
new Thread(() -> {
// 做點什么
}).start();這種寫法也常用于簡化回調函數(shù),再舉個例子:
假設我們有一個簡單的接口叫做Calculator,它定義了一個單一的方法calculate(int a, int b)來執(zhí)行數(shù)學運算:
// @FunctionalInterface: 標識接口是函數(shù)式接口,只包含一個抽象方法,從而能夠使用Lambda表達式來實現(xiàn)接口的實例化
@FunctionalInterface
interface Calculator {
int calculate(int a, int b);
}現(xiàn)在,讓我們創(chuàng)建一個名為CallbackExample的類。該類有一個名為operate的方法,它接受兩個整數(shù)和一個Calculator接口作為參數(shù)。該方法將使用提供的Calculator接口執(zhí)行計算并返回結果:
public class CallbackExample {
public static int operate(int a, int b, Calculator calculator) {
return calculator.calculate(a, b);
}
public static void main(String[] args) {
int num1 = 10;
int num2 = 5;
// 使用Lambda作為回調
int sum = operate(num1, num2, (x, y) -> x + y);
int difference = operate(num1, num2, (x, y) -> x - y);
int product = operate(num1, num2, (x, y) -> x * y);
int division = operate(num1, num2, (x, y) -> x / y);
System.out.println("Sum: " + sum);
System.out.println("Difference: " + difference);
System.out.println("Product: " + product);
System.out.println("Division: " + division);
}
}通過在方法調用中直接定義計算的行為,我們不再需要為每個運算創(chuàng)建多個實現(xiàn)Calculator接口的類,使得代碼更加簡潔和易讀
6. 集合元素的轉換
使用Lambda的map方法可以更優(yōu)雅地對集合元素進行轉換,提高代碼的可讀性
原來的寫法:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> uppercaseNames = new ArrayList<>();
for (String name : names) {
uppercaseNames.add(name.toUpperCase());
}Lambda寫法:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> uppercaseNames = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());7. 對集合進行分組和統(tǒng)計
以更緊湊的形式傳遞分組和統(tǒng)計的邏輯,避免了繁瑣的匿名內部類的聲明和實現(xiàn)。
通過groupingBy、counting、summingInt等方法,使得代碼更加流暢、直觀且優(yōu)雅。
傳統(tǒng)寫法:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Amy", "Diana");
// 對名字長度進行分組
Map<Integer, List<String>> namesByLength = new HashMap<>();
for (String name : names) {
int length = name.length();
if (!namesByLength.containsKey(length)) {
namesByLength.put(length, new ArrayList<>());
}
namesByLength.get(length).add(name);
}
System.out.println("Names grouped by length: " + namesByLength);
// 統(tǒng)計名字中包含字母'A'的個數(shù)
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Amy", "Diana");
int namesWithA = 0;
for (String name : names) {
if (name.contains("A")) {
namesWithA++;
}
}
System.out.println("Number of names containing 'A': " + namesWithA);Lambda寫法:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Amy", "Diana");
// 使用Lambda表達式對名字長度進行分組
Map<Integer, List<String>> namesByLength = names.stream()
.collect(Collectors.groupingBy(String::length));
System.out.println("Names grouped by length: " + namesByLength);
// 使用Lambda表達式統(tǒng)計名字中包含字母'A'的個數(shù)
long namesWithA = names.stream()
.filter(name -> name.contains("A"))
.count();
System.out.println("Number of names containing 'A': " + namesWithA);8. 對大數(shù)據(jù)量集合的并行處理
當集合的數(shù)據(jù)量很大時,通過Lambda結合Stream API可以方便地進行并行處理,充分利用多核處理器的優(yōu)勢,提高程序的執(zhí)行效率。
假設我們有一個包含一百萬個整數(shù)的列表,我們想要計算這些整數(shù)的平均值:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
public class ParallelStreamExample {
public static void main(String[] args) {
// 創(chuàng)建一個包含一百萬個隨機整數(shù)的列表
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
numbers.add(ThreadLocalRandom.current().nextInt(100));
}
// 順序流的處理
long startTimeSeq = System.currentTimeMillis();
double averageSequential = numbers.stream()
.mapToInt(Integer::intValue)
.average()
.getAsDouble();
long endTimeSeq = System.currentTimeMillis();
System.out.println("Sequential Average: " + averageSequential);
System.out.println("Time taken (Sequential): " + (endTimeSeq - startTimeSeq) + "ms");
// 并行流的處理
long startTimePar = System.currentTimeMillis();
double averageParallel = numbers.parallelStream()
.mapToInt(Integer::intValue)
.average()
.getAsDouble();
long endTimePar = System.currentTimeMillis();
System.out.println("Parallel Average: " + averageParallel);
System.out.println("Time taken (Parallel): " + (endTimePar - startTimePar) + "ms");
}
}分別使用順序流和并行流來計算列表中整數(shù)的平均值:
- 順序流:通過stream()方法獲取流,使用mapToInt將Integer轉換為int,然后使用average()方法計算平均值
- 并行流:使用parallelStream()方法獲取并行流,其他步驟與順序流相同
查看輸出結果:
Sequential Average: 49.517461
Time taken (Sequential): 10ms
Parallel Average: 49.517461
Time taken (Parallel): 3ms
可以看出,順序流和并行流得到了相同的平均值,但并行流的處理時間明顯少于順序流。因為并行流能夠將任務拆分成多個小任務,并在多個處理器核心上同時執(zhí)行這些任務。
當然并行流也有缺點:
- 對于較小的數(shù)據(jù)集,可能并行流更慢
- 數(shù)據(jù)處理本身的開銷較大,比如復雜計算、大量IO操作、網絡通信等,可能并行流更慢
- 可能引發(fā)線程安全問題
收尾
Lambda的使用場景遠不止這些,在多線程、文件操作等場景中也都能靈活運用,一旦熟悉后可以讓代碼更簡潔,實現(xiàn)精準而優(yōu)雅的編程。
寫代碼時,改變偏見需要我們勇于嘗試和付諸行動。有時候,我們可能會對某種編程語言、框架或設計模式持有偏見,認為它們不適合或不好用。但是,只有嘗試去了解和實踐,我們才能真正知道它們的優(yōu)點和缺點。
當我們愿意打破舊有的觀念,敢于嘗試新的技術和方法時,我們就有機會發(fā)現(xiàn)新的可能性和解決問題的新途徑。不要害怕失敗或犯錯,因為每一次嘗試都是我們成長和進步的機會。
只要我們保持開放的心態(tài),不斷學習和嘗試,我們就能夠超越偏見,創(chuàng)造出更優(yōu)秀的代碼和解決方案。
所以,讓我們在編程的路上,積極地去挑戰(zhàn)和改變偏見。用行動去證明,只有不斷地嘗試,我們才能取得更大的進步和成功。讓我們敢于邁出第一步,勇往直前,一同創(chuàng)造出更美好的編程世界!
以上就是Java值得使用Lambda的8個場景合集的詳細內容,更多關于Java Lambda的資料請關注腳本之家其它相關文章!
相關文章
SpringBoot Session接口驗證實現(xiàn)流程詳解
這篇文章主要介紹了SpringBoot+Session實現(xiàn)接口驗證(過濾器+攔截器)文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-09-09
java書店系統(tǒng)畢業(yè)設計 用戶模塊(2)
這篇文章主要介紹了java書店系統(tǒng)畢業(yè)設計,第二步系統(tǒng)總體設計,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-10-10
Java中的clone方法詳解_動力節(jié)點Java學院整理
clone顧名思義就是復制, 在Java語言中, clone方法被對象調用,所以會復制對象。下面通過本文給大家介紹java中的clone方法,感興趣的朋友一起看看吧2017-06-06

