web-dev-qa-db-ja.com

Java:セットからn個の要素を取得する方法

私はxから始まるセットからn個の要素を取得する最もエレガントな方法を見つけようとしていました。私が結論付けたのはストリームを使用することでした:

Set<T> s;
Set<T> subS = s.stream().skip(x).limit(n).collect(Collectors.toSet());

これは、この方法で行うのに最適な方法ですか?欠点はありますか?

14
Diaa

Steve Kuoの回答に似ていますが、最初のx要素もスキップしています。

Iterables.limit(Iterables.skip(s, x), n);

Guava Iterables

12
JamesB

Guava、Iterables.limit(s, 20)を使用します。

9
Steve Kuo

コードが機能しません。

Set<T,C> s;
Set<T,C> subS = s.stream().skip(x).limit(n).collect(Collectors.toSet());

とは Set<T,C>Setには特定のタイプの要素が含まれているので、twoタイプのパラメーターは何を意味するのですか?

さらに、Set<T>、定義された順序はありません。 「xから始まるセットのn個の要素」は、Setのコンテキストでは意味がありません。いくつかの特殊なSet実装があり、順序があります。はソートされるか挿入順序を保持しますが、コードはそのような前提条件を宣言していませんが、任意のSetで動作するように思われるため、壊れていると見なす必要があります。

Setの一部を注文に従って処理する場合は、最初に注文を凍結する必要があります。

Set<T> s;
List<T> frozenOrder=new ArrayList<>(s);

リストには、Setの作成時に固定された、または任意の順序がある場合、ArrayListの順序になります。この順序は後で変更されません。

次に、そのフラグメントを抽出するのは簡単です:

List<T> sub=frozenOrder.subList(x, Math.min(s.size(), x+n));

必要に応じて、Setに戻すこともできます。

Set<T> subSet=new HashSet<>(sub);

とはいえ、位置番号で指定されたSetの一部を処理することはかなり珍しいことです。

5
Holger

セットを繰り返し処理して、最初のn個の要素を収集できます。

int n = 0;
Iterator<T> iter = set.iterator();
while (n < 8  && iter.hasNext()) {
 T t = iter.next();
 list.add(t);
 n++;
}

利点は、より一般的なソリューションよりも高速であることです。

欠点は、提案したものよりも冗長であることです。

1
Ivan Mushketyk

セットは、元の方法では、要素を順序付けすることを目的としていないため、要素xから開始することはできません。 SortedSetは、使用する「セット」である場合があります。

最初にリストに変換します。

_    new ArrayList(s).subList(<index of x>, <index of x + n>);
_

ただし、パフォーマンスに非常に悪い影響を与える可能性があります。この場合、明示的な順序がないため、ArrayListを格納して次のsubListを取得する必要があり、暗黙の順序は、次回new ArrayList(s)が呼び出されたときに変更される可能性があります。

1
Johannes

Streamの使用は問題ありません。私が見ることができる1つの欠点は、Setのすべての実装が順序付けされているわけではないことです。 HashSetは順序付けされていませんが、LinkedHashSetは順序付けされています。 SO実行ごとに結果セットが異なる場合があります。

1
barunsthakur

まず、セットはその特定の要素を取得するために作成されていません。代わりに、sortedSetまたはArrayListを使用する必要があります。

ただし、セットの要素を取得する必要がある場合は、次のコードを使用してセットを反復できます。

int c = 0;
int n = 50; //Number of elements to get
Iterator<T> iter = set.iterator();
while (c<n  && iter.hasNext()) {
   T t = iter.next();
   list.add(t);
   c++;
}
1
Coder55