12 maneiras comuns de usar fluxos Java
Fonte: Dev.to A API Java Streams apareceu pela primeira vez em Java 8. Seu objetivo é fornecer uma maneira mais compacta de realizar operações comuns em coleções de objetos. Além disso, a API Java Streams pode ser usada para implementar algoritmos complexos. Neste artigo, falaremos sobre casos de uso comuns de Java Streams. Primeiro, vamos esclarecer alguns princípios básicos:-
stream() - cria um stream da coleção.
-
collect() – coleta um fluxo em um objeto. Um objeto pode ser uma coleção, uma classe primitiva ou uma classe personalizada.
-
Collectors é uma classe que fornece (muitos) métodos estáticos para coletar streams.
1. Filtragem
-
Usado para remover valores de uma coleção com base em uma condição.
-
Para filtrar elementos da coleção com base em uma condição, use o método filter() . Apenas os elementos correspondentes são salvos.
List<Integer> evenNumbers = originalList.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
2. Pré-processamento
-
Útil quando cada valor em uma coleção precisa ser alterado.
-
O método map() é usado para aplicar uma função a cada elemento da coleção e retornar uma nova coleção de valores calculados.
List<Integer> squares = originalList.stream()
.map(n -> n * n)
.collect(Collectors.toList());
3. Conversão
-
Útil quando queremos transformar uma coleção em outra coleção.
-
Existem várias maneiras de conseguir isso.
Exemplo 1: Crie um mapa a partir de listas.
Converta uma lista de strings em um mapa de strings e comprimentos.Map<String, Integer> wordLengths = words.stream()
.collect(Collectors.toMap(
word -> word,
word -> word.length()));
Exemplo 2. Convertendo uma lista em conjuntos.
Este é um caso de uso comum para remoção de duplicatas. Além disso, se quisermos colocar os elementos de volta na lista, podemos usar os métodos stream() e collect() duas vezes . Por exemplo, vamos converter uma lista de strings em uma lista de strings exclusivas:// if we want to collect to a set
Set<String> uniqueWords = words.stream()
.collect(Collectors.toSet());
// OR
// if we want to start and end as a list
List<String> uniqueWords = words.stream()
.collect(Collectors.toSet()).stream().collect(Collectors.toList());
Exemplo 3. Convertendo uma lista de produtos em uma lista com seus nomes. (Achatamento - Alinhamento)
List<String> productNames = products.stream()
.map(product -> product.getName())
.collect(Collectors.toList());
4. Redução
-
Reduz a Coleção a um único valor.
-
O método reduz() é usado para aplicar uma função a cada elemento da coleção e retornar um único valor.
int sum = numbers.stream()
.reduce(0, (a, b) -> a + b);
5. Agrupamento
-
Agrupa os elementos de uma Coleção com base em uma determinada condição.
-
Para agrupar elementos da coleção por condição, use o método Collectors.groupingBy() .
Map<String, List<Product>> productsByCategory = products.stream()
.collect(Collectors.groupingBy(product -> product.getCategory()));
6. Descoberta
-
Pesquisa o primeiro ou qualquer elemento Collection que corresponda a uma condição.
-
Os métodos findFirst() e findAny() são usados para pesquisar .
Optional<String> firstLongWord = words.stream()
.filter(word -> word.length() > 5)
.findFirst();
// Note that findFirst() and findAny() methods return Optional<T> objects.
7. Classificação
-
Classifica os elementos das Coleções.
-
O método sorted() é usado para classificar .
List<Integer> topK = numbers.stream()
.sorted()
.limit(k)
.collect(Collectors.toList());
8. Particionamento
-
Separa os elementos de uma Coleção com base em uma determinada condição.
-
O método Collectors.partitioningBy() é usado para separar elementos .
Map<Boolean, List<Student>> passingFailing = students
.stream()
.collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
9. Contando
-
Conta o número de elementos que correspondem a uma condição.
-
O método count() é usado para contar o número de elementos que correspondem a uma condição .
long count = words.stream()
.filter(word -> word.length() > 5)
.count();
10. Alcance
-
Cria um intervalo de valores.
-
Para criar um intervalo de valores, use o método range() .
int[] numbers = IntStream.range(0, 10).toArray();
11. Correspondência
-
Combina os elementos de uma coleção com um predicado (condição).
-
Métodos como anyMatch() , allMatch() e noneMatch() são usados para combinar elementos da coleção com um predicado e retornar um valor booleano .
// true when all elements match the predicate
boolean allMatch = products.stream()
.allMatch(product -> product.getPrice() > 10);
// true when any element matches the predicate
boolean anyMatch = products.stream()
.anyMatch(product -> product.getPrice() > 10);
// true when no elements match the predicate
boolean noneMatch = products.stream()
.noneMatch(product -> product.getPrice() > 10);
12. Aderindo
-
Concatena os elementos de uma coleção em uma string.
-
Para unir elementos da coleção em uma string, use o método Collectors.joining() .
String joinedWords = words.stream()
.collect(Collectors.joining(" "));
É isso para cenários gerais. Existem outros cenários menos comuns que você pode explorar por conta própria:
- Fluxos Paralelos;
- Estatisticas;
- Coletores personalizados.
Benefícios dos tópicos
-
Código mais compacto — reduz a quantidade de código necessária para processar a coleção.
-
Menos variáveis intermediárias. Variáveis intervenientes podem causar a ocorrência de erros. Quanto menos houver, mais fácil será evitar erros inesperados.
-
Código intuitivo. Alguns desenvolvedores discordarão que os threads são mais intuitivos do que outros métodos. No entanto, quando nos acostumamos com eles, eles se tornam muito mais intuitivos do que outros métodos.
Como avaliar a alocação de memória de um objeto em Java
Fonte: DZone Este artigo mostra as três maneiras mais conhecidas de avaliar a alocação de memória de um objeto em Java.Avaliação de memória usando Profiler
A maneira mais fácil de estimar a memória de alguns objetos é examinar diretamente a memória da JVM usando um criador de perfil como o Visual VM . O problema com essa abordagem é que você precisa se conectar a uma JVM em execução, o que pode não ser possível em ambientes de produção por motivos de segurança.Avaliação de memória usando instrumentos
Outra forma de estimar a memória alocada para um determinado objeto é usar Instrumentos. Em termos simples, precisamos criar uma classe e compilá-la em um JAR. Após criar o JAR, devemos executar nossa JVM junto com esse JAR. Você pode descobrir mais sobre esse método aqui . A desvantagem aqui é a necessidade de adicionar um arquivo jar específico à JVM, o que pode não ser aceitável para produção devido a questões de segurança ou relacionadas.Avaliação de memória usando a Biblioteca JOL
Como outra opção, podemos usar a Biblioteca JOL . Esta é uma biblioteca muito poderosa que pode fornecer uma estimativa detalhada do peso de um objeto e da memória alocada por uma instância de objeto. Para usar a biblioteca, precisamos adicionar uma dependência:<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.16</version>
</dependency>
Depois disso podemos usá-lo assim:
out.println(GraphLayout.parseInstance(myObject).totalSize() / 1024000d + " MB")
ObjectSizeCalculator do arquivo do Twitter
O repositório GitHub público do Twitter possui uma classe de ferramenta chamada ObjectSizeCalculator que pode estimar a memória alocada para uma determinada instância de objeto. Não é preciso muita memória ou tempo para usar. O processo de avaliação leva segundos, mesmo para objetos grandes. Usar esta classe é bastante simples:ObjectSizeCalculator.getObjectSize(address)
Eu recomendo este método, mas lembre-se de que ele só é compatível com Java Hotspot, OpenJDK e TwitterJDK.
GO TO FULL VERSION