Javaの便利ライブラリ Google Guava

## What's Google Guava?
Googleが開発しているOSSのjava core libraryで、Googleの多くのJavaベースのプロジェクトで使用されており、 Java 1.5 以上で使用できる。
昔、Google Collectionとして開発されていた。

Apache Commons の Lang、Collectionsなどに替わる機能を提供していて、パッケージ名を見れば大体の機能について想像がつくと思います。

* com.google.common.annotations
* com.google.common.base
* com.google.common.cache
* com.google.common.collect
* com.google.common.escape
* com.google.common.eventbus
* com.google.common.hash
* com.google.common.html
* com.google.common.io
* com.google.common.math
* com.google.common.net
* com.google.common.primitives
* com.google.common.reflect
* com.google.common.util.concurrent
※2013/10/27現在

要は`できることを増やすライブラリではなく、普段やっていることを短く書くためのライブラリ`

この中で、使ってみたものを紹介。
気が向いたら、追加してくかも、、



## com.google.common.collect パッケージ
旧google collections library。標準のJDKには含まれていないCollectionの実装クラスをまとめられていて、便利なCollection操作クラスが多数ある。
このクラスを使うために、Guavaを使用するだけでも十分な価値がある。



### Lists / Maps / Sets
冗長なインスタンス化の排除、配列のような柔軟な初期化。

```java:Example
// Java　→　長い、冗長
List<TypeThatsTooLongForItsOwnGood> listJava = new ArrayList<TypeThatsTooLongForItsOwnGood>();

// Guava　→　シンプル(ただしJava7からは右辺のジェネリクスは省略できるので、、、)
List<TypeThatsTooLongForItsOwnGood> listGuava = Lists.newArrayList();
Map<KeyType, LongishValueType> mapGuava = Maps.newLinkedHashMap();

// Guava　→　配列ライクな初期化
List<String> theseElements = Lists.newArrayList("alpha", "beta", "gamma");
Set<String> theseSet = Sets.newHashSet("alpha", "beta", "gamma");

// Guava　→　定数とか
final List<String> constList = ImmutableList.of("dog", "cat", "pig");
final Map<String, String> constMap = ImmutableMap.of("dog", "犬", "cat", "猫");    // k,v,k,v...
```


### HashMultiset
setの中に含まれる、単語検索。

```java:Example
Multiset<String> wordsMultiset = HashMultiset.create();
wordsMultiset.add("word1");
wordsMultiset.add("word2");
wordsMultiset.add("word1");
wordsMultiset.count("word1"); // result 2
```


### Multimap
keyが含まれていなければ、、というチェック無しで、単にputするだけでCollectionに追加される。

```java:Example
// Java
if (!map.contains(k)) {
    map.put(k, new ArrayList());
}
map.get(k).add(v);

// Guava MultiMap
map.put(k, v);
```



### Table
2次元配列のような、2つのキーを持つテーブルを作成

```java:Example
// Java 
Map<KeyA, Map<KeyB, Value>> nestedMap = ...
Map<KeyB, Value> innerMap = nestedMap.get(keyA);
Value value;
if (innerMap == null) {
    value = null;
} else {
    value = innerMap.get(keyB);
}

// Guava 面倒なnullチェックが不要
Table<KeyA, KeyB, Value> table = ...
Value value = table.get(keyA, keyB);
```



### Joiner
データを区切り文字で連結して一つの文字列にする。配列もOK。

```java:Example
String[] animals = new String[]{"dog", "cat", null, "pig"};
Joiner.on(", ").skipNulls().join(animals); // dog, cat, pig

Map<String, String> dictionary = new HashMap<String, String>();
dictionary.put("米", "rice");
dictionary.put("パン", "bread");
dictionary.put("うどん", null);
MapJoiner joiner = Joiner.on(", ").withKeyValueSeparator(":").useForNull("登録なし");
joiner.join(dictionary); // 米:rice, パン:bread, うどん:登録なし
```


### Splitter / CharMatcher(baseパッケージ)
データを区切り文字で分割して一つのリストにする。

```java:Example
String telnum = "090 1234 5678"; // もしくは090-1234-5678に対応
CharMatcher matcher = CharMatcher.WHITESPACE.or(CharMatcher.is('-'));
Iterable<String> splits = Splitter.on(matcher).split(telnum); // 090,1234,5678という長さ3のリスト
```
※ただし、単純な分割ならString#splitで十分。


### ComparisonChain
compare/compareToを書くときに、メソッドチェインで書けるので、シンプル。

```java:Example
public int compareTo(Foo that) {
  return ComparisonChain.start()
      .compare(this.aString, that.aString)
      .compare(this.anInt, that.anInt)
      .compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast())
      .result();
}
```




## com.google.common.primitives パッケージ
Booleans、Ints、Chars、Doublesなどプリミティブ型に対するユーティリティメソッドを提供するクラスが含まれています。

### Ints
プリミティブ型の操作ユーティリティ。

```java:Example
int[] ary = new int[] { 1, 2, 3 };
List<Integer> list = Ints.asList(ary); // 配列からListへの変換
int max = Ints.max(ary); // 3
String joinedStr = Ints.join(" : ", ary); // 1 : 2 : 3
```





## com.google.common.base パッケージ

### Strings
文字列操作ユーティリティ。

```java:Example
Strings.isNullOrEmpty(str); // nullか空文字?
Strings.repeat("*", 10); // **********
Strings.padStart("7", 2, '0'); // 07
Strings.padStart("12", 2, '0'); // 12
Strings.padEnd("7", 3, '0'); // 700
```

### Objects

```java:Example
// nullを気にせずにオブジェクトの比較
Objects.equal("a", "a"); // returns true
Objects.equal(null, "a"); // returns false
Objects.equal("a", null); // returns false
Objects.equal(null, null); // returns true

// 安全なハッシュが簡単に作成
Objects.hashCode(Object...)

// toStringメソッド作成の簡略化
@Override
public String toString(){
        // Returns "ClassName{x=1}"
        return Objects.toStringHelper(this)
           .add("x", this.x) //変数名とその値
           .toString();
        //or
        // Returns "MyObject{x=1}"
        return Objects.toStringHelper("MyObject")
           .add("x", 1)
           .toString();
}
```



## com.google.common.io パッケージ

### Resources
リソースの取得をシンプルに。

```java:Example
// Java
URL resourceJava = this.getClass().getClassLoader().getResource("sample.txt");
// Guava
URL resourceGuava = Resources.getResource("sample.txt");
```

### Files
BufferedReaderの作成や、ファイル入出力の簡略化。

```java:Example
// Java
BufferedReader reader = new BufferedReader(new FileReader(getFile()));
// Guava
BufferedReader reader = Files.newReader(getFile(), Charsets.UTF_8);

// 全行リスト取得
List<String> lines = Files.readLines(getFile(), Charsets.UTF_8);

// 「a」から始まる行のみを抽出
String lines = Files.readLines(getFile(), Charsets.UTF_8, new LineProcessor<String>() {
	private List<String> lines = Lists.newArrayList();
				
	@Override
	public boolean processLine(String line) throws IOException {
		if(line.startsWith("a")) {
			lines.add(line);
		}
		return true;
	}

	@Override
	public String getResult() {
		return Joiner.on(",").join(lines);
	}
});
```




## com.google.common.annotations パッケージ
### @VisibleForTesting
メソッドやフィールドに付与するもので、テストをしやすくするためにアクセス修飾子のレベルを緩くしているということを明示するために付与する。




## 使い方
セントラルリポジトリに登録されているので、Mavenのdependencyを追加。

```
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>r09</version>
</dependency>
```

##参考

* [guava-libraries(公式)](https://code.google.com/p/guava-libraries/)
* [Google製Javaライブラリ Guavaを使ってみた。](http://shikajiro.github.io/blog/2013/03/03/java-guava/)
* [Guavaのススメ](http://www.akirakoyasu.net/2011/01/15/218/)
* [[Java]guava](http://d.hatena.ne.jp/mtoyoshi/20100725/1280040233)