DEV Community

Paulo Porto
Paulo Porto

Posted on • Edited on

Evolução da linguagem Java (parte 2)

Neste artigo damos continuidade à nossa análise histórica sobre os recursos que cada versão do Java trouxe para tornar o código mais limpo e simples para o desenvolvedor.

Se você caiu de paraquedas aqui e ainda não leu a primeira parte, clique aqui.

Java 9

Nesta versão ganhamos métodos para criar coleções, métodos privados em interfaces, novos métodos para Streams API (takeWhile, dropWhile e iterate) e Optional (ifPresentOrElse, or, stream) e melhoria no Try-with-resources.

Novos métodos para criar coleções

Os novos métodos nos permite criar coleções imutáveis com mais facilidade.

// Antes
List<String> lista = Arrays.asList("A", "B", "C");

// Java 9
List<String> lista = List.of("A", "B", "C");
Set<Integer> set = Set.of(1, 2, 3);
Map<String, Integer> mapa = Map.of("um", 1, "dois", 2);
Enter fullscreen mode Exit fullscreen mode

Arrays.asList não era imutável.

Novos métodos para Streams API

O takeWhile serve para pegar elementos de um stream até que a condição seja falsa pela primeira vez.

List<Integer> nums = List.of(1, 2, 3, 4, 5, 6, 7, 8);

List<Integer> resultado = nums.stream()
    .takeWhile(n -> n < 5)
    .collect(Collectors.toList());

System.out.println(resultado); // [1, 2, 3, 4]
Enter fullscreen mode Exit fullscreen mode

Se a lista não estiver ordenada o takeWhile para na primeira condição de falha.

List<Integer> nums = List.of(1, 2, 6, 3, 4);

List<Integer> resultado = nums.stream()
    .takeWhile(n -> n < 5)
    .collect(Collectors.toList());

System.out.println(resultado); // [1, 2]
Enter fullscreen mode Exit fullscreen mode

O dropWhile é o oposto do takeWhile. Ele descarta os elementos enquanto a condição for verdadeira.

List<Integer> nums = List.of(1, 2, 3, 4, 5, 6, 7);

List<Integer> resultado = nums.stream()
    .dropWhile(n -> n < 5)
    .collect(Collectors.toList());

System.out.println(resultado); // [5, 6, 7]
Enter fullscreen mode Exit fullscreen mode

Como no takeWhile, em listas desordenadas o dropWhile para na primeira falha.

List<Integer> nums = List.of(2, 4, 6, 3, 1, 5);

List<Integer> resultado = nums.stream()
    .dropWhile(n -> n % 2 == 0)
    .collect(Collectors.toList());

System.out.println(resultado); // [3, 1, 5]
Enter fullscreen mode Exit fullscreen mode

O iterate não é novo (veio no pacote do Java 8) mas no Java 9 ganhou uma nova versão com mais um parâmetro.

// Antes
Stream<Integer> numeros = Stream.iterate(1, n -> n + 2)
                                .limit(5);

numeros.forEach(System.out::println);
// Saída: 1, 3, 5, 7, 9

// Com Java 9
Stream<Integer> numeros = Stream.iterate(
    1,                // valor inicial
    n -> n < 20,      // condição de parada
    n -> n + 2        // passo
);

numeros.forEach(System.out::println);
// Saída: 1, 3, 5, 7, 9, 11, 13, 15, 17, 19
Enter fullscreen mode Exit fullscreen mode

Novos métodos para Optional

O ifPresentOrElse executa uma função quando o valor do optional está presente ou outra função quando o valor está ausente.

Optional<String> nome = Optional.of("Maria");

nome.ifPresentOrElse(
    n -> System.out.println("Olá " + n),         // se presente
    () -> System.out.println("Valor ausente")   // se vazio
);

// Saída: Olá Maria
Enter fullscreen mode Exit fullscreen mode

or permite fornecer outro Optional caso o valor esteja vazio.

Optional<String> nome = Optional.empty();

String resultado = nome
    .or(() -> Optional.of("Padrão"))
    .get();

System.out.println(resultado); // Padrão
Enter fullscreen mode Exit fullscreen mode

O método stream transforma o Optional em uma Stream com no máximo 1 elemento.

Optional<String> nome = Optional.of("Ana");

List<String> lista = nome.stream()
                         .map(String::toUpperCase)
                         .collect(Collectors.toList());

System.out.println(lista); // [ANA]
Enter fullscreen mode Exit fullscreen mode

Se for um Optional de uma lista, o streamgera uma Stream com um único elemento: a lista inteira.

Optional<List<String>> optLista = Optional.of(List.of("A", "B", "C"));

optLista.stream()
        .forEach(System.out::println);
// Saída [A, B, C]
Enter fullscreen mode Exit fullscreen mode

melhoria no Try-with-resources

Agora você pode usar recursos declarados antes do try.

BufferedReader br = new BufferedReader(new FileReader("dados.txt"));

try (br) {
    System.out.println(br.readLine());
}
Enter fullscreen mode Exit fullscreen mode

Métodos privados em interfaces

Podemos extrair lógica comum dentro da própria interface.

interface Validador {
    default boolean validar(String s) {
        return s != null && comum(s);
    }
    private boolean comum(String s) {
        return !s.isEmpty();
    }
}
Enter fullscreen mode Exit fullscreen mode

Java 10

O Java 10 nos trouxe o tipo var, que ajuda a aumentar a legibilidade dentro de blocos de código.

// Antes
for (Iterator<String> it = nomes.iterator(); it.hasNext();) {
    String nome = it.next();
}

// Java 10
for (var it = nomes.iterator(); it.hasNext();) {
    var nome = it.next();
}
Enter fullscreen mode Exit fullscreen mode

O var não é tipagem dinâmica como em JavaScript. O tipo continua sendo estático, definido pelo compilador no momento da atribuição.
Ele não pode ser usado em:

  • Atributos de classe
  • Parametros de métodos
  • Retorno de métodos A tipagem continua forte, apenas evita a repetição.

Para mim, os recursos do Java 9 que mais brilham para escrever código limpo são os novos métodos do Optional e os métodos para coleções imutáveis. São sem dúvida os que mais uso no meu dia a dia.

Confesso que ainda prefiro criar classes abstratas para implementar interfaces quando quero compartilhar lógica comum, porque me sinto mais seguro do que levar esse comportamento para uma interface que pode ser implementada em classes que não precisam dele.

Já os novos métodos da Streams API (como takeWhile e dropWhile) ainda não encontrei necessidade de usar em projetos reais — mas é bom saber que estão lá quando for preciso.

O var do Java 10 é um excelente recurso, e ainda estou aprendendo a aproveitá-lo melhor no dia a dia.

👉 Será que os métodos do Optional e o List.of também foram os que mais impactaram o seu dia a dia? Ou você acha que outro recurso merece mais destaque?

Clique aqui para ler a terceira parte.

Top comments (0)