2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Java 8 introduces many new features, the most notable of which are Lambda expressions and Stream API. Stream API provides an efficient and concise way to process collection data, making the code more concise, clear, readable and maintainable. This article will explore the use of Java Stream API in depth, including basic concepts, common operations, parallel processing, practical cases and best practices.
Stream API is an abstraction for processing collection data introduced in Java 8. It allows data to be processed in a declarative way (similar to SQL statements). Stream API provides many powerful operations that can be used to filter, sort, map, reduce, and other operations on collections, greatly simplifying the code.
The Stream API provides multiple ways to create Streams. The most common ones are as follows:
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);
Stream.of
:Stream<String> stream = Stream.of("a", "b", "c");
Stream.generate
:Stream<Double> stream = Stream.generate(Math::random).limit(10);
Stream.iterate
:Stream<Integer> stream = Stream.iterate(0, n -> n + 2).limit(10);
Intermediate operations are used to transform Streams and are lazily evaluated. Common intermediate operations include the following:
filter
: Used to filter elements.Stream<String> stream = list.stream().filter(s -> s.startsWith("a"));
map
: Used to map each element to the corresponding result.Stream<String> stream = list.stream().map(String::toUpperCase);
flatMap
: Used to convert each element into a Stream and then merge them into one Stream.Stream<String> stream = list.stream().flatMap(s -> Stream.of(s.split("")));
distinct
: Used for deduplication.Stream<String> stream = list.stream().distinct();
sorted
: Used for sorting.Stream<String> stream = list.stream().sorted();
peek
: Used to view each element during processing.Stream<String> stream = list.stream().peek(System.out::println);
Terminal operations are used to start stream calculations and generate results. Common terminal operations include the following:
forEach
: Perform an operation on each element.list.stream().forEach(System.out::println);
collect
: Convert a Stream to another form.List<String> result = list.stream().collect(Collectors.toList());
reduce
: Reduce the elements in the Stream to a value.Optional<String> result = list.stream().reduce((s1, s2) -> s1 + s2);
toArray
: Convert a Stream to an array.String[] array = list.stream().toArray(String[]::new);
count
: Calculate the number of elements.long count = list.stream().count();
anyMatch
、allMatch
、noneMatch
: Used for matching judgment.boolean anyMatch = list.stream().anyMatch(s -> s.startsWith("a"));
boolean allMatch = list.stream().allMatch(s -> s.startsWith("a"));
boolean noneMatch = list.stream().noneMatch(s -> s.startsWith("a"));
findFirst
、findAny
: Used to find elements.Optional<String> first = list.stream().findFirst();
Optional<String> any = list.stream().findAny();
usesorted
Method sorts the Stream and can pass in a comparator.
List<String> list = Arrays.asList("b", "c", "a");
List<String> sortedList = list.stream().sorted().collect(Collectors.toList());
// 逆序排序
List<String> sortedListDesc = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
usefilter
Method to filter the elements in the Stream.
List<String> list = Arrays.asList("a", "b", "c");
List<String> filteredList = list.stream().filter(s -> s.startsWith("a")).collect(Collectors.toList());
usemap
Method maps the elements in a Stream.
List<String> list = Arrays.asList("a", "b", "c");
List<String> mappedList = list.stream().map(String::toUpperCase).collect(Collectors.toList());
usereduce
Method to reduce the elements in the Stream.
List<String> list = Arrays.asList("a", "b", "c");
String result = list.stream().reduce("", (s1, s2) -> s1 + s2);
usecollect
Methods convert a Stream into another form.
List<String> list = Arrays.asList("a", "b", "c");
List<String> collectedList = list.stream().collect(Collectors.toList());
Set<String> collectedSet = list.stream().collect(Collectors.toSet());
String joinedString = list.stream().collect(Collectors.joining(","));
Parallel Stream can take full advantage of multi-core CPUs to improve data processing efficiency.parallelStream
Method to create a parallel Stream.
List<String> list = Arrays.asList("a", "b", "c");
List<String> parallelList = list.parallelStream().map(String::toUpperCase).collect(Collectors.toList());
You can also useparallel
method converts a normal Stream into a parallel Stream.
List<String> list = Arrays.asList("a", "b", "c");
List<String> parallelList = list.stream().parallel().map(String::toUpperCase).collect(Collectors.toList());
It should be noted that parallel Stream is not always faster than serial Stream, and specific tests need to be carried out according to specific circumstances.
Given a collection of strings, filter out strings with length less than 3 and convert the remaining strings to uppercase.
List<String> list = Arrays.asList("a", "ab", "abc", "abcd");
List<String> result = list.stream()
.filter(s -> s.length() >= 3)
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(result); // 输出:[ABC, ABCD]
Given a set of integers, calculate the average of all the integers.
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
OptionalDouble average = list.stream()
.mapToInt(Integer::intValue)
.average();
average.ifPresent(System.out::println); // 输出:3.0
Using Stream API
Read the contents of a file and output them to the console.
try (Stream<String> lines = Files.lines(Paths.get("example.txt"))) {
lines.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
Read the file contents and count the number of times each word occurs.
try (Stream<String> lines = Files.lines(Paths.get("example.txt"))) {
Map<String, Long> wordCount = lines
.flatMap(line -> Arrays.stream(line.split("\W+")))
.collect(Collectors.groupingBy(String::toLowerCase, Collectors.counting()));
wordCount.forEach((word, count) -> System.out.println(word + ": " + count));
} catch (IOException e) {
e.printStackTrace();
}
Suppose we have a database tableusers
, containing the fieldsid
、name
andage
We can use the Stream API to process the query results.
List<User> users = queryDatabase();
List<String> names = users.stream()
.filter(user -> user.getAge() > 18)
.map(User::getName)
.collect(Collectors.toList());
System.out.println(names);
Collectors
The class provides a variety of collectors, and you can choose the appropriate collector according to your specific needs.Once a Stream is consumed, it cannot be reused. If you need to reuse it, you can consider converting the Stream into a collection for reuse.
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
stream.forEach(System.out::println);
stream.forEach(System.out::println); // 会抛出IllegalStateException
Parallel Stream is not always faster than serial Stream, you need to test it according to the specific situation.ForkJoinPool
To optimize the performance of parallel Stream.
ForkJoinPool customThreadPool = new ForkJoinPool(4);
customThreadPool.submit(() ->
list.parallelStream().forEach(System.out::println)
).get();
When using the Stream API to process large amounts of data, you need to be aware of memory leaks.close
method to close the Stream, or usetry-with-resources
Statement automatically closes the Stream.
try (Stream<String> lines = Files.lines(Paths.get("example.txt"))) {
lines.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
This article introduces the use of Java Stream API in detail, including basic operations, advanced operations, parallel processing, practical cases and best practices. By making proper use of Stream API, developers can greatly simplify the code, improve the readability and maintainability of the code, and improve the efficiency of data processing. I hope this article will help you use Stream API in Java development.
Java Stream API is a powerful tool for processing collection data. By flexibly using various operations, efficient data processing and stream computing can be achieved. If you have not used Stream API, it is recommended to learn and master this powerful tool as soon as possible and apply it to your project to improve development efficiency and code quality.