Goiaba 18: O que há de novo?

Goiaba 18: O que há de novo?

1. Visão geral

Google Guava fornece bibliotecas com utilitários que facilitam o desenvolvimento Java. Neste tutorial, daremos uma olhada nas novas funcionalidades introduzidas noGuava 18 release.

2. MoreObjects Classe de Utilidade

Guava 18 viu a adição da classeMoreObjects, que contém métodos que não possuem equivalentes emjava.util.Objects.

A partir da versão 18, ele contém apenas implementações do métodotoStringHelper, que pode ser usado para ajudá-lo a construir seus próprios métodostoString.

  • toStringHelper (Classe clazz)

  • toStringHelper (Object self)

  • toStringHelper (String className)

Normalmente,toString() é usado quando você precisa enviar algumas informações sobre um objeto. Normalmente, deve conter detalhes sobre o estado atual do objeto. Usando uma das implementações detoStringHelper, você pode construir facilmente uma mensagemtoString() útil.

Suponha que temos um objetoUser contendo alguns campos que precisam ser escritos quandotoString() é chamado. Podemos usar o métodoMoreObjects.toStringHelper(Object self) para fazer isso facilmente.

public class User {

    private long id;
    private String name;

    public User(long id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
            .add("id", id)
            .add("name", name)
            .toString();
    }
}

Aqui usamos o métodotoStringHelper(Object self). Com essa configuração, podemos criar um usuário de amostra para ver a saída resultante ao chamartoString().

User user = new User(12L, "John Doe");
String userState = user.toString();
// userState: User{ id=12,name=John Doe }

As outras duas implementações retornarão o mesmoString se configuradas de forma semelhante:

toStringHelper (Classe clazz)

@Override
public String toString() {
    return MoreObjects.toStringHelper(User.class)
        .add("id", id)
        .add("name", name)
        .toString();
}

toStringHelper (String className)

@Override
public String toString() {
    return MoreObjects.toStringHelper("User")
        .add("id", id)
        .add("name", name)
        .toString();
}

A diferença entre esses métodos é evidente se você chamartoString() em extensões da classeUser. Por exemplo, se você tiver dois tipos deUsers:AdministratorePlayer, eles produzirão uma saída diferente. __

public class Player extends User {
    public Player(long id, String name) {
        super(id, name);
    }
}

public class Administrator extends User {
    public Administrator(long id, String name) {
        super(id, name);
    }
}

Se você usartoStringHelper(Object self) na classeUser, seuPlayer.toString() retornará “Player\{id=12, name=John Doe}“. No entanto, se você usartoStringHelper(String className) outoStringHelper(Class<?> clazz),Player.toString() retornará “User\{id=12, name=John Doe}“. O nome da classe listado será a classe pai e não a subclasse.

3. Novos métodos emFluentIterable

3.1. Visão geral

FluentIterable é usado para operar com instânciasIterable de forma encadeada. Vamos ver como ele pode ser usado.

Suponha que você tenha uma lista de objetosUser, definida nos exemplos acima, e deseja filtrar essa lista para incluir apenas os usuários com 18 anos ou mais.

List users = new ArrayList<>();
users.add(new User(1L, "John", 45));
users.add(new User(2L, "Michelle", 27));
users.add(new User(3L, "Max", 16));
users.add(new User(4L, "Sue", 10));
users.add(new User(5L, "Bill", 65));

Predicate byAge = user -> user.getAge() >= 18;

List results = FluentIterable.from(users)
                           .filter(byAge)
                           .transform(Functions.toStringFunction())
                           .toList();

A lista resultante conterá as informações de John, Michelle e Bill.

3.2. FluentIterable.of(E[])

Com este método. você pode criar umFluentIterable da matriz deObject.

User[] usersArray = { new User(1L, "John", 45), new User(2L, "Max", 15) } ;
FluentIterable users = FluentIterable.of(usersArray);

Agora você pode usar os métodos fornecidos na interfaceFluentIterable.

3.3. FluentIterable.append(E…)

Você pode criar novosFluentIterable a partir dosFluentIterable existentes anexando mais elementos a eles.

User[] usersArray = {new User(1L, "John", 45), new User(2L, "Max", 15)};

FluentIterable users = FluentIterable.of(usersArray).append(
                                 new User(3L, "Sue", 23),
                                 new User(4L, "Bill", 17)
                             );

Como esperado, o tamanho doFluentIterable resultante é 4.

3.4. FluentIterable.append(Iterable<? extends E>)>

Este método se comporta da mesma forma que o exemplo anterior, mas permite adicionar todo o conteúdo de qualquer implementação existente deIterable aFluentIterable.

User[] usersArray = { new User(1L, "John", 45), new User(2L, "Max", 15) };

List usersList = new ArrayList<>();
usersList.add(new User(3L, "Diana", 32));

FluentIterable users = FluentIterable.of(usersArray).append(usersList);

Como esperado, o tamanho doFluentIterable resultante é 3.

3.5. FluentIterable.join(Joiner)

O métodoFluentIterable.join(…) produz umString que representa todo o conteúdo deFluentIterable, unido por um determinadoString.

User[] usersArray = { new User(1L, "John", 45), new User(2L, "Max", 15) };
FluentIterable users = FluentIterable.of(usersArray);
String usersString = users.join(Joiner.on("; "));

A variávelusersString conterá a saída da chamada do métodotoString() em cada elemento deFluentIterable, separados por um “;”. A classeJoiner fornece várias opções para juntar as strings.

4. Hashing.crc32c

Uma função hash é qualquer função que pode ser usada para mapear dados de tamanho arbitrário para dados de tamanho fixo. É usado em muitas áreas, como criptografia e verificação de erros nos dados transmitidos.

O métodoHashing.crc32c retorna umHashFunction que implementa oCRC32C algorithm.

int receivedData = 123;
HashCode hashCode = Hashing.crc32c().hashInt(receivedData);
// hashCode: 495be649

5. InetAddresses.decrement(InetAddress)

Este método retorna um novoInetAddress que será “um a menos” que sua entrada.

InetAddress address = InetAddress.getByName("127.0.0.5");
InetAddress decrementedAddress = InetAddresses.decrement(address);
// decrementedAddress: 127.0.0.4

6. Novos executores emMoreExecutors __

6.1. Revisão de Threading

Em Java, você pode usar vários encadeamentos para executar o trabalho. Para isso, Java possui as classesThreadeRunnable.

ConcurrentHashMap threadExecutions = new ConcurrentHashMap<>();
Runnable logThreadRun = () -> threadExecutions.put(Thread.currentThread().getName(), true);

Thread t = new Thread(logThreadRun);
t.run();

Boolean isThreadExecuted = threadExecutions.get("main");

Como esperado,isThreadExecuted serátrue. Além disso, você pode ver que esteRunnable será executado apenas no segmentomain. Se quiser usar vários threads, você pode usarExecutors diferentes para finalidades diferentes.

ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(logThreadRun);
executorService.submit(logThreadRun);
executorService.shutdown();

Boolean isThread1Executed = threadExecutions.get("pool-1-thread-1");
Boolean isThread2Executed = threadExecutions.get("pool-1-thread-2");
// isThread1Executed: true
// isThread2Executed: true

Neste exemplo, todo o trabalho enviado é executado emThreadPool threads.

O Guava fornece métodos diferentes em sua classeMoreExecutors.

6.2. MoreExecutors.directExecutor()

Este é um executor leve que pode executar tarefas no thread que chama o métodoexecute.

Executor executor = MoreExecutors.directExecutor();
executor.execute(logThreadRun);

Boolean isThreadExecuted = threadExecutions.get("main");
// isThreadExecuted: true

6.3. MoreExecutors.newDirectExecutorService()

Este método retorna uma instância deListeningExecutorService. É uma implementação mais pesada deExecutor que possui muitos métodos úteis. É semelhante ao métodosameThreadExecutor() obsoleto das versões anteriores do Guava.

EsteExecutorService executará tarefas no encadeamento que chama o métodoexecute().

ListeningExecutorService executor = MoreExecutors.newDirectExecutorService();
executor.execute(logThreadRun);

Este executor possui muitos métodos úteis, comoinvokeAll, invokeAny, awaitTermination, submit, isShutdown, isTerminated, shutdown, shutdownNow.

7. Conclusão

O Guava 18 introduziu várias adições e melhorias em sua crescente biblioteca de recursos úteis. Vale a pena considerar o uso em seu próximo projeto. Os exemplos de código neste artigo estão disponíveisin the GitHub repository.