【Java】Effective Lambda Expressions in Java
1原文
Effective Lambda Expressions in Java | by Bubu Tripathy | Medium
2Introductory
Lambda expressions were introduced in Java 8 to allow functional programming in Java. They are a concise way to express functions that can be used as data and provide a more functional approach to programming. Lambda expressions can be used in a variety of ways, from simple expressions to complex functions. In this article, we will discuss 20 best practices of using lambda expressions in Java with examples for each.
Lambda 表達(dá)式在 Java 8 中引入,允許在 Java 中進(jìn)行函數(shù)式編程。Lambda表達(dá)式是表達(dá)可用作數(shù)據(jù)的函數(shù)的一種簡(jiǎn)潔方式,并為編程提供了一種功能性更強(qiáng)的方法。Lambda表達(dá)式的使用方式多種多樣,從簡(jiǎn)單的表達(dá)式到復(fù)雜的函數(shù)。在本文中,我們將討論在Java中使用lambda表達(dá)式的20個(gè)最佳實(shí)踐,并分別舉例說(shuō)明。
3Use Lambda expressions to create functional Interfaces 使用Lambda表達(dá)式創(chuàng)建功能接口
A functional interface is an interface that contains a single abstract method. Functional interfaces are used extensively in Java to represent functions and Lambdas.
功能接口是一個(gè)包含單個(gè)抽象方法的接口。功能接口在Java中廣泛用于表示函數(shù)和Lambdas。
When using Lambda expressions to create functional interfaces, the Lambda expression is used to define the implementation of the abstract method. The Lambda expression takes the same parameters as the abstract method, and returns a value that represents the result of the method.
當(dāng)時(shí)用Lambda 表達(dá)式創(chuàng)建功能接口的時(shí)候,Lambda 表達(dá)式用于定義抽象方法實(shí)現(xiàn)。Lambda 表達(dá)式接受和抽象方法相同的參數(shù),并且返回代表方法結(jié)果的值。
Here is an example of using Lambda expressions to create a functional interface for a calculator:
下面是使用Lambda 表達(dá)式來(lái)創(chuàng)建功能接口計(jì)算器的案例:
??
interface?Calculator?{??
????int?calculate(int?a,?int?b);??
}??
??
public?class?LambdaDemo?{??
????public?static?void?main(String[]?args)?{??
????????Calculator?add?=?(a,?b)?->?a?+?b;??
????????Calculator?subtract?=?(a,?b)?->?a?-?b;??
??
????????System.out.println("10?+?5?=?"?+?add.calculate(10,?5));??
????????System.out.println("10?-?5?=?"?+?subtract.calculate(10,?5));??
????}??
}
In this example, we are using a Lambda expression to define the implementation of the calculate()
method of the Calculator interface. The calculate()
method takes two integer values as input (a and b), and returns an integer value representing the result of the calculation.
在這個(gè)例子中,我們使用Lambda 表達(dá)式定義Calculator 接口的 calculate()
方法的實(shí)現(xiàn)。calculate()
方法接收兩個(gè)整型參數(shù)作為輸入(a 和 b),并且返回一個(gè)整型結(jié)果代表計(jì)算結(jié)果
Note that in this example, we are using the?@FunctionalInterface?annotation to indicate that the Calculator interface is a functional interface. This annotation is not strictly necessary, but it can help to clarify the intent of the interface.
注意在這個(gè)例子中我們使用了 @FunctionalInterface ?注解指定在 Calculator 接口的接口方法上面。這個(gè)注解嚴(yán)格上來(lái)來(lái)說(shuō)是非必要的, 但它有助于明確界面的意圖。
4Use the right syntax for Lambda Expressions 為L(zhǎng)ambda表達(dá)式使用正確的語(yǔ)法
When using Lambda expressions in Java, it is important to use the correct syntax for defining and using them. The syntax of a Lambda expression consists of three parts: the parameter list, the arrow operator, and the body.
在Java中使用Lambda表達(dá)式, 使用正確的語(yǔ)法定義和使用它們非常重要的。Lambda表達(dá)式的語(yǔ)法由三部分組成:參數(shù)列表、箭頭操作符和主體。
The parameter list [specifies] the input parameters that the Lambda expression will take. If there are no parameters, an empty parameter list must still be specified, as shown here:
參數(shù)列表指定了Lambda表達(dá)式將使用的輸入?yún)?shù),如果沒(méi)有任何參數(shù),一個(gè)空的參數(shù)化列表依然必須被指定,它的表現(xiàn)形式如下:
()?->?System.out.println("Hello,?world!");
The arrow operator separates the parameter list from the body of the Lambda expression. The arrow operator can be either a hyphen and greater-than symbol (->), or the word “goes to” written as an equals sign followed by a greater-than symbol (=>).
箭頭操作符將參數(shù)列表與Lambda表達(dá)式的主體分開(kāi),箭頭運(yùn)算符可以是-
字符和大于號(hào)組合(->),也可以是等號(hào)和大于號(hào)組合(=>)。
//?hyphen?and?greater-than?symbol??
x?->?x?*?x??//?equals?sign?followed?by?a?greater-than?symbol??
(x,?y)?=>?x?+?y
The body of the Lambda expression specifies the behavior of the expression. The body can be a single expression, or a block of statements enclosed in braces. If the body is a single expression, the braces are optional.
Lambda 表達(dá)式的主體指定表達(dá)式的行為,主題可以是一個(gè)單獨(dú)的表達(dá)式,也可以是用大括號(hào)括起來(lái)的語(yǔ)句塊,如果主體是單個(gè)表達(dá)式,則大括號(hào)是可選的。
函數(shù)表達(dá)式
//?single?expression??
x?->?x?*?x??
語(yǔ)句塊
//?block?of?statements??
(x,?y)?->?{??
????int?sum?=?x?+?y;??
????System.out.println("The?sum?is:?"?+?sum);??
}
It is also important to use the correct type for Lambda expressions when they are assigned to variables or parameters. When a Lambda expression is assigned to a variable or parameter, the type of the variable or parameter must be a functional interface that is compatible with the Lambda expression.
當(dāng)Lambda表達(dá)式設(shè)置變量或者參數(shù)的時(shí)候,使用正確的類型也是十分重要。當(dāng)一個(gè)Lambda 表達(dá)式設(shè)置了變量或者參數(shù),變量或參數(shù)必須是與Lambda表達(dá)式兼容的功能接口。
For example, the following Lambda expression:
比如下面這個(gè)函數(shù)表達(dá)式的例子:
(x,?y)?->?x?+?y
can be assigned to a variable of type?IntBinaryOperator:
這里只能夠設(shè)置變量類型為 IntBinaryOperator :
IntBinaryOperator?add?=?(x,?y)?->?x?+?y;
5Use Lambda expressions to implement Functional Programming 使用 Lambda 表達(dá)式實(shí)現(xiàn)函數(shù)式編程
Functional programming is a programming paradigm that emphasizes the use of functions and functional composition to solve problems. In Java, Lambda expressions can be used to implement functional programming by creating and using functions as first-class objects.
函數(shù)式編程是一種編程范式,強(qiáng)調(diào)使用函數(shù)和函數(shù)組合來(lái)解決問(wèn)題。在Java中,可以使用Lambda表達(dá)式來(lái)實(shí)現(xiàn)函數(shù)式編程,將函數(shù)作為頭等對(duì)象來(lái)創(chuàng)建和使用。
Functions in functional programming are defined by their behavior, rather than their implementation. This means that a function can be treated as an object, and passed around as a parameter or returned as a result. This is where Lambda expressions come in — they allow us to define functions as expressions, and pass them around as objects.
函數(shù)式編程當(dāng)中行為是通過(guò)具體行為而不是實(shí)現(xiàn)定義的,也就是說(shuō)函數(shù)可以是對(duì)象,并且把參數(shù)傳遞作為結(jié)果返回。Lambda表達(dá)式的強(qiáng)大之處就在于此,可以把函數(shù)作為表達(dá)式,并且把對(duì)應(yīng)的對(duì)象進(jìn)行傳遞。
Here is an example of using Lambda expressions to implement functional programming in Java:
下面是使用Lambda表達(dá)式使Java實(shí)現(xiàn)函數(shù)式編程。
public?class?FunctionalProgrammingDemo?{??
????public?static?void?main(String[]?args)?{??
????????List<Integer>?numbers?=?Arrays.asList(1,?2,?3,?4,?5);??
????????numbers.stream()??
????????????.filter(n?->?n?%?2?==?0)??
????????????.map(n?->?n?*?n)??
????????????.forEach(System.out::println);??
????}??
}
In this example, we are using Lambda expressions to implement functional programming in Java. The code first creates a list of integers, and then uses a stream to process the list using functional operations.
在本示例中,我們使用Lambda表達(dá)式在Java中實(shí)現(xiàn)函數(shù)式編程。代碼首先創(chuàng)建一個(gè)整數(shù)列表,然后使用stream
的函數(shù)式操作來(lái)處理該列表。
The filter() operation uses a Lambda expression to define a predicate that filters out all odd numbers from the list. The map() operation uses another Lambda expression to define a function that squares each even number in the list. Finally, the?forEach()?operation uses a method reference to print each squared even number to the console.
filter()
操作使用 Lambda 表達(dá)式定義一個(gè)predicate
,predicate
中定義了過(guò)濾列表所有奇數(shù)的操作,map()
操作使用另一個(gè)Lambda表達(dá)式定義一個(gè)函數(shù),該函數(shù)將列表中的每個(gè)元素求平方,最后使用 forEach 的方式,把每個(gè)處理之后的數(shù)據(jù)打印出來(lái)。
By using Lambda expressions to implement functional programming, you can create more expressive and modular code, and solve problems in a more concise and efficient way. Lambda expressions provide a powerful and flexible way to implement functional programming in Java and are a key feature of the Stream API in Java 8 and later versions.
使用函數(shù)表達(dá)式實(shí)現(xiàn)函數(shù)式編程,你可以創(chuàng)建更多更具表現(xiàn)力和模塊化的代碼,解決問(wèn)你也會(huì)更加的簡(jiǎn)單高效,Lambda表達(dá)his提供一個(gè)強(qiáng)大并且流暢的方法在Java中實(shí)現(xiàn)函數(shù)式編程,這是Java 8及更高版本中流API的關(guān)鍵特性。
6Use Lambda expressions to create Anonymous Classes 使用 Lambda 表達(dá)式創(chuàng)建匿名類
Anonymous classes are often used in Java to create objects with a specific behavior, such as event listeners or runnable tasks.
在Java中,匿名類通常用于創(chuàng)建具有特定行為的對(duì)象,如事件監(jiān)聽(tīng)器或可運(yùn)行任務(wù)。
Lambda expressions can be used to create anonymous classes in Java. When using Lambda expressions to create anonymous classes, the Lambda expression is used to define the behavior of the anonymous class.
Lambda表達(dá)式可用于在Java中創(chuàng)建匿名類。使用Lambda表達(dá)式創(chuàng)建匿名類時(shí),Lambda表達(dá)式用于定義匿名類的行為。
Here is an example of using Lambda expressions to create an anonymous class that implements the Runnable interface:
下面是一個(gè)使用Lambda表達(dá)式創(chuàng)建一個(gè)實(shí)現(xiàn)Runnable接口的匿名類的示例:
public?class?AnonymousClassDemo?{??
????public?static?void?main(String[]?args)?{??
????????Runnable?runnable?=?()?->?{??
????????????System.out.println("Hello?from?anonymous?class!");??
????????};??
????????Thread?thread?=?new?Thread(runnable);??
????????thread.start();??
????}??
}
In this example, we are using a Lambda expression to create an anonymous class that implements the Runnable interface. The code first defines a Lambda expression that simply prints a message to the console. This Lambda expression is then used to create an anonymous class that implements the Runnable interface. Finally, the anonymous class is passed to a Thread object and started.
在這個(gè)案例中,我們通過(guò)Lambda表達(dá)式創(chuàng)建Runnable的匿名類,代碼首先定義了一個(gè)Lambda表達(dá)式,該表達(dá)式簡(jiǎn)單地向控制臺(tái)打印一條消息。然后使用該Lambda表達(dá)式創(chuàng)建一個(gè)實(shí)現(xiàn)Runnable接口的匿名類。最后,匿名類被傳遞給Thread對(duì)象并啟動(dòng)。
Note that in this example, we are using a Lambda expression with a block of statements enclosed in braces. This is because the Runnable interface has a single abstract method, run(), that takes no arguments and returns no value. Therefore, the Lambda expression must define the behavior of the run() method using a block of statements.
請(qǐng)注意,在本示例中,我們使用的是一個(gè)Lambda表達(dá)式,其中的語(yǔ)句塊用大括號(hào)括起來(lái)。這是因?yàn)?*Runnable接口只有一個(gè)抽象方法run()**,它不需要參數(shù)也不返回值。因此,Lambda表達(dá)式必須使用語(yǔ)句塊來(lái)定義run()方法的行為。
7Use Lambda expressions to create Event Listeners 使用 Lambda 表達(dá)式創(chuàng)建事件監(jiān)聽(tīng)器
Event listeners are used in Java to handle events that occur in a user interface or other system. Events can include things like button clicks, mouse movements, and keyboard inputs.
Java中的事件監(jiān)聽(tīng)器用于處理用戶界面或其他系統(tǒng)中發(fā)生的事件。
事件包括按鈕點(diǎn)擊、鼠標(biāo)移動(dòng)和鍵盤(pán)輸入等。
When using Lambda expressions to implement event listeners, the Lambda expression is used to define the behavior that should be executed when the event occurs. The Lambda expression takes an event object as input, and performs some action based on the event.
當(dāng)我們使用Lambda表達(dá)式實(shí)現(xiàn)事件監(jiān)聽(tīng)器,通常需要用于定義事件發(fā)生時(shí)應(yīng)執(zhí)行的行為。Lambda表達(dá)式接收一個(gè)事件對(duì)象作為輸入,并且根據(jù)事件的執(zhí)行某些操作。
Here is an example of using Lambda expressions to implement an event listener for a button click:
下面是一個(gè)使用 Lambda 表達(dá)式實(shí)現(xiàn)按鈕點(diǎn)擊事件監(jiān)聽(tīng)器的示例:
public?class?ButtonDemo?{??
????public?static?void?main(String[]?args)?{??
????????JButton?button?=?new?JButton("Click?me!");??
????????button.addActionListener(event?->?System.out.println("Button?clicked!"));??
????????JFrame?frame?=?new?JFrame();??
????????frame.add(button);??
????????frame.pack();??
????????frame.setVisible(true);??
????}??
}
In this example, we are using a Lambda expression to define the behavior that should be executed when the button is clicked. The addActionListener() method of the JButton class takes a ActionListener object as input, which is implemented as a Lambda expression in this case. The Lambda expression simply prints a message to the console when the button is clicked.
在本示例中,我們使用Lambda表達(dá)式來(lái)定義點(diǎn)擊按鈕時(shí)應(yīng)執(zhí)行的行為。JButton類的addActionListener()方法將ActionListener對(duì)象作為輸入,在本例中以Lambda表達(dá)式的形式實(shí)現(xiàn)。當(dāng)按鈕被點(diǎn)擊時(shí),Lambda表達(dá)式簡(jiǎn)單地向控制臺(tái)打印一條消息。
Note that in this example, we are using the “arrow” notation (->) to separate the parameter list from the body of the Lambda expression. The parameter list consists of a single event object, which represents the button click event. The body of the Lambda expression simply prints a message to the console.
請(qǐng)注意,在本例中,我們使用了 "箭頭 "符號(hào) (->) 來(lái)分隔參數(shù)列表和 Lambda 表達(dá)式的主體。參數(shù)列表由單個(gè)字符串值組成,代表列表中的每個(gè)字符串。Lambda 表達(dá)式的主體只是將字符串打印到控制臺(tái)。
8Use Lambda expressions to Iterate over Collections 使用 Lambda 表達(dá)式遍歷集合
Iterating over collections is a common operation in Java, and Lambda expressions can be used to simplify and streamline this process. When using Lambda expressions to iterate over collections, the Lambda expression is used to define the behavior that should be executed for each element in the collection.
在 Java 中,遍歷集合是一種常見(jiàn)操作,而 Lambda 表達(dá)式可用于簡(jiǎn)化和精簡(jiǎn)這一過(guò)程。使用 Lambda 表達(dá)式遍歷集合時(shí),Lambda 表達(dá)式用于定義應(yīng)針對(duì)集合中的每個(gè)元素執(zhí)行的行為。
Here is an example of using Lambda expressions to iterate over a list of strings and print each string to the console:
下面是一個(gè)使用 Lambda 表達(dá)式遍歷字符串列表并將每個(gè)字符串打印到控制臺(tái)的示例:
List<String>?strings?=?Arrays.asList("apple",?"banana",?"cherry");??
strings.forEach(s?->?System.out.println(s));
In this example, we are using the forEach() method of the List interface to iterate over a list of strings. The forEach() method takes a Consumer object as input, which is implemented as a Lambda expression in this case. The Lambda expression simply prints each string to the console.
在本示例中,我們使用 List 接口的 forEach() 方法遍歷字符串列表。forEach()方法將Consumer對(duì)象作為輸入,在本例中以Lambda表達(dá)式的形式實(shí)現(xiàn)。Lambda 表達(dá)式簡(jiǎn)單地將每個(gè)字符串打印到控制臺(tái)。
Note that in this example, we are using the “arrow” notation (->) to separate the parameter list from the body of the Lambda expression. The parameter list consists of a single string value, which represents each string in the list. The body of the Lambda expression simply prints the string to the console.
請(qǐng)注意,在本例中,我們使用了 "箭頭 "符號(hào) (->) 來(lái)分隔參數(shù)列表和 Lambda 表達(dá)式的主體。參數(shù)列表由單個(gè)字符串值組成,代表列表中的每個(gè)字符串。Lambda 表達(dá)式的主體只是將字符串打印到控制臺(tái)。
Here is another example of using Lambda expressions to iterate over a map of key-value pairs and print each pair to the console:
下面是另一個(gè)使用 Lambda 表達(dá)式遍歷鍵值對(duì)映射并將每一對(duì)鍵值對(duì)打印到控制臺(tái)的示例:
Map<String,?Integer>?map?=?new?HashMap<>();??
map.put("apple",?1);??
map.put("banana",?2);??
map.put("cherry",?3);??map.forEach((k,?v)?->?System.out.println(k?+?"?->?"?+?v));
In this example, we are using the?forEach()?method of the Map interface to iterate over a map of key-value pairs. The forEach() method takes a?BiConsumer?object as input, which is implemented as a Lambda expression in this case. The Lambda expression takes two parameters, a key and a value, and simply prints each key-value pair to the console.
在本例中,我們使用 Map
接口的 forEach() 方法遍歷鍵值對(duì)映射。forEach()方法將 BiConsumer 對(duì)象作為輸入,在本例中是以 Lambda 表達(dá)式的形式實(shí)現(xiàn)的。
Lambda 表達(dá)式接收兩個(gè)參數(shù),一個(gè)鍵和一個(gè)值,并簡(jiǎn)單地將每個(gè)鍵值對(duì)打印到控制臺(tái)。
Note that in this example, we are using the “arrow” notation (->) to separate the parameter list from the body of the Lambda expression. The parameter list consists of two values, a key and a value, which represent each key-value pair in the map. The body of the Lambda expression simply prints the key-value pair to the console.
請(qǐng)注意,在這個(gè)示例中,我們使用了 "箭頭 "符號(hào) (->) 來(lái)分隔參數(shù)列表和 Lambda 表達(dá)式的主體。參數(shù)列表由兩個(gè)值(一個(gè) key 和一個(gè) value)組成,分別代表 map 中的每個(gè)鍵值對(duì)。Lambda 表達(dá)式的主體只是將鍵值對(duì)打印到控制臺(tái)。
9Use Lambda expressions to Filter Collections 使用 Lambda 表達(dá)式過(guò)濾集合
Filtering collections is a common operation in Java, and Lambda expressions can be used to simplify and streamline this process. When using Lambda expressions to filter collections, the Lambda expression is used to define a predicate that selects which elements in the collection should be included or excluded.
過(guò)濾集合是 Java 中的一種常見(jiàn)操作,而 Lambda 表達(dá)式可用于簡(jiǎn)化和精簡(jiǎn)這一過(guò)程。使用 Lambda 表達(dá)式過(guò)濾集合時(shí),Lambda 表達(dá)式用于定義一個(gè)謂詞,該謂詞用于選擇應(yīng)包含或排除集合中的哪些元素。
Here is an example of using Lambda expressions to filter a list of integers and create a new list that contains only the even numbers:
下面是一個(gè)使用 Lambda 表達(dá)式過(guò)濾整數(shù)列表并創(chuàng)建一個(gè)只包含偶數(shù)的新列表的示例:
List<Integer>?numbers?=?Arrays.asList(1,?2,?3,?4,?5,?6,?7,?8,?9,?10);??
List<Integer>?evenNumbers?=?numbers.stream()??
????????????????????????????????????.filter(n?->?n?%?2?==?0)??
????????????????????????????????????.collect(Collectors.toList());??
System.out.println(evenNumbers);
In this example, we are using the filter() method of the Stream interface to filter a list of integers. The filter() method takes a predicate as input, which is implemented as a Lambda expression in this case. The Lambda expression defines a predicate that tests whether a number is even or not by checking if its remainder is zero when divided by two.
在本例中,我們使用流接口的 filter() 方法過(guò)濾整數(shù)列表。filter() 方法將一個(gè)謂詞作為輸入,在本例中以 Lambda 表達(dá)式的形式實(shí)現(xiàn)。Lambda 表達(dá)式定義了一個(gè)謂詞,該謂詞通過(guò)檢查一個(gè)數(shù)字除以 2 后的余數(shù)是否為零來(lái)檢驗(yàn)該數(shù)字是否為偶數(shù)。
Note that in this example, we are using the “arrow” notation (->) to separate the parameter list from the body of the Lambda expression. The parameter list consists of a single integer value, which represents each element in the stream. The body of the Lambda expression is a boolean expression that defines the predicate.
請(qǐng)注意,在這個(gè)示例中,我們使用了 "箭頭 "符號(hào) (->) 來(lái)分隔參數(shù)列表和 Lambda 表達(dá)式的主體。參數(shù)列表由單個(gè)整數(shù)值組成,代表流中的每個(gè)元素。Lambda 表達(dá)式的主體是定義謂詞的布爾表達(dá)式。
The filtered elements are then collected into a new list using the collect() method of the Stream interface, which takes a Collector object as input. The Collector object in this case is the toList() method of the Collectors class, which creates a new list of the filtered elements.
然后,使用流接口的 collect() 方法將過(guò)濾后的元素收集到一個(gè)新的列表中,該方法將收集器對(duì)象作為輸入。本例中的收集器對(duì)象是收集器類的 toList() 方法,它將創(chuàng)建一個(gè)包含過(guò)濾元素的新列表。
10Use Lambda expressions to Sort Collections 使用 Lambda 表達(dá)式對(duì)集合進(jìn)行排序
Sorting is the process of arranging the elements of a collection in a specific order. In Java, collections can be sorted using the?sorted()?method of the Stream API.
排序是將集合中的元素按特定順序排列的過(guò)程。在Java中,可以使用流API的 sorted() 方法對(duì)集合進(jìn)行排序。
When using Lambda expressions to sort collections, the Lambda expression is used to define the?order?in which the elements should be sorted.
使用 Lambda 表達(dá)式對(duì)集合進(jìn)行排序時(shí),Lambda 表達(dá)式用于定義元素的排序順序。
The Lambda expression takes two elements from the collection as input, and returns an integer value indicating their relative order.
Lambda 表達(dá)式將集合中的兩個(gè)元素作為輸入,并返回一個(gè)整數(shù)值,表示它們的相對(duì)順序。
If the first element should come before the second element in the sorted collection, the Lambda expression returns a negative integer.
如果在排序集合中,第一個(gè)元素應(yīng)在第二個(gè)元素之前,則 Lambda 表達(dá)式會(huì)返回一個(gè)負(fù)整數(shù)。
If the first element should come after the second element, the Lambda expression returns a positive integer. If the two elements are equal, the Lambda expression returns zero.
如果第一個(gè)元素位于第二個(gè)元素之后,則 Lambda 表達(dá)式返回一個(gè)正整數(shù)。如果兩個(gè)元素相等,則 Lambda 表達(dá)式返回 0。
Here is an example of using Lambda expressions to sort a list of integers:
下面是一個(gè)使用 Lambda 表達(dá)式對(duì)整數(shù)列表進(jìn)行排序的示例:
List<Integer>?numbers?=?Arrays.asList(3,?1,?4,?1,?5,?9,?2,?6,?5,?3,?5);??
List<Integer>?sortedNumbers?=?numbers.stream().sorted().collect(Collectors.toList());
In this example, we are using a Lambda expression to sort the list of integers in ascending order. The sorted() method uses this Lambda expression to create a new stream that contains the elements of the original list in sorted order.
在這個(gè)示例中,我們使用 Lambda 表達(dá)式按升序?qū)φ麛?shù)列表進(jìn)行排序。
sorted()方法使用該Lambda表達(dá)式創(chuàng)建一個(gè)新的流,其中包含按排序順序排列的原始列表元素。
Note that in this example, we are not explicitly defining a Lambda expression for the sorted() method. This is because the default behavior of the sorted() method is to sort the elements in natural order. However, you can also provide a custom Lambda expression to the sorted() method to define a custom sort order.
請(qǐng)注意,在這個(gè)示例中,我們沒(méi)有為 sorted() 方法明確定義一個(gè) Lambda 表達(dá)式。這是因?yàn)?sorted() 方法的默認(rèn)行為是按自然順序?qū)υ剡M(jìn)行排序。
不過(guò),您也可以為 sorted() 方法提供自定義 Lambda 表達(dá)式,以定義自定義排序順序。
Here is an example of using a Lambda expression to sort a list of strings in descending order:
下面是一個(gè)使用 Lambda 表達(dá)式對(duì)字符串列表進(jìn)行降序排序的示例:
List<String>?words?=?Arrays.asList("apple",?"banana",?"cherry",?"date",?"elderberry");??
List<String>?sortedWords?=?words.stream().sorted((a,?b)?->?b.compareTo(a)).collect(Collectors.toList());
In this example, we are using a Lambda expression to sort the list of strings in descending order. The Lambda expression takes two strings as input, and returns the result of comparing the second string to the first string using the?compareTo()?method of the String class.
在本例中,我們使用 Lambda 表達(dá)式對(duì)字符串列表進(jìn)行降序排序。Lambda 表達(dá)式將兩個(gè)字符串作為輸入,并使用 String 類的 compareTo() 方法返回第二個(gè)字符串與第一個(gè)字符串的比較結(jié)果。
11Use Lambda expressions to Map Collections
Mapping is the process of transforming one collection into another. In Java, collections can be mapped using the map() method of the Stream API.
Map是將一個(gè)集合轉(zhuǎn)換成另一個(gè)集合的過(guò)程。在 Java 中,可以使用流 API 的 map() 方法對(duì)集合進(jìn)行映射。
When using Lambda expressions to map collections, the Lambda expression is used to define the transformation that should be applied to each element in the collection. The Lambda expression takes an element from the collection as input and returns a new value that represents the transformed element.
使用 Lambda 表達(dá)式映射集合時(shí),Lambda 表達(dá)式用于定義應(yīng)用于集合中每個(gè)元素的轉(zhuǎn)換。Lambda 表達(dá)式將集合中的元素作為輸入,并返回一個(gè)代表轉(zhuǎn)換后元素的新值。
Here is an example of using Lambda expressions to map a list of strings to a list of integers:
List<String>?strings?=?Arrays.asList("1",?"2",?"3",?"4",?"5");??
List<Integer>?integers?=?strings.stream().map(Integer::parseInt).collect(Collectors.toList());
In this example, we are using a Lambda expression to map the list of strings to a list of integers. The Lambda expression applies the parseInt() method of the Integer class to each string in the list, converting it to an integer value. The map() method then uses this Lambda expression to create a new stream that contains the transformed elements.
在本例中,我們使用 Lambda 表達(dá)式將字符串列表映射為整數(shù)列表。Lambda 表達(dá)式對(duì)列表中的每個(gè)字符串應(yīng)用 Integer 類的 parseInt() 方法,將其轉(zhuǎn)換為整數(shù)值。然后,map() 方法使用此 Lambda 表達(dá)式創(chuàng)建一個(gè)包含轉(zhuǎn)換后元素的新流。
Note that in this example, we are using the method reference notation (::) to refer to the parseInt() method of the Integer class. This is a shorthand notation for a Lambda expression that simply calls a single method.
請(qǐng)注意,在本例中,我們使用方法引用符號(hào)(::)來(lái)引用 Integer 類的 parseInt() 方法。這是一個(gè) Lambda 表達(dá)式的簡(jiǎn)寫(xiě)符號(hào),只需調(diào)用一個(gè)方法即可。
Here is another example of using a Lambda expression to map a list of strings to a list of uppercase strings:
下面是另一個(gè)使用 Lambda
表達(dá)式將字符串列表映射為大寫(xiě)字符串列表的示例:
List<String>?words?=?Arrays.asList("apple",?"banana",?"cherry",?"date",?"elderberry");??
List<String>?uppercaseWords?=?words.stream().map(s?->?s.toUpperCase()).collect(Collectors.toList());
In this example, we are using a Lambda expression to map the list of strings to a list of uppercase strings. The Lambda expression applies the toUpperCase() method of the String class to each string in the list, converting it to an uppercase string. The map() method then uses this Lambda expression to create a new stream that contains the transformed elements.
在本例中,我們使用 Lambda 表達(dá)式將字符串列表映射為大寫(xiě)字符串列表。Lambda 表達(dá)式將 String 類的 toUpperCase() 方法應(yīng)用于列表中的每個(gè)字符串,將其轉(zhuǎn)換為大寫(xiě)字符串。然后,map() 方法使用此 Lambda 表達(dá)式創(chuàng)建一個(gè)包含轉(zhuǎn)換后元素的新流。
12Use Lambda expressions to Reduce Collections 使用 Lambda 表達(dá)式精簡(jiǎn)集合
Reducing is the process of applying an operation to all the elements of a collection to produce a single result. In Java, collections can be reduced using the reduce() method of the Stream API.
Reducing
是對(duì)集合中的所有元素進(jìn)行操作以產(chǎn)生單一結(jié)果的過(guò)程。在 Java 中,可以使用流 API 的 reduce()
方法對(duì)集合進(jìn)行還原。
When using Lambda expressions to reduce collections, the Lambda expression is used to define the operation that should be applied to each element in the collection. The Lambda expression takes two arguments as input: an accumulator and an element from the collection. The accumulator is the result of the previous operation, or an initial value if this is the first operation. The Lambda expression returns a new value that represents the result of applying the operation to the accumulator and the current element.
使用 Lambda 表達(dá)式還原集合時(shí),Lambda 表達(dá)式用于定義應(yīng)用于集合中每個(gè)元素的操作。Lambda 表達(dá)式將兩個(gè)參數(shù)作為輸入:累加器和集合中的一個(gè)元素。累加器是前一次操作的結(jié)果,如果是第一次操作,則是初始值。Lambda 表達(dá)式返回一個(gè)新值,該值代表對(duì)累加器和當(dāng)前元素應(yīng)用操作的結(jié)果。
Here is an example of using Lambda expressions to reduce a list of integers to a single sum:
下面是一個(gè)使用 Lambda 表達(dá)式將整數(shù)列表簡(jiǎn)化為單個(gè)和的示例:
List<Integer>?numbers?=?Arrays.asList(1,?2,?3,?4,?5);??
int?sum?=?numbers.stream().reduce(0,?(a,?b)?->?a?+?b);
In this example, we are using a Lambda expression to reduce the list of integers to a single sum. The Lambda expression takes two integer values as input: an accumulator (initialized to zero in this case), and an element from the list. The Lambda expression adds the element to the accumulator, and returns the new value of the?accumulator. The reduce() method then uses this Lambda expression to apply the operation to each element in the list, producing the final sum.
在本例中,我們使用 Lambda 表達(dá)式將整數(shù)列表還原為單個(gè)和。Lambda 表達(dá)式將兩個(gè)整數(shù)值作為輸入:一個(gè)累加器(本例中初始化為零)和列表中的一個(gè)元素。Lambda 表達(dá)式將元素加到累加器中,并返回_accumulator_的新值。然后,reduce() 方法使用此 Lambda 表達(dá)式對(duì)列表中的每個(gè)元素進(jìn)行運(yùn)算,得出最終總和。
Note that in this example, we are using the “arrow” notation (->) to separate the parameter list ?from the body of the Lambda expression. The parameter list consists of two integer values: the accumulator and the current element from the list. The body of the Lambda expression adds the current element to the accumulator using the + operator.
請(qǐng)注意,在本例中,我們使用了 "箭頭 "符號(hào) (->) 來(lái)分隔參數(shù)列表和 Lambda 表達(dá)式的主體。參數(shù)列表由兩個(gè)整數(shù)值組成:累加器和列表中的當(dāng)前元素。Lambda 表達(dá)式的主體使用 + 運(yùn)算符將當(dāng)前元素添加到累加器中。
Here is another example of using a Lambda expression to reduce a list of strings to a single concatenated string:
下面是另一個(gè)使用 Lambda 表達(dá)式將字符串列表縮減為單個(gè)連接字符串的示例:
List<String>?words?=?Arrays.asList("apple",?"banana",?"cherry",?"date",?"elderberry");??
String?concatenated?=?words.stream().reduce("",?(a,?b)?->?a?+?b);
In this example, we are using a Lambda expression to reduce the list of strings to a single concatenated string. The Lambda expression takes two string values as input: an accumulator (initialized to an empty string in this case), and an element from the list. The Lambda expression concatenates the element to the accumulator, and returns the new value of the accumulator. The reduce() method then uses this Lambda expression to apply the operation to each element in the list, producing the final concatenated string.
在本例中,我們使用 Lambda 表達(dá)式將字符串列表還原為單個(gè)連接字符串。Lambda 表達(dá)式將兩個(gè)字符串值作為輸入:一個(gè)累加器(本例中初始化為空字符串)和列表中的一個(gè)元素。Lambda 表達(dá)式將元素連接到累加器,并返回累加器的新值。然后,reduce() 方法使用此 Lambda 表達(dá)式對(duì)列表中的每個(gè)元素進(jìn)行操作,生成最終的連接字符串。
13Use Lambda expressions to Group Collections ?使用 Lambda 表達(dá)式對(duì)集合進(jìn)行分組
Grouping is the process of grouping the elements of a collection based on a common property or criterion. In Java, collections can be grouped using the?groupingBy()?method of the Collectors class.
分組是根據(jù)共同屬性或標(biāo)準(zhǔn)對(duì)集合中的元素進(jìn)行分組的過(guò)程。在 Java 中,可以使用 Collectors 類的 groupingBy() 方法對(duì)集合進(jìn)行分組。
When using Lambda expressions to group collections, the Lambda expression is used to define the criterion that should be used to group the elements. The Lambda expression takes an element from the collection as input, and returns a value that represents the grouping criterion.
使用 Lambda 表達(dá)式對(duì)集合進(jìn)行分組時(shí),Lambda 表達(dá)式用于定義對(duì)元素進(jìn)行分組的標(biāo)準(zhǔn)。Lambda 表達(dá)式將集合中的元素作為輸入,并返回一個(gè)代表分組標(biāo)準(zhǔn)的值。
Here is an example of using Lambda expressions to group a list of words by their length:
下面是一個(gè)使用 Lambda 表達(dá)式按單詞長(zhǎng)度分組的示例:
List<String>?words?=?Arrays.asList("apple",?"banana",?"cherry",?"date",?"elderberry");??
Map<Integer,?List<String>>?groups?=?words.stream().collect(Collectors.groupingBy(String::length));
In this example, we are using a Lambda expression to group the list of words by their length. The groupingBy() method uses this Lambda expression to create a map that groups the words by their length. The key of each entry in the map is an integer value representing the length of the words, and the value of each entry is a list of words with that length.
在本例中,我們使用 Lambda
表達(dá)式按單詞長(zhǎng)度對(duì)單詞列表進(jìn)行分組。groupingBy()
方法使用此 Lambda
表達(dá)式創(chuàng)建一個(gè)按單詞長(zhǎng)度分組的映射。映射中每個(gè)條目的鍵是代表單詞長(zhǎng)度的整數(shù)值,每個(gè)條目的值是具有該長(zhǎng)度的單詞列表。
Note that in this example, we are using the method reference notation (::) to refer to the length() method of the String class. This is a shorthand notation for a Lambda expression that simply calls a single method.
請(qǐng)注意,在本例中,我們使用方法引用符號(hào)(::
)來(lái)引用 String
類的 length()
方法。這是簡(jiǎn)單調(diào)用單個(gè)方法的 Lambda 表達(dá)式的速記符號(hào)。
Here is another example of using a Lambda expression to group a list of employees by their department:
下面是另一個(gè)使用 Lambda 表達(dá)式按部門(mén)對(duì)員工列表進(jìn)行分組的示例:
List<Employee>?employees?=?Arrays.asList(??
????new?Employee("Alice",?"Sales"),??
????new?Employee("Bob",?"Marketing"),??
????new?Employee("Charlie",?"Sales"),??
????new?Employee("Dave",?"Marketing"),??
????new?Employee("Eve",?"HR")??
);??
Map<String,?List<Employee>>?groups?=?employees.stream().collect(Collectors.groupingBy(Employee::getDepartment));
In this example, we are using a Lambda expression to group the list of employees by their department. The groupingBy() method uses this Lambda expression to create a map that groups the employees by their department. The key of each entry in the map is a string value representing the department of the employees, and the value of each entry is a list of employees in that department.
在本例中,我們使用 Lambda 表達(dá)式按部門(mén)對(duì)員工列表進(jìn)行分組。groupingBy()方法使用此 Lambda 表達(dá)式創(chuàng)建了一個(gè)按部門(mén)對(duì)員工進(jìn)行分組的映射。映射中每個(gè)條目的鍵是代表員工部門(mén)的字符串值,每個(gè)條目的值是該部門(mén)的員工列表。
14Use Lambda expressions to Handle Exceptions 使用 Lambda 表達(dá)式處理異常
Lambda expressions can be used to handle checked exceptions in Java. Checked exceptions are a type of exception that must be declared in a method’s signature or handled by the caller. When using Lambda expressions to handle checked exceptions, the Lambda expression is used to define the behavior that should be executed in case of an exception, while still allowing the checked exception to be propagated up to the caller.
Lambda 表達(dá)式可用于處理 Java 中的校驗(yàn)異常。校驗(yàn)異常是一種必須在方法簽名中聲明或由調(diào)用者處理的異常類型。使用 Lambda 表達(dá)式處理校驗(yàn)異常時(shí),Lambda 表達(dá)式用于定義異常情況下應(yīng)執(zhí)行的行為,同時(shí)仍允許將校驗(yàn)異常傳播給調(diào)用者。
Here is an example of using Lambda expressions to handle a checked exception when reading a file:
下面是一個(gè)使用 Lambda 表達(dá)式處理讀取文件時(shí)已檢查異常的示例:
List<String>?lines?=?null;??
try?(BufferedReader?reader?=?new?BufferedReader(new?FileReader("file.txt")))?{??
????lines?=?reader.lines()??
??????????????????.map(line?->?{??
??????????????????????try?{??
??????????????????????????return?process(line);??
??????????????????????}?catch?(IOException?e)?{??
??????????????????????????throw?new?UncheckedIOException(e);??
??????????????????????}??
??????????????????})??
??????????????????.collect(Collectors.toList());??
}?catch?(IOException?e)?{??
????e.printStackTrace();??
}??
private?static?String?process(String?line)?throws?IOException?{??
????//?process?the?line??
}??
In this example, we are using a Lambda expression to handle a checked exception when processing each line of a file. The code first creates a?BufferedReader?object that reads from a file named “file.txt”. The lines from the file are then processed using the map() method of the Stream interface. The map() method takes a Function object as input, which is implemented as a Lambda expression in this case. The Lambda expression calls the process() method to process each line, and catches any IOException that may occur. If an IOException occurs, the Lambda expression throws an UncheckedIOException, which is a runtime exception that wraps the original checked exception.
在本示例中,我們使用 Lambda 表達(dá)式來(lái)處理處理文件每一行時(shí)檢查到的異常。代碼首先創(chuàng)建了一個(gè) BufferedReader 對(duì)象,用于讀取名為 "file.txt "的文件。
然后使用 Stream 接口的 map() 方法處理文件中的行。
map() 方法將一個(gè) Function 對(duì)象作為輸入,在本例中實(shí)現(xiàn)為一個(gè) Lambda 表達(dá)式。Lambda 表達(dá)式調(diào)用 process() 方法處理每一行,并捕獲可能出現(xiàn)的任何 IOException。
如果出現(xiàn) IO 異常,Lambda 表達(dá)式會(huì)拋出一個(gè)未檢查的 IO 異常,這是一個(gè)運(yùn)行時(shí)異常,它封裝了原始的已檢查異常。
Note that in this example, we are using a Lambda expression with a block of statements enclosed in braces. This is because the?process()?method throws an?IOException, which must be caught or re-thrown by the Lambda expression.
請(qǐng)注意,在這個(gè)示例中,我們使用的是一個(gè) Lambda 表達(dá)式和一個(gè)用大括號(hào)括起來(lái)的語(yǔ)句塊。這是因?yàn)?process() 方法會(huì)拋出一個(gè)_IOException_,而 Lambda 表達(dá)式必須捕獲或重新拋出這個(gè) IOException 。
By using Lambda expressions to handle checked exceptions, you can create more concise and readable code, and handle exceptions with greater flexibility and modularity. Lambda expressions provide a powerful and flexible way to handle checked exceptions in Java, and can be used in a wide range of scenarios, such as file I/O, network communication, and database access.
通過(guò)使用 Lambda
表達(dá)式來(lái)處理校驗(yàn)異常,您可以創(chuàng)建更簡(jiǎn)潔、更易讀的代碼,并以更大的靈活性和模塊化來(lái)處理異常。Lambda 表達(dá)式為在 Java 中處理檢查異常提供了一種強(qiáng)大而靈活的方法,可用于文件 I/O、網(wǎng)絡(luò)通信和數(shù)據(jù)庫(kù)訪問(wèn)等多種場(chǎng)景。
15Use Lambda expressions to Handle Null Values 使用 Lambda 表達(dá)式處理空值
In Java, NullPointerExceptions (NPEs) can often occur when dealing with null values. Lambda expressions can be used to handle null values in a more concise and expressive way, and to prevent?NullPointerExceptions?from occurring. Here is an example of using Lambda expressions to handle null values when filtering a list of strings:
在 Java 中,處理空值時(shí)經(jīng)常會(huì)出現(xiàn) NullPointerException(NPE)
??梢允褂?Lambda 表達(dá)式以更簡(jiǎn)潔、更具表現(xiàn)力的方式處理空值,并防止發(fā)生 NullPointerException 異常。下面是一個(gè)在過(guò)濾字符串列表時(shí)使用 Lambda 表達(dá)式處理空值的示例:
List<String>?list?=?Arrays.asList("apple",?null,?"banana",?"cherry",?null);??
List<String>?filteredList?=?list.stream()??
????????????????????????????????.filter(s?->?s?!=?null)??
????????????????????????????????.collect(Collectors.toList());??
System.out.println(filteredList);??
In this example, we are using the?filter()?method of the Stream interface to filter a list of strings. The filter() method takes a Predicate object as input, which is implemented as a Lambda expression in this case. The Lambda expression defines a predicate that tests whether a string is not null.
在本例中,我們使用 Stream 接口的 filter() 方法過(guò)濾字符串列表。filter()方法將一個(gè)謂詞對(duì)象作為輸入,在本例中是以 Lambda 表達(dá)式的形式實(shí)現(xiàn)的。Lambda 表達(dá)式定義了一個(gè)謂詞,用于測(cè)試字符串是否為空。
Note that in this example, we are using the != operator to test for null values. This is because the null value is not equal to any other value, including null itself.
請(qǐng)注意,在本例中,我們使用 != 操作符來(lái)測(cè)試空值。這是因?yàn)閚ull值不等于任何其他值,包括null值本身。
16Use Lambda expressions to perform Parallel Operations 使用 Lambda 表達(dá)式執(zhí)行并行操作
Lambda expressions are anonymous functions in Java that can be used to perform a variety of operations, including parallel operations.
Lambda 表達(dá)式是 Java 中的匿名函數(shù)(但是細(xì)節(jié)上和真正的匿名函數(shù)不一樣),可用于執(zhí)行各種操作,包括并行操作。
Parallelism refers to the ability to perform multiple operations simultaneously, thereby reducing the amount of time it takes to complete a task. In Java, parallelism can be achieved using the Stream API and lambda expressions.
并行性是指同時(shí)執(zhí)行多個(gè)操作的能力,從而減少完成任務(wù)所需的時(shí)間。在 Java 中,可以使用流 API 和 lambda 表達(dá)式來(lái)實(shí)現(xiàn)并行性
The Stream API provides a?parallelStream()?method that allows you to create parallel streams. Streams are collections of objects that can be processed sequentially or in parallel. By default, streams are processed sequentially, but you can use the?parallelStream()?method to process them in parallel.
流 API 提供了一個(gè) parallelStream() 方法,允許您創(chuàng)建并行流。
流是可以按順序或并行處理的對(duì)象集合。默認(rèn)情況下,流是按順序處理的,但您可以使用 parallelStream() 方法并行處理它們。
To use lambda expressions to perform parallel operations, you first need to create a stream using the parallelStream() method. You can then use lambda expressions to define the operations that are performed on the elements of the stream.?The Stream API will automatically split the stream into multiple substreams and distribute them across multiple threads, allowing the operations to be performed in parallel.
要使用 lambda 表達(dá)式執(zhí)行并行操作,首先需要使用 parallelStream() 方法創(chuàng)建一個(gè)流。然后,就可以使用 lambda 表達(dá)式定義對(duì)流元素執(zhí)行的操作。?**流 API 會(huì)自動(dòng)將流拆分成多個(gè)子流,并將它們分配給多個(gè)線程,從而允許并行執(zhí)行操作。
Here’s an example of using lambda expressions to perform a parallel operation:
下面是一個(gè)使用 lambda 表達(dá)式執(zhí)行并行操作的示例:
List<Integer>?numbers?=?Arrays.asList(1,?2,?3,?4,?5,?6,?7,?8,?9,?10);??
int?sum?=?numbers.parallelStream()??
????????????????.filter(n?->?n?%?2?==?0)??
????????????????.mapToInt(n?->?n)??
????????????????.sum();
17Use Lambda expressions to create Custom Collectors ?使用 Lambda 表達(dá)式創(chuàng)建自定義收集器
A collector is an operation that can be performed on a stream to accumulate the elements of the stream into a final result. Collectors are used with the?collect()?method of the Stream interface.
收集器是一種可在流上執(zhí)行的操作,用于將流的元素累加為最終結(jié)果。收集器與流接口的 collect() 方法一起使用。
Java provides a number of built-in collectors that perform common operations like grouping elements, counting elements, and calculating averages. However, you can also create your own custom collectors using lambda expressions.
Java 提供了許多內(nèi)置收集器,可執(zhí)行分組元素、計(jì)數(shù)元素和計(jì)算平均值等常見(jiàn)操作。 不過(guò),您也可以使用 lambda 表達(dá)式創(chuàng)建自己的自定義收集器。
To create a custom collector using lambda expressions, you need to define a new class that implements the?Collector?interface. The Collector interface has four methods that you need to implement:
要使用 lambda 表達(dá)式創(chuàng)建自定義收集器,需要定義一個(gè)實(shí)現(xiàn) Collector 接口的新類。收集器接口有四個(gè)方法需要實(shí)現(xiàn):
The?supplier()?method returns a function that creates a new mutable result container.
The?accumulator()?method returns a function that adds an element to the result container.
The?combiner()?method returns a function that combines two result containers.
The?finisher()?method returns a function that performs a final transformation on the result container.
_supplier()_: 方法返回一個(gè)函數(shù),用于創(chuàng)建一個(gè)新的可變結(jié)果容器。
_Accumulator()_: ?方法返回一個(gè)將元素添加到結(jié)果容器的函數(shù)。
_combiner()_:方法返回一個(gè)將兩個(gè)結(jié)果容器組合在一起的函數(shù)。
_finisher()_: 方法返回一個(gè)對(duì)結(jié)果容器執(zhí)行最終轉(zhuǎn)換的函數(shù)。
Here’s an example of creating a custom collector that calculates the average of a stream of integers:
下面是一個(gè)創(chuàng)建自定義收集器的示例,用于計(jì)算整數(shù)流的平均值:
public?class?AverageCollector?implements?Collector<Integer,?int[],?Double>?{??
???? ??
????public?Supplier<int[]>?supplier()?{??
????????return?()?->?new?int[2];??
????}??
??????
???? ??
????public?BiConsumer<int[],?Integer>?accumulator()?{??
????????return?(acc,?val)?->?{??
????????????acc[0]?+=?val;??
????????????acc[1]++;??
????????};??
????}??
??????
???? ??
????public?BinaryOperator<int[]>?combiner()?{??
????????return?(acc1,?acc2)?->?{??
????????????acc1[0]?+=?acc2[0];??
????????????acc1[1]?+=?acc2[1];??
????????????return?acc1;??
????????};??
????}??
??????
???? ??
????public?Function<int[],?Double>?finisher()?{??
????????return?acc?->?((double)?acc[0])?/?acc[1];??
????}??
??????
???? ??
????public?Set<Characteristics>?characteristics()?{??
????????return?Collections.emptySet();??
????}??
}
In this example, we define a new class called?AverageCollector?that implements the Collector interface. The?supplier()?method returns a function that creates a new integer array with two elements to store the sum and count of the elements in the stream.
在本例中,我們定義了一個(gè)名為 AverageCollector 的新類,該類實(shí)現(xiàn)了收集器接口。_supplier()_ 方法返回一個(gè)函數(shù),用于創(chuàng)建一個(gè)包含兩個(gè)元素的新整數(shù)數(shù)組,用于存儲(chǔ)數(shù)據(jù)流中元素的總和與計(jì)數(shù)。
The accumulator() method returns a function that adds each element to the sum and increments the count. The?combiner()?method returns a function that combines two integer arrays by adding their corresponding elements. The?finisher()?method returns a function that calculates the average by dividing the sum by the count. Finally, the?characteristics()?method returns an empty set because this collector does not have any special characteristics.
累加器()方法返回一個(gè)將每個(gè)元素加到總和中并遞增計(jì)數(shù)的函數(shù)。_combiner()_ 方法返回一個(gè)函數(shù),該函數(shù)通過(guò)將兩個(gè)整數(shù)數(shù)組中的相應(yīng)元素相加來(lái)合并兩個(gè)數(shù)組。_finisher()_ 方法返回一個(gè)函數(shù),通過(guò)用總和除以計(jì)數(shù)來(lái)計(jì)算平均值。最后,_characteristics()_ 方法返回空集,因?yàn)樵撌占鳑](méi)有任何特殊特征。
Once you’ve defined your custom collector, you can use it with the collect() method of the Stream interface like this:
一旦定義了自定義收集器,就可以像這樣將其與 Stream 接口的 collect() 方法結(jié)合使用:
List<Integer>?numbers?=?Arrays.asList(1,?2,?3,?4,?5,?6,?7,?8,?9,?10);??
double?average?=?numbers.stream()??
????????????????????????.collect(new?AverageCollector());
In this example, we create a stream of integers and use the collect() method with our custom AverageCollector to calculate the average of the integers in the stream. The lambda expressions we defined in the AverageCollector class are used to perform the accumulation and transformation operations.
在本例中,我們創(chuàng)建了一個(gè)整數(shù)流,并使用帶有自定義 AverageCollector 的 collect() 方法計(jì)算流中整數(shù)的平均值。我們?cè)?AverageCollector 類中定義的 lambda 表達(dá)式用于執(zhí)行累加和轉(zhuǎn)換操作。
18Use Lambda expressions to create Higher-order Functions 使用 Lambda 表達(dá)式創(chuàng)建高階函數(shù)
A higher-order function is a function that takes one or more functions as arguments and/or returns a function as its result. Lambda expressions can be used to create functions that take other functions as arguments or return functions as results.
高階函數(shù)是將一個(gè)或多個(gè)函數(shù)作為參數(shù)和/或?qū)⒁粋€(gè)函數(shù)作為結(jié)果返回的函數(shù)。Lambda 表達(dá)式可用于創(chuàng)建將其他函數(shù)作為參數(shù)或?qū)⒑瘮?shù)作為結(jié)果返回的函數(shù)。
To create a higher-order function using lambda expressions, you can define a method that takes a functional interface as a parameter or return value. A functional interface is an interface that has exactly one abstract method and is annotated with the @FunctionalInterface annotation.
要使用 lambda 表達(dá)式創(chuàng)建高階函數(shù),可以定義一個(gè)將功能接口作為參數(shù)或返回值的方法。功能接口是一個(gè)擁有一個(gè)抽象方法并使用 @FunctionalInterface 注解的接口。
Here’s an example of creating a higher-order function that takes a function as an argument:
下面是一個(gè)創(chuàng)建以函數(shù)為參數(shù)的高階函數(shù)的示例:
??
interface?BinaryOperator<T>?{??
????T?apply(T?t1,?T?t2);??
}??
public?static?<T>?BinaryOperator<T>?compose(BinaryOperator<T>?op1,?BinaryOperator<T>?op2)?{??
????return?(x,?y)?->?op1.apply(op2.apply(x,?y),?y);??
}
In this example, we define a functional interface called?BinaryOperator?that has an?apply()?method that takes two arguments and returns a result. We then define a static method called?compose()?that takes two BinaryOperator functions as arguments and returns a new BinaryOperator function that composes the two input functions.
在本例中,我們定義了一個(gè)名為 BinaryOperator 的函數(shù)接口,它有一個(gè) apply() 方法,該方法接收兩個(gè)參數(shù)并返回一個(gè)結(jié)果。然后,我們定義了一個(gè)名為 compose() 的靜態(tài)方法,該方法接收兩個(gè) BinaryOperator 函數(shù)作為參數(shù),并返回一個(gè)新的 BinaryOperator 函數(shù),該函數(shù)將兩個(gè)輸入函數(shù)合成。
The?compose()?method takes two BinaryOperator functions as arguments, op1 and op2. It then returns a new BinaryOperator function that applies op1 to the result of applying op2 to its arguments. The lambda expression (x, y) -> op1.apply(op2.apply(x, y), y) defines the new BinaryOperator function. The first argument of the lambda expression (x) is the result of applying op2 to the original arguments, and the second argument (y) is the second original argument.
compose() 方法將 op1 和 op2 這兩個(gè)二進(jìn)制操作符函數(shù)作為參數(shù)。然后,它返回一個(gè)新的二進(jìn)制操作符函數(shù),該函數(shù)將 op1 應(yīng)用于將 op2 應(yīng)用于其參數(shù)的結(jié)果。lambda 表達(dá)式 (x, y) -> op1.apply(op2.apply(x, y), y)
定義了新的二元運(yùn)算符函數(shù)。lambda 表達(dá)式的第一個(gè)參數(shù) (x) 是將 op2 應(yīng)用于原始參數(shù)的結(jié)果,第二個(gè)參數(shù) (y) 是第二個(gè)原始參數(shù)。
Here’s an example of using the compose() method to compose two BinaryOperator functions:
下面是一個(gè)使用 compose()
方法組合兩個(gè) BinaryOperator
函數(shù)的示例:
BinaryOperator<Integer>?add?=?(x,?y)?->?x?+?y;??
BinaryOperator<Integer>?multiply?=?(x,?y)?->?x?*?y;??
BinaryOperator<Integer>?composed?=?compose(add,?multiply);??
System.out.println(composed.apply(2,?3));?//?Output:?8
In this example, we define two BinaryOperator functions: add, which adds its two arguments, and multiply, which multiplies its two arguments. We then use the compose() method to create a new BinaryOperator function that first multiplies its arguments and then adds the result. We test the composed function by applying it to the values 2 and 3, which should result in 8.
在本例中,我們定義了兩個(gè) BinaryOperator 函數(shù):add 和 multiply,前者用于將兩個(gè)參數(shù)相加,后者用于將兩個(gè)參數(shù)相乘。然后,我們使用 compose() 方法創(chuàng)建一個(gè)新的 BinaryOperator 函數(shù),首先乘以參數(shù),然后將結(jié)果相加。我們對(duì)組成的函數(shù)進(jìn)行測(cè)試,將其應(yīng)用于數(shù)值 2 和 3,結(jié)果應(yīng)為 8。
Lambda expressions can also be used to create higher-order functions that return functions as results. Here’s an example of creating a higher-order function that returns a UnaryOperator function:
Lambda 表達(dá)式還可用于創(chuàng)建高階函數(shù),將函數(shù)作為結(jié)果返回。下面是創(chuàng)建返回 UnaryOperator 函數(shù)的高階函數(shù)的示例:
??
interface?UnaryOperator<T>?{??
????T?apply(T?t);??
}??
public?static?<T>?UnaryOperator<T>?addValue(T?value)?{??
????return?x?->?x?+?value;??
}
In this example, we define a functional interface called UnaryOperator that has an apply() method that takes one argument and returns a result. We then define a static method called addValue() that takes a value of type T and returns a new UnaryOperator function that adds the value to its argument.
在本例中,我們定義了一個(gè)名為 UnaryOperator 的函數(shù)接口,它有一個(gè) apply() 方法,該方法接收一個(gè)參數(shù)并返回一個(gè)結(jié)果。然后,我們定義了一個(gè)名為 addValue() 的靜態(tài)方法,該方法接收一個(gè) T 類型的值,并返回一個(gè)新的 UnaryOperator 函數(shù),將值添加到其參數(shù)中。
The addValue() method returns a lambda expression that defines the new UnaryOperator function. The lambda expression x -> x + value takes one argument (x) and adds the value to it.
addValue()
方法返回一個(gè) lambda 表達(dá)式,該表達(dá)式定義了新的 UnaryOperator
函數(shù)。lambda 表達(dá)式 x -> x + value
接收一個(gè)參數(shù)(x)
并將值添加到參數(shù)中。
Here’s an example of using the addValue() method to create a new UnaryOperator function:
下面是一個(gè)使用 addValue()
方法創(chuàng)建新的 UnaryOperator
函數(shù)的示例:
UnaryOperator<Integer>?add5?=?addValue(5);??
System.out.println(add5.apply(2));?//?Output:?7
In this example, we use the addValue() method to create a new UnaryOperator function that adds 5 to its argument. We assign the result to the add5 variable, which is now a function that adds 5 to its argument. We test the add5 function by applying it to the value 2, which should result in 7.
在本例中,我們使用 addValue() 方法創(chuàng)建了一個(gè)新的 UnaryOperator 函數(shù),將 5 添加到參數(shù)中。我們將結(jié)果賦值給 add5 變量,它現(xiàn)在是一個(gè)將 5 添入其參數(shù)的函數(shù)。我們對(duì) add5 函數(shù)進(jìn)行測(cè)試,將其應(yīng)用于數(shù)值 2,結(jié)果應(yīng)為 7。
19Use Lambda expressions to create Closures 使用 Lambda 表達(dá)式創(chuàng)建閉包
A closure is a function that can access and modify variables in its enclosing scope. In other words, a closure “closes over” the variables in its enclosing scope and can use them as if they were local variables.
閉包是一個(gè)可以訪問(wèn)和修改其外層作用域中變量的函數(shù)。換句話說(shuō),閉包 "關(guān)閉 "其外層作用域中的變量,并能像使用局部變量一樣使用它們。
To create a closure using lambda expressions, you can define a lambda expression that references a variable in its enclosing scope. The lambda expression will then capture the value of the variable at the time the lambda expression is created and use that value whenever it is called.
要使用 lambda 表達(dá)式創(chuàng)建閉包,可以定義一個(gè) lambda 表達(dá)式,在其外層作用域中引用一個(gè)變量。然后,在創(chuàng)建 lambda 表達(dá)式時(shí),lambda 表達(dá)式將捕獲變量的值,并在調(diào)用時(shí)使用該值。
Here’s an example of creating a closure using a lambda expression:
下面是一個(gè)使用 lambda 表達(dá)式創(chuàng)建閉包的示例:
public?class?ClosureExample?{??
????public?static?void?main(String[]?args)?{??
????????int?x?=?5;??
????????Runnable?runnable?=?()?->?System.out.println(x);??
????????x?=?10;??
????????runnable.run();?//?Output:?10??
????}??
}
In this example, we define a variable x with the value 5. We then define a lambda expression that references x and prints its value. Finally, we change the value of x to 10 and call the lambda expression.
在本例中,我們定義了一個(gè)值為 5 的變量 x。然后,我們定義一個(gè) lambda 表達(dá)式,引用 x 并打印其值。最后,我們將 x 的值改為 10 并調(diào)用 lambda 表達(dá)式。
When the lambda expression is created, it captures the value of x, which is 5 at the time. When we call the lambda expression, it prints the value of x, which is now 10 because we changed its value after the lambda expression was created. The lambda expression “closes over” the variable x and uses it as if it were a local variable.
創(chuàng)建 lambda 表達(dá)式時(shí),它會(huì)捕捉 x 的值,當(dāng)時(shí)的值是 5。當(dāng)我們調(diào)用 lambda 表達(dá)式時(shí),它會(huì)打印出 x 的值,現(xiàn)在是 10,因?yàn)槲覀冊(cè)趧?chuàng)建 lambda 表達(dá)式后更改了它的值。lambda 表達(dá)式 "關(guān)閉 "了變量 x,并像使用局部變量一樣使用它。
Here’s another example of creating a closure using a lambda expression:
下面是另一個(gè)使用lambda表達(dá)式創(chuàng)建閉包的示例:
public?class?ClosureExample?{??
????public?static?void?main(String[]?args)?{??
????????List<Integer>?numbers?=?Arrays.asList(1,?2,?3,?4,?5);??
????????int?sum?=?0;??
????????numbers.forEach(n?->?sum?+=?n);??
????????System.out.println(sum);?//?Output:?15??
????}??
}
In this example, we define a list of integers and a variable sum with the initial value 0. We then use a lambda expression to iterate over the list and add each element to the sum variable. Finally, we print the value of sum.
在本例中,我們定義了一個(gè)整數(shù)列表和一個(gè)初始值為 0 的變量 sum。然后,我們使用 lambda 表達(dá)式遍歷列表,并將每個(gè)元素添加到 sum 變量中。最后,我們打印 sum 的值。
The lambda expression “closes over” the variable sum and updates its value each time it is called. This allows us to calculate the sum of the list using a single lambda expression and a single variable, without the need for a separate loop or accumulator.
lambda 表達(dá)式 "關(guān)閉 "變量 sum,并在每次調(diào)用時(shí)更新其值。這樣,我們就可以使用單個(gè) lambda 表達(dá)式和單個(gè)變量計(jì)算列表的總和,而無(wú)需單獨(dú)的循環(huán)或累加器。