Apache Commons Lang
Apache Commons Langの概要
[編集]Apache Commons Lang (以後ACL) はJavaの標準ライブラリでは提供されていない便利な機能を提供するライブラリです。 古いバージョンのJavaでも利用できるという特徴もあります。 ライセンスはThe Apache Software License, Version 2.0 を採用しています。
本書の目的
[編集]本書では、ACLの便利な機能を実際の使用例を交えて学んでいくことを目的としています。 また、利便性を良くするために逆引き形式をとっています。
想定読者
[編集]Langを利用できるJavaの開発環境を構築できる方を想定しています。
開発環境
[編集]以下の表を参考にして、使用するACLとJDKのバージョンを選んで下さい。
Apache Commons Lang | Java Development Kit |
---|---|
ACL 3.13以降 | JDK 11以上 |
ACL 3.9 - 3.12 | JDK 1.8以上 |
ACL 3.0 - 3.8 | JDK 1.6 - 1.8 |
ACL 2.x | JDK 1.4 - 1.6 |
Langの機能
[編集]文字列処理
[編集]Java Development Kit の進化で必要なくなった Apache Commons Lang の機能
[編集]Apache Commons Lang は Java の標準ライブラリを補完する便利なユーティリティを提供するライブラリですが、Java の進化(特に Java 8 以降)により、いくつかの機能が標準ライブラリで代替可能となり、その使用が必要なくなりました。以下にその例をいくつかコード付きで紹介します。
1. 文字列の操作: StringUtils.isEmpty
[編集]- Apache Commons Lang
import org.apache.commons.lang3.StringUtils; public class Main { public static void main(String[] args) { String str = ""; System.out.println(StringUtils.isEmpty(str)); // true } }
- Java 11以降
public class Main { public static void main(String[] args) { String str = ""; System.out.println(str.isEmpty()); // true } }
Java 11 以降では、String.isBlank()
も利用可能で、空文字列だけでなく空白文字のみの文字列もチェックできます。
2. コレクションの処理: ArrayUtils
[編集]- Apache Commons Lang
import org.apache.commons.lang3.ArrayUtils; public class Main { public static void main(String[] args) { int[] array = {1, 2, 3}; System.out.println(ArrayUtils.contains(array, 2)); // true } }
- Java 8以降
import java.util.Arrays; public class Main { public static void main(String[] args) { int[] array = {1, 2, 3}; System.out.println(Arrays.stream(array).anyMatch(i -> i == 2)); // true } }
Java 8 のストリーム API を使用することで、同様の機能が簡潔に実現可能です。
3. 型変換: NumberUtils.toInt
[編集]- Apache Commons Lang
import org.apache.commons.lang3.math.NumberUtils; public class Main { public static void main(String[] args) { String str = "123"; System.out.println(NumberUtils.toInt(str)); // 123 } }
- Java 8以降
public class Main { public static void main(String[] args) { String str = "123"; System.out.println(Integer.parseInt(str)); // 123 } }
Java の標準ライブラリは、基本型への変換を直接サポートしています。
4. オブジェクト比較: ObjectUtils.compare
[編集]- Apache Commons Lang
import org.apache.commons.lang3.ObjectUtils; public class Main { public static void main(String[] args) { Integer a = 10; Integer b = 20; System.out.println(ObjectUtils.compare(a, b)); // -1 } }
- Java 7以降
import java.util.Objects; public class Main { public static void main(String[] args) { Integer a = 10; Integer b = 20; System.out.println(Integer.compare(a, b)); // -1 } }
Java 7 以降では java.util.Objects
が多くのユーティリティメソッドを提供しています。
5. 文字列結合: StringUtils.join
[編集]- Apache Commons Lang
import org.apache.commons.lang3.StringUtils; public class Main { public static void main(String[] args) { String[] array = {"a", "b", "c"}; System.out.println(StringUtils.join(array, ",")); // "a,b,c" } }
- Java 8以降
import java.util.StringJoiner; public class Main { public static void main(String[] args) { String[] array = {"a", "b", "c"}; System.out.println(String.join(",", array)); // "a,b,c" } }
Java 8 以降では String.join
を利用して簡潔に結合できます。
6. デフォルト値の設定: ObjectUtils.defaultIfNull
[編集]- Apache Commons Lang
import org.apache.commons.lang3.ObjectUtils; public class Main { public static void main(String[] args) { String value = null; System.out.println(ObjectUtils.defaultIfNull(value, "default")); // "default" } }
- Java 8以降
import java.util.Optional; public class Main { public static void main(String[] args) { String value = null; System.out.println(Optional.ofNullable(value).orElse("default")); // "default" } }
Java 8 の Optional
を使用することで同様の動作が可能です。
まとめ
[編集]Java の標準ライブラリの進化により、かつては Apache Commons Lang に頼っていた多くの機能が不要となりました。ただし、Apache Commons Lang にはまだ便利な機能が多く含まれているため、プロジェクトの要件によって使い分けることが重要です。
最新のJDKでもサポートされていないApache Commons Langの有用な機能
[編集]最新のJDK(たとえば、Java 17以降のLTSバージョン)でも標準ライブラリで直接サポートされていない機能が、Apache Commons Lang にはいまだに含まれています。以下にその代表例を挙げて、実際の使用例とともに説明します。
1. 深い比較(EqualsBuilder
と HashCodeBuilder
)
[編集]Java の標準ライブラリでは、equals()
や hashCode()
メソッドをオーバーライドする際に手動で実装する必要がありますが、Apache Commons Lang のユーティリティを使うと簡潔に記述できます。
- Apache Commons Lang
import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; public class Person { private String name; private int age; @Override public boolean equals(Object obj) { if (obj == this) return true; if (!(obj instanceof Person)) return false; Person other = (Person) obj; return new EqualsBuilder() .append(this.name, other.name) .append(this.age, other.age) .isEquals(); } @Override public int hashCode() { return new HashCodeBuilder(17, 37) .append(name) .append(age) .toHashCode(); } }
- Java 標準ライブラリの問題点
- 手動で
equals
やhashCode
を実装する際、コードが冗長になりやすく、漏れやエラーを引き起こすリスクがあります。java.util.Objects
では補助的なメソッドがあるものの、深い比較(ネストされたオブジェクトの比較など)や複雑なロジックには対応しにくいです。
2. クラス情報の操作(ClassUtils
)
[編集]ClassUtils
は、Java の標準ライブラリでは直接提供されていない、クラス関連の便利なメソッドを多数提供します。
- 例1
- 全スーパークラスとインターフェースの取得
import org.apache.commons.lang3.ClassUtils; public class Main { public static void main(String[] args) { System.out.println(ClassUtils.getAllSuperclasses(String.class)); // [class java.lang.Object] System.out.println(ClassUtils.getAllInterfaces(String.class)); // [interface java.io.Serializable, interface java.lang.Comparable, interface java.lang.CharSequence] } }
- Java 標準ライブラリでは非対応
- 標準ライブラリでは、
Class.getSuperclass()
やClass.getInterfaces()
を使う必要がありますが、これらは深い階層をたどる処理を手動で実装する必要があります。
3. ランダムな文字列生成(RandomStringUtils
)
[編集]特定の長さや条件でランダムな文字列を生成する場合、Apache Commons Lang の RandomStringUtils
は非常に便利です。
- Apache Commons Lang
import org.apache.commons.lang3.RandomStringUtils; public class Main { public static void main(String[] args) { String randomAlphanumeric = RandomStringUtils.randomAlphanumeric(10); String randomNumeric = RandomStringUtils.randomNumeric(5); System.out.println(randomAlphanumeric); // 例: "a8f3ZkL1Pq" System.out.println(randomNumeric); // 例: "48293" } }
- Java 標準ライブラリの問題点
- 標準ライブラリでは、
java.util.Random
やjava.security.SecureRandom
を使って自前で文字列を生成する必要があります。簡潔さではRandomStringUtils
に劣ります。
4. 例外のラッピングとチェーン操作(ExceptionUtils
)
[編集]例外を扱う際、Apache Commons Lang の ExceptionUtils
は、スタックトレースやルート原因の取得などの機能を提供します。
- Apache Commons Lang
import org.apache.commons.lang3.exception.ExceptionUtils; public class Main { public static void main(String[] args) { try { throw new IllegalArgumentException("Root cause", new NullPointerException("Original cause")); } catch (IllegalArgumentException e) { System.out.println(ExceptionUtils.getRootCauseMessage(e)); // "Original cause" } } }
- Java 標準ライブラリの問題点
- Java 標準ライブラリでは、
Throwable.getCause()
を使って手動でルート原因をたどる必要がありますが、ExceptionUtils
のように一括で取得する機能はありません。
5. 文字列差分の比較(StringUtils.difference
)
[編集]Apache Commons Lang の StringUtils.difference
は、2つの文字列の差分を簡単に取得できます。
- Apache Commons Lang
import org.apache.commons.lang3.StringUtils; public class Main { public static void main(String[] args) { String str1 = "abcdef"; String str2 = "abcxyz"; System.out.println(StringUtils.difference(str1, str2)); // "xyz" } }
- Java 標準ライブラリでは非対応
- 標準ライブラリでは、文字列の差分を取得するために自前のロジックを実装する必要があります。
6. トリプルやクワッド(Triple
, Quadruple
)
[編集]Java 標準ライブラリにはペア(Pair
)のような構造は提供されておらず、トリプルやクワッドを表現するクラスも存在しません。Apache Commons Lang はこれらを補完します。
- Apache Commons Lang
import org.apache.commons.lang3.tuple.Triple; public class Main { public static void main(String[] args) { Triple<String, Integer, Boolean> triple = Triple.of("Alice", 30, true); System.out.println(triple.getLeft()); // "Alice" System.out.println(triple.getMiddle()); // 30 System.out.println(triple.getRight()); // true } }
- Java 標準ライブラリでは非対応
- 標準ライブラリで同等の機能を実現するには、自前でクラスを定義する必要があります。
まとめ
[編集]Apache Commons Lang は、標準ライブラリで未だにサポートされていない以下のような機能で有用です:
- 深い比較(
EqualsBuilder
とHashCodeBuilder
) - クラス情報の操作(
ClassUtils
) - ランダム文字列生成(
RandomStringUtils
) - 例外処理の補助(
ExceptionUtils
) - 文字列差分(
StringUtils.difference
) - トリプルやクワッド(
Triple
,Quadruple
)
これらの機能は、複雑なロジックやカスタム実装を避けるために活用できる場面が多いです。