Apache commonsが便利な件(commons-lang編)
http://d.hatena.ne.jp/daisuke-m/20080702/1214982943
やー、前書いたエントリいつだったかな、と思って見たら7月ですよ。コツコツ書いていきますね。まず初回はcommons-lang。
commons-lang は、java.langパケにあるような基本的なクラスを追加で提供している感じです。また、既存の基本クラス(String,Object,配列等)のメソッドに対してnullチェックを搭載したものが多く提供されています。null対策を内部で行っているので、ぬるぽを恐れる必要があまりありません。こういうのを使いこなせると便利ですね。
StringUtils
これはよく使いますかね。もしかしたらcommonsで一番知名度の高いクラスかもしれない。しかしその中でマイナーかもしれないのはまず定数系。下記の例では、後者の方が記述量は多くなりますが、「コードで語れ」てます。
if(x.equals("")) { ... } if(x.equals(StringUtils.EMPTY)) { ... } if(y.indexOf(z) == -1) { ... } if(y.indexOf(z) == StringUtils.INDEX_NOT_FOUND) { ... }
その他、メソッドはStringのメソッドに対してnull対策を施したものが多数。前者はfooがnullだった時はぬるぽが飛びますが、後者はnullが入ります。
String foo = ...;
String bar = foo.trim();
String baz = StringUtils.trim(foo);
そんなnull対策でよくやるのが、こんなコード。
if("hoge".equals(x)) { ... }
しかし、どうも美しくない。これはこう書くと美しいかも。
if(StringUtils.equals(x, "hoge")) { ... }
ObjectUtils
上記StringUtilsによるnullチェックと同様、Objectに対するnull対策済みメソッドを提供。例えば x.equals(y) は、xのnullチェックが要るケースが多いが、ObjectUtils.equals(x, y) でいい。
identityToString
hashCodeやtoStringをオーバーライドしてしまったクラスで、ObjectオリジナルのtoStringの結果を使いたい場合。
defaultIfNull
Object x; if(y == null) { x = z; } else { x = y; }
じゃなくて、こう書ける。
Object x = ObjectUtils.defaultIfNull(y, z);
Object x = y == null ? z : y; とも等価だけど、ObjectUtils使った方が分かりやすい。。
ClassUtils
Classオブジェクト用ユーティリティ。
クラス表現文字列(com.example.Foo$Bar 等)の構成要素が定数として定義されている。下記1行目よりも、2行目の方がやりたいことが明確。コードで語る。
String[] x = y.getClass().getName().split(".");
String[] x = y.getClass().getName().split(ClassUtils.PACKAGE_SEPARATOR_CHAR);
getShortClassName, getPackageName
com.example.Foo という文字列が欲しければ、x.getClass().getName()
でいいのだが、Fooだけが欲しい時、ありますよね。FQCNじゃ、なげーよ、というとき。
ClassUtils.getShortClassName(x) でどうぞ。逆にパケ名だけ欲しいときは getPackageName で。
SystemUtils
システムプロパティが定数化している。
String x = System.getSystemProperty("file.separator");
String x = SystemUtils.FILE_SEPARATOR;
その他、JavaバージョンやOSなどの判定メソッドなど。user.homeをFileオブジェクトとして取得するメソッド等も便利(getUserHome())。
ArrayUtils
まず、各種基本オブジェクトの空配列が定数として定義されている。以下の2文は同義です。
return new String[0]; return ArrayUtils.EMPTY_STRING_ARRAY;
toString
ListオブジェクトをSystem.out.printlnする*1と、"[A, B, C]" のように要素が並んで表示されるが、配列を表示しようとすると "[Ljava.lang.String;@107077e" こんなあまり嬉しくない文字列になる。その辺の解決。"{a,b,c}" という感じ。
コレクションのように配列を扱うメソッド群
ArrayUtils.isEmpty(array) など、配列をあたかもコレクションのように操作するユーティリティがいっぱいあります。reverse, indexOf, lastIndexOf, contains, add, addAll, remove, removeAllなどなど。
その他
- 配列のequals比較
- clone
- subarray(substringみたいに一部切り出し)
- 要素数の取得と比較(null対策済み)
Validate
メソッドの事前条件など、値検証用のユーティリティ。
Validate.notNull(argument);
Validate.notEmpty(array);
// 等...
CharRange, CharSet
あんまり使うこともないかもしれないけど、「文字の範囲」をあらわすクラス。
CharRange cr = new CharRange('c', 'e'); assert cr.contains('d') == true; assert cr.contains('x') == false; cr = new CharRange('c', 'e', true); // 反転 assert cr.contains('x') == true; assert cr.contains('d') == false;
よく使うものは定数としてCharSetクラスに定義されている。
CharSet.ASCII_ALPHA = new CharSet("a-zA-Z"); CharSet.ASCII_ALPHA_LOWER = new CharSet("a-z"); CharSet.ASCII_ALPHA_UPPER = new CharSet("A-Z"); CharSet.ASCII_NUMERIC = new CharSet("0-9");
例外
例外も定義されています。黙って使用例を見ると分かります。
public void foo(Object obj) { if (obj instanceof String == false) { throw new IllegalClassException(String.class, obj); } // do something with the string } public void foo(PersonSearcher search) { if (search.getSurname() == null || search.getForename() == null || search.getSex() == null) { throw new IncompleteArgumentException("search"); } // do something with the searcher } public void foo(String str) { if (str == null) { throw new NullArgumentException("str"); } // do something with the string } public void foo() { try { // do something that throws an Exception } catch (Exception ex) { // don't know what to do here yet throw new NotImplementedException("TODO", ex); } }
継承関係はこんな感じ。
- IllegalArgumentException
- IllegalClassException
- IncompleteArgumentException
- NullArgumentException
- UnsupportedOperationException
- NotImplementedException
ToStringBuilder
toStringを作るのって、結構大変。それをサポートしてくれるのがこのクラス。
public class Person { String name; int age; boolean smoker; // ... public String toString() { return ToStringBuilder.reflectionToString(this); } }
toString結果は "Person@7f54[name=Stephen,age=29,smoker=false]" など。
フィールド数が多くて1行表示だと見づらい場合は、第二引数にフォーマットが指定できる。
どう使うかは貴方次第、Mutableシリーズ
primitiveラッパーオブジェクト(Integer,Boolean等)はimmutableであることで有名です。足したり引いたり、とにかく値が変わるとインスタンス自体が置き換わるクラスです。
じゃあ、Mutableなラッパーがあってもいいじゃないか、というシリーズ。
StrBuilder
StringBuilderの強力版。appendlnメソッドが便利。最後に改行をつけてくれるんですね。その他色々な便利メソッドが追加されています。
しかし、StringBuilderはfinalクラスなのでextendsできません。力技で作っているクラスです。
その他、見てみると面白いかもしれないクラス
- LocaleUtils
- WordUtils
- StringEscapeUtils
- RandomStringUtils
- DateUtils
- DateFormatUtils
- StopWatch (ちょっとしたパフォーマンス測定に使える)
以上、すべてではありませんが、個人的に気に入っているクラスを中心に紹介しました。これでcommons-langに興味を持った方は、他のクラスも覗いて見るといいと思います。ちなみに commons-lang (v2.4) は約80クラスしかなく、ほとんどのクラスが独立している(依存していない)ので、非常に読みやすいライブラリだと思います。
*1:toStringする