моя контактная информация
Почтамезофия@protonmail.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
В Java 8 представлено множество новых функций, наиболее заметными из которых являются лямбда-выражения и Stream API. Stream API предоставляет эффективный и лаконичный метод обработки данных сбора, что делает код более кратким и понятным, а также обеспечивает высокую читаемость и удобство обслуживания. В этой статье мы углубимся в использование Java Stream API, включая базовые концепции, общие операции, параллельную обработку, практические примеры и лучшие практики.
Stream API — это абстракция, представленная в Java 8 для обработки данных коллекции, которая позволяет обрабатывать данные декларативным образом (аналогично операторам SQL). Stream API предоставляет множество мощных операций, которые можно использовать для фильтрации, сортировки, сопоставления, сокращения и других операций с коллекциями, что значительно упрощает код.
Stream API предоставляет различные способы создания Stream.
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);
Промежуточные операции используются для преобразования Stream и лениво оцениваются. К распространенным промежуточным операциям относятся следующие:
filter
: используется для фильтрации элементов.Stream<String> stream = list.stream().filter(s -> s.startsWith("a"));
map
: используется для сопоставления каждого элемента с соответствующим результатом.Stream<String> stream = list.stream().map(String::toUpperCase);
flatMap
: используется для преобразования каждого элемента в поток и последующего объединения его в один поток.Stream<String> stream = list.stream().flatMap(s -> Stream.of(s.split("")));
distinct
: используется для удаления дубликатов.Stream<String> stream = list.stream().distinct();
sorted
: используется для сортировки.Stream<String> stream = list.stream().sorted();
peek
: используется для просмотра каждого элемента во время обработки.Stream<String> stream = list.stream().peek(System.out::println);
Терминальные операции используются для запуска расчета Stream и генерации результатов. К общим терминальным операциям относятся следующие:
forEach
: выполнить операцию над каждым элементом.list.stream().forEach(System.out::println);
collect
: Преобразование потока в другие формы.List<String> result = list.stream().collect(Collectors.toList());
reduce
: Преобразовать элементы в потоке в значение.Optional<String> result = list.stream().reduce((s1, s2) -> s1 + s2);
toArray
:Преобразовать поток в массив.String[] array = list.stream().toArray(String[]::new);
count
: подсчитать количество элементов.long count = list.stream().count();
anyMatch
、allMatch
、noneMatch
: Используется для сопоставления решений.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
: используется для поиска элементов.Optional<String> first = list.stream().findFirst();
Optional<String> any = list.stream().findAny();
использоватьsorted
Метод сортирует поток и может передаваться в компаратор.
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());
использоватьfilter
Метод фильтрации элементов в Stream.
List<String> list = Arrays.asList("a", "b", "c");
List<String> filteredList = list.stream().filter(s -> s.startsWith("a")).collect(Collectors.toList());
использоватьmap
Метод отображает элементы в потоке.
List<String> list = Arrays.asList("a", "b", "c");
List<String> mappedList = list.stream().map(String::toUpperCase).collect(Collectors.toList());
использоватьreduce
Метод уменьшения элементов в потоке.
List<String> list = Arrays.asList("a", "b", "c");
String result = list.stream().reduce("", (s1, s2) -> s1 + s2);
использоватьcollect
Методы преобразуют Stream в другие формы.
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 может в полной мере использовать преимущества многоядерных процессоров для повышения эффективности обработки данных.можешь использоватьparallelStream
Метод создает параллельный поток.
List<String> list = Arrays.asList("a", "b", "c");
List<String> parallelList = list.parallelStream().map(String::toUpperCase).collect(Collectors.toList());
Также можно использоватьparallel
Метод преобразует обычный поток в параллельный поток.
List<String> list = Arrays.asList("a", "b", "c");
List<String> parallelList = list.stream().parallel().map(String::toUpperCase).collect(Collectors.toList());
Следует отметить, что параллельный Stream не всегда быстрее последовательного Stream, и его необходимо тестировать в соответствии с конкретной ситуацией.
Учитывая коллекцию строк, отфильтруйте строки, длина которых меньше 3, и преобразуйте оставшиеся строки в верхний регистр.
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]
Учитывая набор целых чисел, вычислите среднее значение всех целых чисел.
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
Использование API потока
Прочитайте содержимое файла и выведите на консоль.
try (Stream<String> lines = Files.lines(Paths.get("example.txt"))) {
lines.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
Прочитайте содержимое файла и подсчитайте количество вхождений каждого слова.
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();
}
Допустим, у нас есть таблица базы данных.users
, содержащий поляid
、name
иage
. Мы можем использовать Stream API для обработки результатов запроса.
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
В классе представлены разнообразные коллекторы, и вы можете выбрать подходящий коллектор в соответствии с конкретными потребностями.После использования потока его нельзя использовать снова. Если вам нужно использовать его повторно, вы можете рассмотреть возможность преобразования потока в коллекцию перед его использованием.
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
stream.forEach(System.out::println);
stream.forEach(System.out::println); // 会抛出IllegalStateException
Параллельные потоки не всегда быстрее последовательных потоков, и их необходимо тестировать в каждом конкретном случае.можешь использоватьForkJoinPool
Чтобы оптимизировать производительность параллельного Stream.
ForkJoinPool customThreadPool = new ForkJoinPool(4);
customThreadPool.submit(() ->
list.parallelStream().forEach(System.out::println)
).get();
При использовании Stream API для обработки больших объемов данных необходимо обратить внимание на проблему утечек памяти.можешь использоватьclose
метод, чтобы закрыть поток, или использоватьtry-with-resources
оператор автоматически закрывает Stream.
try (Stream<String> lines = Files.lines(Paths.get("example.txt"))) {
lines.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
В этой статье подробно описывается использование Java Stream API, включая базовые операции, расширенные операции, параллельную обработку, практические примеры и лучшие практики. Рационально используя Stream API, разработчики могут значительно упростить код, улучшить читаемость и удобство сопровождения кода, а также повысить эффективность обработки данных. Я надеюсь, что эта статья поможет вам использовать Stream API при разработке Java.
Java Stream API — мощный инструмент для обработки данных коллекции. Благодаря гибкому использованию различных операций можно добиться эффективной обработки данных и потоковых вычислений. Если вы еще не использовали Stream API, рекомендуется как можно скорее изучить и освоить этот мощный инструмент и применить его в своем проекте, чтобы повысить эффективность разработки и качество кода.