メインページ > 工学 > 情報技術 > Java > 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. 深い比較(EqualsBuilderHashCodeBuilder

編集

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 標準ライブラリの問題点
手動で equalshashCode を実装する際、コードが冗長になりやすく、漏れやエラーを引き起こすリスクがあります。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.Randomjava.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 は、標準ライブラリで未だにサポートされていない以下のような機能で有用です:

  • 深い比較(EqualsBuilderHashCodeBuilder
  • クラス情報の操作(ClassUtils
  • ランダム文字列生成(RandomStringUtils
  • 例外処理の補助(ExceptionUtils
  • 文字列差分(StringUtils.difference
  • トリプルやクワッド(Triple, Quadruple

これらの機能は、複雑なロジックやカスタム実装を避けるために活用できる場面が多いです。

外部リンク

編集
 
Wikipedia
ウィキペディアApache Commons Langの記事があります。