1. Verificando
Acho que você já deve estar entediado em aprender como encadear fluxos de dados. Você quer finalmente fazer algo com os dados.
A Stream
classe tem três métodos padrão que não constroem fluxos, mas verificam que tipo de dados estão neles. Esses métodos são: anyMatch()
, allMatch()
, e noneMatch()
.
boolean anyMatch(rule)
método
Este método verifica se o stream possui pelo menos um elemento que satisfaça a regra que é passada para o método. Se houver tal elemento, o método retorna true
, caso contrário false
.
Exemplos
Código | Observação |
---|---|
|
|
|
|
|
|
No último exemplo, primeiro retemos apenas os elementos menores que zero e, em seguida, verificamos o resultado para ver se algum dos elementos filtrados é maior que zero. Claro, esses elementos não estão mais lá.
Método booleano allMatch(rule)
Esse método verifica se todos os elementos no fluxo correspondem à regra (também conhecida como predicado). A regra é passada como um argumento para o método:
Código | Observação |
---|---|
|
(todos os elementos maiores que zero) |
|
(existem elementos menores ou iguais a zero?) |
|
(mantivemos os elementos que são menores que zero) |
No último exemplo, primeiro permitimos que apenas elementos menores que zero passem pelo filtro e, em seguida, verificamos se todos os elementos retidos são menores que zero. A verificação produz um resultado positivo.
método booleano noneMatch(rule)
O noneMatch()
método verifica se o fluxo não possui elementos que correspondam à regra aprovada. É como o oposto do anyMatch()
método.
Código | Observação |
---|---|
|
|
|
|
|
|
2. Classes utilitárias: Optional
classe
Às vezes é muito inconveniente para os programadores trabalhar com null
referências. Por exemplo, suponha que você esteja comparando duas strings. Se ambas as variáveis não forem null
, você pode simplesmente chamar s1.equals(s2)
, e tudo funcionará. Mas se s1
puder ser null
, então você tem que escrever um código que lide com esta situação para evitar um erro NullPointerException
.
É por isso que os programadores criaram a Optional<T>
classe utilitária. Seu código é mais ou menos assim:
Código | Observação |
---|---|
|
Verifica se o valor não é null Verifica se o valor é null Retorna o valor armazenado. Lança uma exceção se o valor for nulo. Retorna o valor não nulo armazenado. Ou se o valor armazenado for null , retorna o valor passado como um argumento de método. Retorna o valor não nulo armazenado ou lança uma exceção se o valor for nulo. |
O propósito desta classe é simplesmente armazenar um objeto T (uma referência a um objeto cujo tipo é T). A referência de objeto dentro de um Optional<T>
objeto pode ser null
.
Essa classe permite que os programadores escrevam um código um pouco mais bonito. Vamos comparar:
Usando Opcional | Não usando Opcional |
---|---|
|
|
Um Optional
objeto sempre pode ser comparado a outro Optional
objeto usando o equals
método, mesmo que armazenem null
referências.
Simplificando, a Optional
classe permite que você escreva verificações "bonitas" null
e ações "bonitas" no caso de um Optional
objeto armazenar um null
valor.
3. Encontrar elementos
Vamos voltar para a Stream
aula. A Stream
classe tem mais 4 métodos que permitem pesquisar elementos em um fluxo. Esses métodos são findFirst()
, findAny()
, min()
e max()
.
Optional<T> findFirst()
método
O findFirst()
método simplesmente retorna o primeiro elemento no fluxo. Isso é tudo que ele faz.
A coisa mais interessante a notar aqui é que o método não retorna um T
objeto, mas sim um Optional<T>
objeto wrapper. Isso garante que o método nunca retornará null
após falhar em localizar um objeto.
Exemplo:
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String str = list.stream().findFirst().get(); // Hello
Para maior esclarecimento, vamos quebrar a última linha em várias linhas:
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
Stream<String> stream = list.stream();
Optional<String> result = stream.findFirst();
String str = result.get(); // Hello
O último get()
método é simplesmente recuperar o valor armazenado dentro do Optional
objeto.
Optional<T> findAny()
método
O findAny()
método retorna qualquer elemento do stream e termina ali. Esse método é semelhante ao findFirst()
, mas é ótimo para fluxos usados em operações paralelas.
Ao processar fluxos em paralelo, pode ser que um elemento já tenha sido encontrado em alguma parte de um fluxo, mas ainda não está claro se é o primeiro ou não.
Se muitos elementos corresponderem a todos os filtros e for importante para o programador obter exatamente o primeiro deles, o findFirst()
método é o que deve ser chamado. Se o programador souber que, na realidade, 0 ou 1 elemento corresponderá a todos os filtros, basta simplesmente chamar findAny()
- e isso será mais rápido.
Optional<T> min(Comparator<T>)
método
O min()
método usa um comparator
objeto para comparar todos os elementos no fluxo e retorna o elemento mínimo. A maneira mais conveniente de definir um objeto comparador é com uma função lambda.
Exemplo de busca pela string mais curta:
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String min = list.stream().min( (s1, s2)-> s1.length()-s2.length() ).get();
Optional<T> max(Comparator<T>)
método
O max()
método usa um comparator
objeto para comparar todos os elementos no fluxo e retorna o elemento máximo. A maneira mais conveniente de definir um objeto comparador é com uma função lambda.
Exemplo de busca pela string mais longa:
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String max = list.stream().max( (s1, s2)-> s1.length()-s2.length() ).get();
GO TO FULL VERSION