1

Java の要素のリストにフィルター メソッドを実装したいので、フィルターに従ってリスト内のいくつかの要素を取り除くことができます。そして、最も重要なことは、インターフェイスをできるだけシンプルに設計したいということです。

これが私の実装です。EasierList という名前のクラスを作成し、そのクラスに、署名と実装が次のようなメソッドを追加しました。

public IEasierList<T> filter(ISelection<T> filter) {
    List<T> result = new ArrayList<T>();
    for(T item : mInternalList) {
        if(filter.accept(item)) {
            result.add(item);
        }
    }

    mInternalList = result;
    return new EasierList<T>(this);
}

ISelection インターフェイスに関しては、非常に簡単です。

public boolean accept(T obj);

したがって、このクラスを使用するユーザーは、フィルターを使用するために次のようなコードを記述する必要があることがわかります。

aEasierList.filter(new ISelection<T>() {
@Override
public boolean accept(T obj) {
        // some test
    return false;
}
});

これを行うためのより良い方法があるかどうか疑問に思っています。インターフェイスをさらに使いやすくすることを意味しますか?

前もって感謝します!

4

2 に答える 2

5

2 つのポイント:

まず、車輪を再発明する必要はありません。コレクションと iterable のフィルタリング変換を既にサポートしているGuavaを使用できます。確かに、これらのメソッドは静的ですが、標準またはインターフェイスに使用できます。ListCollectionIterable

第 2 に、Java はまだラムダ式をサポートしていないため (Java 8 で計画されています)、冗長な匿名クラスが関数オブジェクトを実装する唯一の方法です (本格的な名前付きクラスを作成したくない場合)。ただし、匿名クラスをその場で実装するのではなく、静的フィールドに格納することで、少しは自分を助けることができます。

private static final Predicate<String> startsWithS = new Predicate<String>() {
    @Override public boolean apply(String string) {
        return string.startsWith("S");
    }
}

そして、次のように使用します。

Collection<String> strings = ...
Collection<String> filtered = Collections2.filter(strings, startsWithS);

編集:

もう 1 つ重要なことに言及する必要があります。これらのメソッドfiltertransformメソッドは、元のコレクションに依存しない新しいコレクションを作成しません。彼らが作成するのは「ビュー」です。これは、技術的には元のコレクションを指し、反復、クエリなどの際に指定されたPredicateまたはその要素に遅延適用するプロキシ オブジェクトです。Function

これは便利な場合もありますが、覚えておく必要があるのは、元のコレクションから独立している (もちろん深くではありません) 新しいコレクションを取得するには、新しいコレクションのコンストラクタ (またはファクトリ) に渡す必要があることです。コレクション。

List<String> filteredList =
    new ArrayList<>(Collections2.filter(strings, startsWithS));

ところで、これはfilterメソッドに static import を使用して冗長性を少し減らす良い機会かもしれません。

于 2012-04-18T00:13:11.500 に答える
3

これは、クロージャーをサポートする代替 JVM 言語 (Groovy、Scala) に頼ることなく、ネイティブ Java で実行できる最善の方法だと思います。

CollectionUtils.filterCommons Collections は基本的に同じパターンを実装しています -とのドキュメントをチェックしてくださいPredicate。唯一の欠点は、ジェネリックをサポートしていないことです。

http://commons.apache.org/collections/apidocs/org/apache/commons/collections/CollectionUtils.html

したがって、そのルートに進む場合は、既に作成およびテストされているものを使用することもできます。

C# には、LINQ と拡張メソッドを介したこのパターンに対する優れたソリューションもあります。これにより、上記のfilterメソッドに類似したものが、それ自体に属しているように見えCollectionます。

于 2012-04-18T00:16:06.263 に答える