2

と がある場合ArrayList<Double> dblList、次の使用Predicate<Double> IS_EVENからすべての偶数要素を削除できます。dblList

Collections2.filter(dblList, IS_EVEN).clear()

dblListただし、次のような変換の結果である場合

dblList = Lists.transform(intList, TO_DOUBLE)

変換されたリストは不変であるため、これはもはや機能しません:-)

解決策はありますか?

4

6 に答える 6

2

Lists.transform()は List を受け取り、 RandomAccessリストである結果を返します。Iterables.transform()は Iterable のみを受け入れ、結果は RandomAccess ではありません。最後に、Iterables.removeIf (私が見る限り、これは Iterables で唯一のものです) は、与えられた引数が RandomAccess である場合に最適化されています。そのポイントは、アルゴリズムを二次ではなく線形にすることです。大きなArrayList(ArrayDequeではなく、より一般的である必要があります)があり、最初から空になるまで要素を削除し続けた場合に発生します。

しかし、最適化は iterator remove() ではなくList.set()に依存します。これは、変換されたリストではサポートできない可能性があります。これを修正するには、「オプションの set() が実際に機能する」ことを示すために、別のマーカー インターフェイスが必要になります。

したがって、次のオプションがあります。

  • Iterables.removeIf() バージョンを呼び出し、二次アルゴリズムを実行します (リストが小さいか、削除する要素が少ないかは関係ありません)。
  • List を、すべてのオプション操作をサポートする別の List にコピーしてから、Iterables.removeIf()を呼び出します。
于 2010-07-08T08:46:04.553 に答える
1

まだ試していませんが、次のアプローチが機能するはずです。

Collection<Double> dblCollection =
    Collections.checkedCollection(dblList, Double.class);
Collections2.filter(dblCollection, IS_EVEN).clear();

checkCollection() メソッドは、List を実装しないリストのビューを生成します。[代わりに ForwardingCollection を作成する方がクリーンですが、より冗長になります。] 次に、Collections2.filter() は、サポートされていない set() メソッドを呼び出しません。

ライブラリ コードをより堅牢にすることができます。Iterables.removeIf() は、Michael D が提案したように、変換されたリストが渡されると、合成された述語を生成できます。ただし、そのような特殊なケースのロジックを追加してコードを複雑にしないことは以前に決めていました。

于 2010-07-08T17:22:10.873 に答える
0

Iterables.removeIf()解決策がありません。代わりに、 との組み合わせで何らかの問題が見つかりましたLists.TransformingRandomAccessList

変換されたリストは RandomAccess を実装するため、サポートされていない List.set() 操作に依存する which にIterables.removeIf()委譲します。ただし、remove() 操作は でサポートされているため、Iterables.removeIfFromRandomAccessList()呼び出しは成功します。Iterators.removeIf()Lists.TransformingRandomAccessList

参照: イテラブル: 147

結論: instanceof RandomAccess は List.set() を保証しません。

追加: removeIfFromRandomAccessList() を呼び出す特別な状況では、削除する要素が List の末尾でコンパクトなグループを形成する場合、またはすべての要素が Predicate によってカバーされる場合にのみ機能します。

于 2010-07-08T10:33:40.183 に答える
0

中間コレクションが必要ない限り、 Predicates.compose() を使用して、最初にアイテムを変換し、次に変換されたアイテムで述語を評価する述語を作成できます。

たとえば、整数部分が偶数であるすべての項目を削除したい List<Double> があるとします。私はすでに、整数部分を提供する Function<Double,Integer> と、それが偶数かどうかを教えてくれる Predicate<Integer> を持っています。

これらを使用して、新しい述語 INTEGER_PART_IS_EVEN を取得できます。

Predicate<Double> INTEGER_PART_IS_EVEN = Predicates.compose(IS_EVEN, DOUBLE_TO_INTEGER);
Collections2.filter(dblList, INTEGER_PART_IS_EVEN).clear();
于 2010-07-07T20:31:07.590 に答える
0

多分:

Collection<Double> odds = Collections2.filter(dblList, Predicates.not(IS_EVEN));

また

dblList = Lists.newArrayList(Lists.transform(intList, TO_DOUBLE));
Collections2.filter(dblList, IS_EVEN).clear();
于 2010-07-07T19:18:12.713 に答える
0

いくつかの試行の後、私はそれを見つけたと思います:)

final ArrayList<Integer> ints = Lists.newArrayList(1, 2, 3, 4, 5);
Iterables.removeIf(Iterables.transform(ints, intoDouble()), even());
System.out.println(ints);

[1,3,5]
于 2010-07-08T08:14:43.407 に答える