こんにちは。ハンドルネーム「Javaを復習する初心者」です。このサイトはプログラミング言語Javaの復習・学習をするブログです。プログラムの開発・実行はEclipseで行ってます。
スポンサーリンク
お知らせ
  • 参考文献のページ作りました。
  • Amazon.co.jpアソシエイトに参加していますが、参考文献の紹介はもしもアフィリエイトに統一しました。
  • 2016年10月9日からは投稿ペースを落とします。週1回くらいにする予定です。
スポンサーリンク

List<String>の文字列を検索する

こんにちは。「Javaを復習する初心者」です。List<String>の各要素から条件に合う文字列を検索する方法を確認しました。

List<String>型変数にArrayListが格納されているとします。このArrayListには文字列がいくつか追加されているとします。このうち、条件に合った文字列を抽出する方法を考えました。

抽出条件

抽出条件は以下です。

  • 完全一致
  • 前方一致
  • 後方一致
  • 部分一致
  • 部分一致の論理和
  • 部分一致の論理積

上記はStringクラスに用意されているメソッドを使用します。完全一致はequalsメソッド、前方一致はstartsWithメソッド、後方一致はendsWithメソッド、部分一致はcontainsメソッドを使います。論理和と論理積はcontainsメソッドと演算子「||」と「&&」を使います。

リストの内容

リストには以下のように文字列が格納されているとします。

        List<String> words = new ArrayList<String>();
        words.add("ab1-1AB");
        words.add("ab1-2AB");
        words.add("ab1-3AB");
        words.add("ab2-1AB");
        words.add("ab2-2AB");
        words.add("ab2-3AB");

抽出クラスを作る

用意するメソッドは次のようにしました。第1引数にリスト、第2引数に検索語句を指定します。条件を満たす文字列のみを格納したリストを返却します。論理和と論理積の検索の場合のみ、第3引数も定義します。

まず、判定をするためのインターフェースを定義しました。

public interface ExtractWordsJudge {

    public abstract boolean judge(String word, String... searchWords);

}

このインターフェースの実装クラスは第1引数wordが第2引数以降に対して、等しいなどを返却する想定です。第1引数wordをリストに残すかどうかの判定を実装します。

以下は抽出クラスです。コンストラクタで上記のインターフェースの実装クラスを受け取ります。

public class ExtractWords {

    private ExtractWordsJudge extractWordsJudge;

    public ExtractWords(ExtractWordsJudge extractWordsJudge) {
        this.extractWordsJudge = extractWordsJudge;
    }

    public List<String> getList(List<String> sourceList, String... searchWords) {
        List<String> list = new ArrayList<>();
        for (String word : sourceList) {
            if (extractWordsJudge.judge(word, searchWords)) {
                list.add(word);
            }
        }
        return list;
    }
}

getListメソッドで文字列の抽出をします。このメソッドのif文で、コンストラクタで受け取ったインターフェースの実装クラスを使用します。

抽出クラスを使う

以下は上記クラスの使用例と実行結果です。

    public static void main(String[] args) {

        List<String> words = new ArrayList<String>();
        words.add("ab1-1AB");
        words.add("ab1-2AB");
        words.add("ab1-3AB");
        words.add("ab2-1AB");
        words.add("ab2-2AB");
        words.add("ab2-3AB");

        ExtractWords extractWords;

        // 完全一致
        System.out.println("完全一致");
        extractWords = new ExtractWords((String word, String... searchWords) -> word.equals(searchWords[0]));
        System.out.println(extractWords.getList(words, "ab2-1AB"));

        // 前方一致
        System.out.println("前方一致");
        extractWords = new ExtractWords((String word, String... searchWords) -> word.startsWith(searchWords[0]));
        System.out.println(extractWords.getList(words, "ab2"));

        // 後方一致
        System.out.println("後方一致");
        extractWords = new ExtractWords((String word, String... searchWords) -> word.endsWith(searchWords[0]));
        System.out.println(extractWords.getList(words, "3AB"));

        // 部分一致
        System.out.println("部分一致");
        extractWords = new ExtractWords((String word, String... searchWords) -> word.contains(searchWords[0]));
        System.out.println(extractWords.getList(words, "3A"));

        // 部分一致の論理和
        System.out.println("部分一致の論理和");
        extractWords = new ExtractWords((String word, String... searchWords) -> word.contains(searchWords[0]) || word.contains(searchWords[1]));
        System.out.println(extractWords.getList(words, "1-3", "2-2"));

        // 部分一致の論理積
        System.out.println("部分一致の論理積");
        extractWords = new ExtractWords((String word, String... searchWords) -> word.contains(searchWords[0]) && word.contains(searchWords[1]));
        System.out.println(extractWords.getList(words, "-1", "2"));

    }

ExtractWordsのコンストラクタに指定するインターフェースがメソッドを一つだけ持つため、ラムダ式を使っています。

完全一致
[ab2-1AB]
前方一致
[ab2-1AB, ab2-2AB, ab2-3AB]
後方一致
[ab1-3AB, ab2-3AB]
部分一致
[ab1-3AB, ab2-3AB]
部分一致の論理和
[ab1-3AB, ab2-2AB]
部分一致の論理積
[ab2-1AB]

上記のようになりました。複数の引数もうまく機能しています。