Table of contents
What is Stream?
Stream is a new way of processing collection data in Java 8. It provides a streaming processing method similar to database operations. It can filter, map, sort, aggregate and other operations on collections, making collection operations more efficient. Simple and efficient.
Stream stream mainly has the following characteristics:
- Stream is not a data structure and does not change the source data. Instead, it generates a new data stream by operating on the source data.
- Stream supports chain operations and can combine multiple operations, making the code more concise.
- Stream stream supports delayed operation, and calculation will only be performed when the operation is terminated, which can improve the performance of the program.
- Stream can perform parallel operations and take advantage of the performance advantages of multi-core processors to improve the calculation speed of the program.
How to use Stream?
Using Stream can be divided into the following steps:
- Obtain data sources: Data sources can be obtained through collections, arrays, IO streams, etc.
- Convert to stream: Convert the data source to a stream through methods such as stream() and parallelStream().
- Intermediate operations: Perform intermediate operations on the stream, such as filtering, mapping, sorting, deduplication, etc. These operations will return a new stream.
- Termination operation: perform termination operations on the stream, such as collection, counting, search, matching, etc. These operations will return a result.
The methods and usage examples of each operation will be introduced below.
1. Get the data source
Data sources can be obtained through collections, arrays, IO streams, etc.
Get a data source using a collection
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
Get data source using array
String[] array = {
"apple", "banana", "orange", "grape", "watermelon"};
2. Convert to stream
Convert the data source into a stream through methods such as stream() and parallelStream().
Convert collection to stream
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
Stream<String> stream = list.stream();
Convert array to stream
String[] array = {
"apple", "banana", "orange", "grape", "watermelon"};
Stream<String> stream = Arrays.stream(array);
3. Intermediate operations
Perform intermediate operations on the stream, such as filtering, mapping, sorting, deduplication, etc. These operations will return a new stream.
Filter data
Filter out strings whose length is less than or equal to 5:
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
Stream<String> stream = list.stream().filter(str -> str.length() > 5);
Mapping data
Extract the names of all fruits:
List<Fruit> fruits = Arrays.asList(
new Fruit("apple", "red"),
new Fruit("banana", "yellow"),
new Fruit("orange", "orange"),
new Fruit("grape", "purple"),
new Fruit("watermelon", "green")
);
Stream<String> stream = fruits.stream().map(Fruit::getName);
Sort data
Sort by fruit name:
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
Stream<String> stream = list.stream().sorted();
Deduplicate data
Remove duplicate fruit names:
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon", "apple", "banana");
Stream<String> stream = list.stream().distinct();
4. Terminate operation
Perform termination operations on the stream, such as collection, counting, search, matching, etc., these operations will return a result.
Data collection
Collect fruit names into a list:
List<Fruit> fruits = Arrays.asList(
new Fruit("apple", "red"),
new Fruit("banana", "yellow"),
new Fruit("orange", "orange"),
new Fruit("grape", "purple"),
new Fruit("watermelon", "green")
);
List<String> names = fruits.stream().map(Fruit::getName).collect(Collectors.toList());
count data
Count the number of fruit names:
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon", "apple", "banana");
long count = list.stream().count();
Find data
Find the first fruit name:
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
Optional<String> first = list.stream().findFirst();
Match data
Determine whether a certain fruit name is included:
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
boolean contains = list.stream().anyMatch(str -> str.equals("banana"));
How to use Lambda expressions?
Lambda expressions can be used in functional interfaces, which are interfaces that contain only one abstract method.
Basic syntax of lambda expressions:
(parameters) -> expression
Among them, parameters is the parameter list of the method, and expression is the method body.
Examples of using Lambda expressions are introduced below.
1. Use Lambda expressions as parameters
Pass a Lambda expression as a parameter to another method:
public void process(int num, IntConsumer consumer) {
consumer.accept(num);
}
public static void main(String[] args) {
LambdaExample example = new LambdaExample();
// 使用Lambda表达式作为参数
example.process(10, (num) -> System.out.println(num));
// 使用Lambda表达式实现函数接口
Function<Integer, Integer> square = (num) -> num * num;
int result = square.apply(5);
System.out.println(result);
// 使用Lambda表达式简化集合操作
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
// 使用Lambda表达式实现筛选
List<String> filteredList = list.stream().filter(str -> str.length() > 5).collect(Collectors.toList());
// 使用Lambda表达式实现映射
List<String> mappedList = list.stream().map(str -> str.toUpperCase()).collect(Collectors.toList());
// 使用Lambda表达式实现排序
List<String> sortedList = list.stream().sorted().collect(Collectors.toList());
// 使用Lambda表达式实现去重
List<String> distinctList = list.stream().distinct().collect(Collectors.toList());
}
2. Use Lambda expressions to implement functional interfaces
Use Lambda expressions to implement a functional interface:
Function<Integer, Integer> square = (num) -> num * num;
3. Use Lambda expressions to simplify set operations
Lambda expressions can simplify collection operations, such as filtering, mapping, sorting, deduplication, etc. Here are some common examples of collection operations:
3.1 Filtering operation
Filtering operations can be implemented through the filter method, which can filter elements in the collection based on conditions and return a new Stream. For example, here is an example of a filter operation:
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); // [2, 4, 6, 8, 10]
In this example, first create a List collection containing integers 1 to 10, then use the filter method of the Stream stream to filter out the even numbers, and save the result to a new List collection.
3.2 Mapping operation
Mapping operations can be implemented through the map method, which maps an element in a collection to another element and returns a new Stream. For example, here is an example of a mapping operation:
List<String> words = Arrays.asList("hello", "world", "java", "stream", "lambda");
List<Integer> lengths = words.stream()
.map(String::length)
.collect(Collectors.toList());
System.out.println(lengths); // [5, 5, 4, 6, 6]
In this example, you first create a List collection containing strings, then use the map method of the Stream stream to map each string to its length, and save the result to a new List collection.
3.3 Sorting operation
Sorting operations can be implemented through the sorted method, which sorts the elements in the collection and returns a new Stream. For example, here is an example of a sort operation:
List<String> words = Arrays.asList("hello", "world", "java", "stream", "lambda");
List<String> sortedWords = words.stream()
.sorted()
.collect(Collectors.toList());
System.out.println(sortedWords); // [hello, java, lambda, stream, world]
In this example, first create a List collection containing strings, then use the sorted method of the Stream stream to sort the strings, and save the results to a new List collection.
3.4 Deduplication operation
The deduplication operation can be implemented through the distinct method, which can remove duplicate elements from the collection and return a new Stream. For example, here is an example of a deduplication operation:
List<Integer> numbers = Arrays.asList(1, 2, 3, 2, 4, 5, 4, 6, 7, 5);
List<Integer> distinctNumbers = numbers.stream()
.distinct()
.collect(Collectors.toList());
System.out.println(distinctNumbers); // [1, 2, 3, 4
Usage scenarios of Lambda expressions
Lambda expressions are suitable for handling the following scenarios:
- Functional interface: Lambda expressions can be used as implementations of functional interfaces. A functional interface contains only an abstract method, which can be implemented using Lambda expressions.
- Collection operations: Streams can be used to process elements in collections, such as filtering, mapping, sorting, deduplication, etc. Lambda expressions can be used to simplify the code.
- Multi-threaded programming: Lambda expressions can be used as implementations of Runnable and Callable interfaces, making multi-threaded programming more convenient.
- GUI event listener: Lambda expressions can be used to handle event processing methods in GUI event listeners, making the code more concise.
Advantages of Streams and Lambda Expressions
Using Streams and Lambda expressions has the following advantages:
- Simplicity: Using Stream and Lambda expressions can make the code more concise and readable, and reduce the complexity of the code.
- Easy to maintain: Using Stream and Lambda expressions can make the code easier to maintain and reduce code duplication.
- Concurrent execution: Stream streams can support concurrent execution and improve program execution efficiency.
- Efficient: Using Streams and Lambda expressions can make the code more efficient and reduce memory and CPU overhead.
in conclusion
Streams and Lambda expressions are two important features in Java 8. They can make the code more concise, readable, and flexible, and at the same time improve the efficiency and maintainability of the code. If you haven't used Streams and Lambda expressions yet, I hope this tutorial will help you get started.