minhas informações de contato
Correspondência[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Java 8 introduz muitos recursos novos, sendo os mais notáveis as expressões Lambda e a API Stream. A API Stream fornece um método eficiente e conciso para processar dados de coleta, tornando o código mais conciso e claro, além de possuir alta legibilidade e facilidade de manutenção. Este artigo se aprofundará no uso da API Java Stream, incluindo conceitos básicos, operações comuns, processamento paralelo, casos práticos e práticas recomendadas.
A API Stream é uma abstração introduzida no Java 8 para processar dados de coleta que permite que os dados sejam processados de maneira declarativa (semelhante às instruções SQL). A API Stream fornece muitas operações poderosas que podem ser usadas para filtrar, classificar, mapear, reduzir e outras operações em coleções, simplificando bastante o código.
A API Stream fornece uma variedade de maneiras de criar um Stream. As mais comuns incluem o seguinte:
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);
As operações intermediárias são usadas para converter Stream e são avaliadas lentamente. As operações intermediárias comuns incluem o seguinte:
filter
: usado para filtrar elementos.Stream<String> stream = list.stream().filter(s -> s.startsWith("a"));
map
: usado para mapear cada elemento para o resultado correspondente.Stream<String> stream = list.stream().map(String::toUpperCase);
flatMap
: usado para converter cada elemento em um Stream e depois mesclá-lo em um Stream.Stream<String> stream = list.stream().flatMap(s -> Stream.of(s.split("")));
distinct
: Usado para remover duplicatas.Stream<String> stream = list.stream().distinct();
sorted
: usado para classificação.Stream<String> stream = list.stream().sorted();
peek
: Usado para visualizar cada elemento durante o processamento.Stream<String> stream = list.stream().peek(System.out::println);
As operações de terminal são usadas para iniciar o cálculo do Stream e gerar resultados. As operações de terminal comuns incluem o seguinte:
forEach
: Execute uma operação em cada elemento.list.stream().forEach(System.out::println);
collect
: Converta Stream para outros formulários.List<String> result = list.stream().collect(Collectors.toList());
reduce
: reduza os elementos do Stream em um valor.Optional<String> result = list.stream().reduce((s1, s2) -> s1 + s2);
toArray
:Converter fluxo em array.String[] array = list.stream().toArray(String[]::new);
count
: conte o número de elementos.long count = list.stream().count();
anyMatch
、allMatch
、noneMatch
: Usado para julgamento correspondente.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
: Usado para encontrar elementos.Optional<String> first = list.stream().findFirst();
Optional<String> any = list.stream().findAny();
usarsorted
O método classifica o Stream e pode passar um comparador.
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());
usarfilter
Método para filtrar elementos no Stream.
List<String> list = Arrays.asList("a", "b", "c");
List<String> filteredList = list.stream().filter(s -> s.startsWith("a")).collect(Collectors.toList());
usarmap
O método mapeia elementos no Stream.
List<String> list = Arrays.asList("a", "b", "c");
List<String> mappedList = list.stream().map(String::toUpperCase).collect(Collectors.toList());
usarreduce
Método para reduzir os elementos do Stream.
List<String> list = Arrays.asList("a", "b", "c");
String result = list.stream().reduce("", (s1, s2) -> s1 + s2);
usarcollect
Os métodos convertem Stream em outros formulários.
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(","));
O Parallel Stream pode aproveitar ao máximo as vantagens das CPUs multi-core para melhorar a eficiência do processamento de dados.pode usarparallelStream
O método cria Stream paralelo.
List<String> list = Arrays.asList("a", "b", "c");
List<String> parallelList = list.parallelStream().map(String::toUpperCase).collect(Collectors.toList());
Também pode ser usadoparallel
O método converte um Stream normal em um Stream paralelo.
List<String> list = Arrays.asList("a", "b", "c");
List<String> parallelList = list.stream().parallel().map(String::toUpperCase).collect(Collectors.toList());
Deve-se observar que o Stream paralelo nem sempre é mais rápido que o Stream serial e precisa ser testado de acordo com a situação específica.
Dada uma coleção de strings, filtre as strings cujo comprimento seja menor que 3 e converta as strings restantes em maiúsculas.
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]
Dado um conjunto de inteiros, calcule a média de todos os inteiros.
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
Usando a API Stream
Leia o conteúdo do arquivo e envie-o para o console.
try (Stream<String> lines = Files.lines(Paths.get("example.txt"))) {
lines.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
Leia o conteúdo do arquivo e conte o número de ocorrências de cada palavra.
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();
}
Digamos que temos uma tabela de banco de dadosusers
, contendo camposid
、name
eage
. Podemos usar a API Stream para processar os resultados da consulta.
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
A classe oferece uma variedade de coletores, e você pode escolher o coletor adequado de acordo com necessidades específicas.Depois que um Stream é consumido, ele não pode ser usado novamente. Se precisar reutilizá-lo, considere converter o Stream em uma coleção antes de usá-lo.
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
stream.forEach(System.out::println);
stream.forEach(System.out::println); // 会抛出IllegalStateException
Os fluxos paralelos nem sempre são mais rápidos que os fluxos seriais e precisam ser testados caso a caso.pode usarForkJoinPool
Para otimizar o desempenho do Stream paralelo.
ForkJoinPool customThreadPool = new ForkJoinPool(4);
customThreadPool.submit(() ->
list.parallelStream().forEach(System.out::println)
).get();
Ao usar a API Stream para processar grandes quantidades de dados, você precisa prestar atenção ao problema de vazamento de memória.pode usarclose
método para fechar o Stream ou usartry-with-resources
a instrução fecha automaticamente o Stream.
try (Stream<String> lines = Files.lines(Paths.get("example.txt"))) {
lines.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
Este artigo apresenta detalhadamente o uso da API Java Stream, incluindo operações básicas, operações avançadas, processamento paralelo, casos práticos e práticas recomendadas. Ao utilizar racionalmente a API Stream, os desenvolvedores podem simplificar bastante o código, melhorar a legibilidade e a capacidade de manutenção do código e também melhorar a eficiência do processamento de dados. Espero que este artigo seja útil para o uso da API Stream no desenvolvimento Java.
A API Java Stream é uma ferramenta poderosa para processar dados de coleta. Através do uso flexível de várias operações, o processamento eficiente de dados e a computação de streaming podem ser alcançados. Se você ainda não usou a API Stream, é recomendável aprender e dominar esta ferramenta poderosa o mais rápido possível e aplicá-la ao seu projeto para melhorar a eficiência do desenvolvimento e a qualidade do código.