ganhando_produtividade_com_Stream_API_Java
ganhando_produtividade_com_Stream_API_Java copied to clipboard
Duvida desafio 7
Boa tarde, prô!
Estou com dúvida no exercicio 7, como localizar o segundo maior valor da lista usando stream, qual seria a maneira correta usando stream? pensei em organizar do menor para o maior, contar a quantidade de elementos da stream e usar o skip para pular ate o penultimo, mas nao parece ser a maneira correta...
int segundoMaior = numeros.stream().sorted().toList().get(11);
Fiz desse jeito, na prática deu certo, mas como disse, não parece a maneira correta...
System.out.println(nums.stream().distinct().sorted((a, b) -> b.compareTo(a)).skip(1).findFirst().orElse(null));
Fiz assim. Tive que usar um recurso de optional, mesmo não assistindo o vídeo sobre essa parte ainda. Mas acho que ficou mais dinâmico, visto que você pode adicionar números na lista depois e o código ainda assim retornar o resultado correto.
Boa tarde, @thiagovanzele. Parabéns pelos estudos, viu? Está indo bem!
Deixa eu te mostrar uma forma de fazer. Lembrando que existem outras formas:
- Removemos elementos repetidos com
distinct()para garantir que a lista tem apenas elementos únicos. - Ordenamos os números na ordem decrescente com
sorted(Comparator.reverseOrder()), - Depois pulamos o primeiro número com
skip(1) - Encontramos o primeiro elemento após o pulo com
findFirst() - Como o
findFirst()retorna umOptional, precisamos tratar. Usei aqui o métodoorElse(null)para obter o valor caso exista. Caso contrário, retornanull.
List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 5, 4, 3);
Integer segundoNumero = numeros.stream()
.distinct() // Remove elementos repetidos
.sorted(Comparator.reverseOrder()) // Ordena os números na ordem decrescente
.skip(1) // Pula o primeiro número
.findFirst() // Encontra o primeiro elemento após o pulo
.orElse(null); // Se não encontrar, retorna null
Se ficou alguma dúvida, me avisa que fazemos de outras formas. (:
Parabéns pela resposta, @siqueirarxd. Muito bom! (:
Não sei se você conhece, mas você também poderia utilizar o método orElseThrow(). Porque daí, já lançamos uma exception caso não exista um segundo maior número.
Exemplo de solução:
List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 5, 4, 3);
Integer segundoNumero = numeros.stream()
.distinct() // Remove elementos repetidos
.sorted(Comparator.reverseOrder()) // Ordena os números na ordem decrescente
.skip(1) // Pula o primeiro número
.findFirst() // Encontra o primeiro elemento após o pulo
.orElseThrow(() -> new NoSuchElementException("Não existe segundo maior número."));
Bons estudos para nós!
Outra maneira de resolver seria ordenando o array de forma crescente e pegando o penúltimo elemento, consequentemente o segundo mais alto. Utilizando também o distinct() para que ele não pegue o elemento mais alto caso o mais alto se repita.
List<Integer> numerosOrdenado = numeros.stream()
.sorted()
.distinct()
.collect(Collectors.toList());
int segundoMaisAlto = numerosOrdenado.get(numerosOrdenado.size() - 2));
Massa, @willianac. Parabéns! Não tinha pensando em resolver desse jeito. Aprendi mais uma! Obrigada por compartilhar. <3
Olha como ficou o meu...
public class Desafio7 {
public static void main(String[] args) {
List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 5, 4, 10);
Optional<Integer> primeiroMaior = numeros.stream().max(Integer::compareTo);
Integer x = numeros.stream().reduce(0, (Integer n, Integer n2)-> {
return (n2 > n && n2 < primeiroMaior.get()) ? n2 : n;
});
System.out.println("Numero reduce: " + x);
}
}
Parabéns, @jpvalim. Só ficou um mais complexa a solução. Mas chegando no resultado, ótimo! Mais uma vez parabéns pelos estudos! (:
Usei o limit hehe
numbers.stream().sorted(Collections.reverseOrder()).skip(1).limit(1).forEach(System.out::println);