JavaRush /Blogue Java /Random-PT /Pausa para café #108. 12 usos comuns de fluxos Java, como...

Pausa para café #108. 12 usos comuns de fluxos Java, como avaliar a alocação de memória de um objeto em Java

Publicado no grupo Random-PT

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. Pausa para café #108.  12 usos comuns de fluxos Java, como avaliar a alocação de memória de um objeto em Java - 1Primeiro, 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.

Agora vamos ver alguns casos de uso de 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.

Exemplo: remova todos os números ímpares da lista.
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.

Por exemplo, vamos converter cada valor em seu quadrado.
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.

Conforme mencionado acima, podemos usar os métodos map() e collect() para transformar uma coleção em outra coleção.

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.

Observe que como o método reduz() retorna um único valor, ele não pode ser usado para retornar uma Coleção. Exemplo, somamos todos os valores da lista:
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() .

Por exemplo, vamos agrupar todos os produtos em listas de produtos por categorias.
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 .

Isso geralmente é semelhante a uma pesquisa linear. Por exemplo, procuramos a primeira palavra da lista cujo comprimento excede 5 caracteres.
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 .

Geralmente, Collections.sort() é suficiente para classificar uma coleção. Podemos usar sorted() especificamente se quisermos executar outra operação. Por exemplo, vamos classificar uma lista de números em ordem crescente e retornar os primeiros k elementos.
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 .

Uma divisão é semelhante a um grupo, exceto que retorna duas coleções — uma para os elementos que correspondem à condição e outra para os elementos que não correspondem à condição. Por exemplo, vamos dividir os alunos entre aqueles que passaram no exame e aqueles que foram reprovados.
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 .

Por exemplo, vamos contar o número de palavras na lista cujo comprimento excede 5 caracteres.
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() .

Existem classes especiais para criar fluxos de certos tipos – IntStream , LongStream , DoubleStream e Stream . Essas classes são úteis ao trabalhar com tipos numéricos primitivos. Para converter um array em um stream, use Arrays.stream() . Por exemplo, vamos criar uma matriz de números de 0 a 10.
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 .

Por exemplo, vamos verificar produtos com preço superior a 10.
// 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() .

Por exemplo, vamos concatenar todas as palavras de uma lista em uma string.
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.

Obrigado por ler. Espero que tenha gostado deste artigo. Existem muitos outros casos em que threads podem ser usados ​​que não são abordados neste tópico. Sinta-se à vontade para adicionar qualquer cenário comum que eu perdi.

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 . Pausa para café #108.  12 usos comuns de fluxos Java, como avaliar a alocação de memória de um objeto em Java - 2O 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.
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION