1. 概要

Google Guava は、Java開発を容易にするユーティリティをライブラリに提供します。 このチュートリアルでは、Guava18リリースで導入された新機能を見ていきます。

2. MoreObjectsユーティリティクラス

Guava 18では、 MoreObjects クラスが追加されました。このクラスには、java.util.Objectsに同等のものがないメソッドが含まれています。

リリース18の時点では、 toStringHelper メソッドの実装のみが含まれています。これは、独自のtoStringメソッドの構築に使用できます。

  • toStringHelper(Class> clazz)
  • toStringHelper(Object self)
  • toStringHelper(String className)

通常、 toString() オブジェクトに関する情報を出力する必要がある場合に使用されます通常、オブジェクトの現在の状態に関する詳細が含まれている必要があります。 toStringHelper の実装の1つを使用することにより、便利な toString()メッセージを簡単に作成できます。

toString()が呼び出されたときに書き込む必要のあるいくつかのフィールドを含むUserオブジェクトがあるとします。 MoreObjects.toStringHelper(Object self)メソッドを使用してこれを簡単に行うことができます。

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();
    }
}

ここでは、 toStringHelper(Object self)メソッドを使用しました。 この設定では、 toString()を呼び出したときに生じる出力を確認するためのサンプルユーザーを作成できます。

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

他の2つの実装は、同様に構成されている場合、同じStringを返します。

toStringHelper(Class> 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();
}

これらのメソッドの違いは、 Userクラスの拡張機能でtoString()を呼び出すと明らかです。 たとえば、ユーザーの2種類(管理者プレーヤー)がある場合、それらは異なる出力を生成します。

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);
    }
}

ユーザークラスでtoStringHelper(Object self)を使用すると、 Player.toString()は「 Player {id = 12、name = John Doe} “。 ただし、使用する場合 toStringHelper(String className) また toStringHelper(Class> clazz) Player.toString() 戻ります “ User {id = 12、name = John Doe} 「。 リストされているクラス名は、サブクラスではなく親クラスになります。

3. FluentIterableの新しいメソッド

3.1. 概要

FluentIterable は、Iterableインスタンスを連鎖的に操作するために使用されます。 使い方を見てみましょう。

上記の例で定義されたUserオブジェクトのリストがあり、そのリストをフィルタリングして18歳以上のユーザーのみを含めるとします。

List<User> 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<User> byAge = user -> user.getAge() >= 18;

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

結果のリストには、John、Michelle、およびBillの情報が含まれます。

3.2。FluentIterable.of(E [])

この方法で。 Objectの配列からFluentIterableを作成できます。

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

これで、FluentIterableインターフェースで提供されるメソッドを使用できます。

3.3。FluentIterable.append(E…)

さらに要素を追加することで、既存のFluentIterableから新しいFluentIterableを作成できます。

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

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

予想どおり、結果のFluentIterableのサイズは4です。

3.4。 FluentIterable.append(Iterable <? E>)を拡張します

このメソッドは前の例と同じように動作しますが、Iterableの既存の実装のコンテンツ全体をFluentIterableに追加できます。

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

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

FluentIterable<User> users = FluentIterable.of(usersArray).append(usersList);

予想どおり、結果のFluentIterableのサイズは3です。

3.5。FluentIterable.join(Joiner)

FluentIterable.join(…)メソッドは、 FluentIterable のコンテンツ全体を表す文字列を生成し、特定の文字列で結合します。

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

usersString 変数には、 FluentIterableの各要素でtoString()メソッドを呼び出す出力が「;」で区切られて含まれます。 Joiner クラスは、文字列を結合するためのいくつかのオプションを提供します。

4. Hashing.crc32c

ハッシュ関数は、任意のサイズのデータを固定サイズのデータにマップするために使用できる任意の関数です。 暗号化や送信データのエラーチェックなど、多くの分野で使用されています。

Hashing.crc32c メソッドは、CRC32Cアルゴリズムを実装するHashFunctionを返します。

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

5. InetAddresses.decrement(InetAddress)

このメソッドは、入力より「1つ少ない」新しいInetAddressを返します。

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

6. MoreExecutors の新しいエグゼキュータ

6.1. スレッディングレビュー

Javaでは、複数のスレッドを使用して作業を実行できます。 この目的のために、JavaにはThreadクラスとRunnableクラスがあります。

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

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

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

予想どおり、isThreadExecutedtrueになります。 また、この Runnable は、メインスレッドでのみ実行されることがわかります。 複数のスレッドを使用する場合は、さまざまな目的でさまざまなExecutorsを使用できます。

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

この例では、送信されたすべての作業はThreadPoolスレッドで実行されます。

Guavaは、MoreExecutorsクラスでさまざまなメソッドを提供しています。

6.2. MoreExecutors.directExecutor()

これは、executeメソッドを呼び出すスレッドでタスクを実行できる軽量のエグゼキュータです。

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

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

6.3. MoreExecutors.newDirectExecutorService()

このメソッドは、ListeningExecutorServiceのインスタンスを返します。 これは、 Executor のより重い実装であり、多くの便利なメソッドがあります。 これは、以前のバージョンのGuavaで廃止された sameThreadExecutor()メソッドに似ています。

このExecutorServiceは、 execute()メソッドを呼び出すスレッドでタスクを実行します。

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

このエグゼキュータには、 invokeAll、invokeAny、awaitTermination、submit、isShutdown、isTerminated、shutdown、shutdownNowなどの多くの便利なメソッドがあります。

7. 結論

Guava 18は、増え続ける便利な機能のライブラリにいくつかの追加と改善を導入しました。 次のプロジェクトでの使用を検討する価値は十分にあります。 この記事のコードサンプルは、GitHubリポジトリで入手できます。