Guavaって便利なの?

docs

前回に引き続き、今回も便利なライブラリ**「Guava」**について紹介するよ!


Guavaって、ぶっちゃけ何?

Guava(グァバって読むよ)は、Googleが作って公開している、Javaの標準ライブラリを「もっと便利に、もっと使いやすく」拡張してくれるユーティリティライブラリなんだ。Java開発でよくある「あー、これ標準でできないのかな?」みたいなかゆいところに手が届く機能がたくさん詰まっているんだよ。

例えるなら、DIYをする時に、標準のドライバーセットだけじゃなくて、もっと特殊なネジに対応できるドライバーとか、電動ドリルとか、万能なプライヤーとか、「あったら嬉しい道具」を詰め合わせた工具箱みたいなものかな。これがあれば、作業がぐっと楽になるよね? Guavaもそれと同じで、Javaでのプログラミング作業を効率化してくれるんだ。

じゃあ、Guavaを使うとどんないいことがあるんだろう? 主なメリットはこれ!

  1. コードが簡潔になる:冗長なコードを減らし、より少ない行数で同じ処理を書けるようになる。
  2. バグが減る:NullPointerException (通称: ぬるぽ) のような、Javaでよくあるエラーを防ぐための機能が充実している。
  3. パフォーマンスが向上する:Google内部で最適化されたアルゴリズムが使われているから、効率的な処理ができる。

Guavaのすごいところを見てみよう!

Guavaには本当にたくさんの機能があるんだけど、今回は特に「これは便利!」と感じるであろう代表的なモジュールをいくつかピックアップして紹介するね。

1. Collections (コレクション)

JavaのListSetMapといったコレクションはよく使うよね。でも、たまに「もっとこんな機能があったらな〜」って思うことない? GuavaのCollectionsは、そんな願いを叶えてくれるんだ。

a. 不変コレクション (Immutable Collections)

コレクションを作った後に、中身を変更されたくない時ってあるよね。例えば、設定情報を保持するリストとか、一度作ったら絶対に変更されないデータとか。そんな時に便利なのが不変コレクションだよ。変更しようとするとエラーになるから、意図しない書き換えを防げるんだ。

Java

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;

public class ImmutableCollectionsExample {
    public static void main(String[] args) {
        // ImmutableListの作成
        ImmutableList<String> immutableList = ImmutableList.of("Apple", "Banana", "Orange");
        System.out.println("ImmutableList: " + immutableList);

        // ImmutableListは変更できない(実行時にUnsupportedOperationExceptionが発生)
        // immutableList.add("Grape"); // ←コメントアウトを外すとエラーになるよ!

        // ImmutableSetの作成
        ImmutableSet<Integer> immutableSet = ImmutableSet.of(1, 2, 3, 1); // 重複は自動で削除される
        System.out.println("ImmutableSet: " + immutableSet);

        // ImmutableMapの作成
        ImmutableMap<String, Integer> immutableMap = ImmutableMap.of("Alice", 25, "Bob", 30);
        System.out.println("ImmutableMap: " + immutableMap);

        // 不変コレクションをメソッドの引数として渡すことで、
        // 呼び出し元がコレクションを変更しないことを保証できる
        processList(immutableList);
    }

    public static void processList(ImmutableList<String> list) {
        System.out.println("処理中のリスト: " + list);
        // ここでリストを変更しようとしても、コンパイルエラーや実行時エラーになるので安全
        // list.add("Pineapple");
    }
}

ImmutableList.of()のように簡単に作れて、一度作ったら変更できないから、マルチスレッド環境でも安全に扱えるのが大きなメリットだよ。

b. マルチマップ (Multimap)

JavaのMapは、1つのキーに対して1つの値をマッピングするよね。でも、「1つのキーに対して複数の値を持ちたい」なんて思うことはないかな? 例えば、「都道府県」をキーにして、そこに属する「市区町村」を複数持ちたい場合とか。そんな時に便利なのがMultimapだよ。

Java

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;

public class MultimapExample {
    public static void main(String[] args) {
        Multimap<String, String> prefectureCityMap = ArrayListMultimap.create();

        // キー「東京都」に複数の値を追加
        prefectureCityMap.put("東京都", "千代田区");
        prefectureCityMap.put("東京都", "新宿区");
        prefectureCityMap.put("東京都", "渋谷区");

        // キー「大阪府」に複数の値を追加
        prefectureCityMap.put("大阪府", "大阪市");
        prefectureCityMap.put("大阪府", "堺市");

        System.out.println("東京都の市区町村: " + prefectureCityMap.get("東京都"));
        System.out.println("大阪府の市区町村: " + prefectureCityMap.get("大阪府"));
        System.out.println("京都府の市区町村: " + prefectureCityMap.get("京都府")); // 空のリストが返る

        // 全てのエントリをイテレート
        for (String city : prefectureCityMap.values()) {
            System.out.println("すべての市区町村: " + city);
        }

        // キーごとのエントリをイテレート
        for (String prefecture : prefectureCityMap.keySet()) {
            System.out.println(prefecture + " には " + prefectureCityMap.get(prefecture) + " があります。");
        }
    }
}

ArrayListMultimapを使うと、putするたびに値が追加されていくんだ。getすると、そのキーに関連付けられた値のリストが返ってくる。これ、便利だよね!

2. Optional (オプショナル)

Javaで一番多いエラーの一つがNullPointerException(ぬるぽ)だと言っても過言じゃない。メソッドがnullを返したときに、それをチェックせずに使うと発生しちゃうやつだね。GuavaのOptionalは、このnull問題をスマートに解決してくれるんだ。

Optionalは、「値があるかもしれないし、ないかもしれない」という状態を明確に表現するためのコンテナなんだ。

Java

import com.google.common.base.Optional;

public class OptionalExample {

    public static Optional<String> findUserName(long userId) {
        // 実際はデータベースなどからユーザー名を検索する処理
        if (userId == 123) {
            return Optional.of("Alice"); // 値がある場合
        } else if (userId == 456) {
            return Optional.of("Bob");
        } else {
            return Optional.absent(); // 値がない場合 (nullの代わりにOptional.absent()を使う)
        }
    }

    public static void main(String[] args) {
        // ユーザーID 123の場合
        Optional<String> user1 = findUserName(123);
        if (user1.isPresent()) { // 値が存在するかどうかをチェック
            System.out.println("ユーザー1の名前: " + user1.get()); // 値を取得
        } else {
            System.out.println("ユーザー1は見つかりませんでした。");
        }

        // ユーザーID 789の場合
        Optional<String> user2 = findUserName(789);
        if (user2.isPresent()) {
            System.out.println("ユーザー2の名前: " + user2.get());
        } else {
            System.out.println("ユーザー2は見つかりませんでした。");
        }

        // 値がない場合にデフォルト値を指定 (nullチェック不要)
        String userNameOrDefault = findUserName(999).or("Guest");
        System.out.println("ユーザー999の名前 (デフォルト値): " + userNameOrDefault);

        // Java 8以降のOptionalとほとんど同じ考え方だけど、Guavaの方が歴史が長く、
        // さらに多くのユーティリティメソッドを持っている場合もあるよ。
    }
}

Optional.of()で値がある場合、Optional.absent()で値がない場合を表現するんだ。そして、isPresent()で値の有無をチェックしたり、get()で値を取得したり、or()で値がない場合のデフォルト値を指定したりできる。これを使えば、いちいちif (value != null)って書かなくて済むから、コードがすごくスッキリするし、NullPointerExceptionの発生を未然に防げるようになるんだ!

3. Hashing (ハッシュ)

データの完全性をチェックしたり、高速な検索を実現したりするために、データをハッシュ化する場面って意外と多いんだ。GuavaのHashingモジュールは、MD5やSHA-256といった標準的なハッシュ関数を簡単に使えるようにしてくれるよ。

Java

import com.google.common.hash.Hashing;
import com.google.common.base.Charsets;

public class HashingExample {
    public static void main(String[] args) {
        String data = "Hello, Guava Hashing!";

        // MD5ハッシュの計算
        String md5Hash = Hashing.md5()
                                .hashString(data, Charsets.UTF_8)
                                .toString();
        System.out.println("MD5 Hash: " + md5Hash);

        // SHA-256ハッシュの計算
        String sha256Hash = Hashing.sha256()
                                   .hashString(data, Charsets.UTF_8)
                                   .toString();
        System.out.println("SHA-256 Hash: " + sha256Hash);

        // ファイルの内容のハッシュを計算することもできる
        // FileInputStream inputStream = new FileInputStream("my_file.txt");
        // String fileHash = Hashing.sha256()
        //                           .hashBytes(ByteStreams.toByteArray(inputStream))
        //                           .toString();
        // System.out.println("File Hash: " + fileHash);
    }
}

Hashing.md5()Hashing.sha256()のように直感的に使えるのがいいところだね。データの送信前後でハッシュ値を比較することで、データが改ざんされていないかを簡単に確認できるよ。


Guavaを使い始めるには?

Guavaは、MavenやGradleといったビルドツールを使っていれば、依存関係に追加するだけで簡単に使えるようになるよ。

例えば、Mavenを使っているなら、pom.xmlに以下の行を追加するだけ!

XML

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>33.0.0-jre</version>
</dependency>

Gradleなら、build.gradleにこれ!

Gradle

dependencies {
    implementation 'com.google.guava:guava:33.0.0-jre' // 最新バージョンは適宜確認してね
}

ね、簡単でしょ?


まとめ

今回はJava開発を強力にサポートしてくれるユーティリティライブラリ「Guava」について紹介したよ。

  • GuavaはJavaの標準ライブラリを拡張し、コードを簡潔に、バグを少なく、パフォーマンス良くするための便利なツール。
  • 特に、不変コレクションマルチマップといったコレクションの拡張機能、null安全を実現するOptional、そしてハッシュ計算などが非常に便利。
  • MavenやGradleで簡単にプロジェクトに追加できる。

Guavaは、今回紹介した以外にも、文字列処理、キャッシュ、プリミティブ型ユーティリティなど、本当にたくさんの便利な機能を提供しているんだ。Javaを書き始めたばかりの君も、少しずつGuavaの機能に触れてみて、その便利さを実感してみてほしいな!きっと、君のプログラミングライフがもっと快適になるはずだよ。


次の記事も読んでくれると嬉しいな!

コメント

タイトルとURLをコピーしました