0

LinkedHashSet の最後の 5 つの要素を新しい LinkedHashSet で取得するためのライナーはありますか?

これは私が現在持っているものですが、あまり効率的ではありません:

new LinkedHashSet<String>(new LinkedList<String>(set)
.subList(Math.max(0, set.size() - 5), set.size());

または、この場合、 TreeSet 、 SortedSet 、 HashSet を使用する必要がありますか?

4

4 に答える 4

0

これが問題です。a の反復子LinkedHashSetは単方向です。つまり、基礎となるデータ構造に双方向リンク リストがある場合でも、逆方向に反復することはできません。つまり、最後の N を取得するには、リストの最後まで繰り返す必要があります。それはO(N)です。

あなたのアルゴリズムでは、LinkedListコンストラクターは (おそらく) イテレーターを使用してセットを新しいデータ構造にコピーしています。

対照的に、TreeSetAPI には、リストを逆方向に反復するdescendingIterator()を返すメソッドがあります。Iteratorこれを正しく使用すると、セットの最後の 5 つの要素を で取得できますO(1)。欠点は、要素をセットに追加すると、ハッシュベースのセットのO(logN)代わりになることです。O(1)

于 2016-04-10T07:01:00.717 に答える
0

Java 8 を使用していて、HashSet( の代わりにLinkedHashSet) を取得しても問題ない場合は、Stream API を使用できます。

Set<String> newSet = set.stream()
                        .skip(set.size() - 5)
                        .collect(Collectors.<String>toSet());
于 2016-04-10T06:04:52.013 に答える
0

を使用ArrayListすると、パフォーマンスが向上します。

long s1 = System.nanoTime();
LinkedHashSet<String> last5 = new LinkedHashSet<String>(new LinkedList<String>(set)
        .subList(Math.max(0, set.size() - 5), set.size()));
System.out.println(System.nanoTime() - s1);

s1 = System.nanoTime();
LinkedHashSet<String> usingArrayList = new LinkedHashSet<String>(new ArrayList<String>(set)
        .subList(Math.max(0, set.size() - 5), set.size()));
System.out.println(System.nanoTime() - s1);
于 2016-04-10T06:23:57.447 に答える
0

私はこれを使用することになりました:

com.google.common.collect.EvictingQueue<E>

これにより、最後の x 要素のみを保持できます。

EvictingQueue<String> queue = EvictingQueue.create(5);
于 2016-04-10T09:48:02.503 に答える