LoginSignup
36
35

More than 5 years have passed since last update.

GuavaとJava7

Last updated at Posted at 2014-04-18

はじめに

ちょっと前になりますが、ADTが一部を除いてJava7に対応しましたね。
(try-with-resourcesはminSdkVersionの19のようですね。)

ADTプラグインの説明の22.6.0の説明
こちらのブログがとても分かりやすく書かれています。(切り身こわい)

さて、話は変わってGoogle製のJavaライブラリ、Guava
Androidでも、Android以外でもJavaでの開発に使っている方も多いのではないでしょうか?
先日、Google+のGuava公式アカウントGuava APIs obsoleted by JDK7というタイトルで投稿をしていました。

以下、Guava APIs obsoleted by JDK7より

While Guava doesn't require JDK7, there are a bunch of Guava APIs that have been obsoleted by JDK7. If you're using JDK7, you should prefer the built-in JDK7 APIs over the Guava APIs; at some point, we may remove these APIs from Guava. Here’s a list of obsoleted Guava APIs and their JDK replacements:

-instead of c.g.c.base.Charsets.UTF_8, prefer java.nio.charset.StandardCharsets.UTF_8 (same goes for the other constants in our Charsets class)
-instead of c.g.c.base.Objects.equal(), prefer java.util.Objects.equals()
-instead of c.g.c.base.Objects.hashCode(), prefer java.util.Objects.hash()
-instead of c.g.c.collect.Iterators.emptyIterator(), prefer java.util.Collections.emptyIterator()
-instead of c.g.c.primitives.Booleans.compare(), prefer java.lang.Boolean.compare() (same goes for the other compare() methods in our primitive wrapper classes)
-instead of the static factory methods for creating collections (e.g. Lists.newArrayList()), prefer the constructors with the diamond operator (e.g., new ArrayList<>())

JDK8 obsoletes a ton of Guava APIs, so we’re hard at work figuring out what a JDK8-friendly version of Guava will look like!

なるほど。
よく使うものが並んでいますね。
こちらの投稿に関するコメントで大変勉強になるものがいくつかあったので、そこで言われていたことに、自分の考えを追加してまとめました。

Objects#equalとLists#newArrayListは、無くなっちゃ悲しいし、Guavaの方が便利ですね。
という話です。

GuavaのObjects#equalとJava7のObjects#equals

次のようなコードがあるとします、

String a = getString();
String b = getString();
if(a.equals(b)){
// 略

この場合getStringがnullを返し得るならば、aがnullの場合NullPointerExceptionになってしまうので、nullでないか事前のチェックが必要です。

このようにオブジェクトがnullの場合まで含めたequlasの比較はGuavaのObjects#equalメソッドが便利です。

次のコードはGuavaのObjects.equalの使用例です。

GuavaのObjects.equal
System.out.println(Objects.equal("hoge", "hoge")); // true
System.out.println(Objects.equal(null, "hoge")); // false
System.out.println(Objects.equal("hoge", null)); // false
System.out.println(Objects.equal(null, null)); // true
GuavaのObjects.equalを使う
String a = getString();
String b = getString();
if(Objects.equal(a,b)){
// 略
// ただしaもbもnullな場合真なことに注意

このObjects.equalはObjectのメソッドは、equalsメソッドをオーバーライドする際にも大変役立ちます。

さて、Java7にはjava.lang.Objectsクラスにequalsというメソッドがあります。

Guavaのcom.google.common.base.Objectsのequalメソッド
Java7のjava.lang.Objectsクラスのequalsメソッド

どちらも二つのObject型の引数をとり、nullの対処も同じです。

非常に良く似ていますが、大きな違いがあります。GuavaはequalでJava7はequalsです。sの違いです。このsによって、あることがGuavaではできますが、Java7ではできません。

メソッドのstaticインポートです。
Javaのすべてのクラスの親クラスObjectクラス。このクラスはいくつかのメソッドを持っていますが、Object型一つを引数にとるequlsもその一つです。

そのため、Java7のequalsメソッドはstaticインポートが書けません。それに比べて、Guavaはstaticインポートが可能です。

com.google.common.base.Objects#equal
import static com.google.common.base.Objects.equal;

//略
Hoge a = createHoge();
Hoge b = createHoge();
if(equal(a,b)) { // staticインポートしているので、equalだけの記述でOK
    // anything TODO
}
java.lang.Objectsクラス#equals
Hoge a = createHoge();
Hoge b = createHoge();
if(Objects.equals(a,b)) { // 「if(equals(a, b))」はコンパイルエラー
    // anything TODO
}

まぁ、正直次のやつにくらべたら無くなっても、いいかなという感じですが...

GuavaのLists#newArrayListとJava7で導入されたダイヤモンドオペレーター

Java7はダイヤモンドオペレーターにより次のように、型の記述がすこし簡略化できるようになりました。

ダイヤモンドオペレーターを使う
List<String> list = new ArrayList<>();

実は、GuavaのLists#newArrayListも型推論をしてくれるので、インスタンス化の方の型の記述をしなくてもいいです。

GuavaのLists#newArrayList
List<String> list = Lists.newArrayList();

// 上記メソッドをstaticインポートすれば
// List<String> list = newArrayList();
// でいい。

これだけであればわざわざGuavaを導入しなくても、単純にダイヤモンドオペレーターを使えば良いとも思えるのですが、GuavaのLists#newArrayListには、次のように初期化できるオーバーロードが用意されています。

GuavaのLists#newArrayListで初期化
List<Strng> list = Lists.newArrayList("H", "e", "l", "l", "o");
// static importすれば、 
// List<String> list = newArrayList("H", "e", "l", "l", "o");

このように簡潔に初期要素こみのListのインスタンスを作成できます。
ArrayListのコンストラクタには、このように簡潔にインスタンス化できるものは無いです。コンストラクタは、

  • 引数なし
  • int型 (初期容量指定)
  • Collectionを実装した型 (初期要素指定)

の3個です。3個目のCollectionを実装した型を引数に取るものを使ったとしても、次のように書く必要があります。

List<String> list = new ArrayList<>(Arrays.asList("H","e","l","l","o"));

(ちなみにArrays.asListもListインターフェースを実装したインスタンスを作成しますが、addメソッドなどを呼び出すと、UnsupportedOperationExceptionを投げます。)
(参考:Java7のArrayListのAPIリファレンス)

ちなみにC#では次のように、Listを初期化できます。

C#のリストの初期化
var list = new List<string> {"H", "e", "l", "l", "o"};

Groovyもリストのインスタンス化は、次のような便利な記法が用意されています。

Groovyのリストの初期化
def list = ["H", "e", "l", "l", "o"]

Javaのリストの初期化は少々冗長です。ダイヤモンドオペレーターで少しは短くなりましたが、GuavaのLists#newArrayListを使うとさらに短くすることが可能ですね。

その他投稿にあったもの

c.g.c.base.Charsetsとjava.nio.charset.StandardCharsets

InputStreamReaderクラスなどの初期化に用いるCharset型の定数です。

new InputStreamReader(new FileInputStream(file),StandardCharsets.UTF_8)
// or
new InputStreamReader(new FileInputStream(file), Charsets.UTF_8)

参考:Where to get “UTF-8” string literal in Java?
参考:java.nio.charset.StandardCharsets
参考:com.google.common.base.Charsets

c.g.c.base.Objects.hashCode()とjava.util.Objects.hash()

どちらもhashCodeを作る便利メソッドで、内部的にArrays.hashCode(Object[])が呼ばれるようですね。

これはequalsと逆で、Guavaのメソッドの方がObjectのほうと同じメソッド名でjava.utils.Objectsの方が違うメソッド名ですね。そのため、java.utils.Objectsのhashメソッドの方はstaticインポート可能ですね。

参考:java.util.Objects#hash
参考:com.google.common.base.Objects#hashCode

c.g.c.collect.Iterators.emptyIterator()とjava.util.Collections.emptyIterator()

自作コレクションなどに使うのでしょうか?

ちなみに、java.util.Collections.emptyList()やjava.util.CollectionsCollections.emptyMap()もありました。どちらも、add・putしたら、UnsupportedOperationExceptionが発生しました。

参考:java.util.Collections#emptyIterator
参考:com.google.common.Iterators#emptyIterator

プリミティブ型のラッパークラスのcompareメソッド

Guavaはcom.google.common.primitivesという名前空間にBooleans、Ints、Doublesなど、プリミティブ型の便利クラスがあります。

com.google.common.primitives.Booleans.compareのドキュメントには、
Java7以降ならjava.lang.Boolean.compareを使おうとありました。

参考:com.google.common.primitives.Booleans#compare
参考:java.lang.Boolean#compare

Guavaについての分かりやいページ

まとめ

やっぱり、Guava便利ですね。
Java7で加わったメソッドも要チェックですね。

36
35
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
36
35