是否有一個班輪在新的LinkedHashSet中獲取LinkedHashSet的最後5個元素?獲取LinkedHashSet的最後5個元素的子列表?
這是我現在有,但它是不是很有效:
new LinkedHashSet<String>(new LinkedList<String>(set)
.subList(Math.max(0, set.size() - 5), set.size());
或者我應該使用這種情況下一個TreeSet,SortedSet的,HashSet的?
是否有一個班輪在新的LinkedHashSet中獲取LinkedHashSet的最後5個元素?獲取LinkedHashSet的最後5個元素的子列表?
這是我現在有,但它是不是很有效:
new LinkedHashSet<String>(new LinkedList<String>(set)
.subList(Math.max(0, set.size() - 5), set.size());
或者我應該使用這種情況下一個TreeSet,SortedSet的,HashSet的?
我結束了使用此:
com.google.common.collect.EvictingQueue<E>
這個你只保留最後x元素。
EvictingQueue<String> queue = EvictingQueue.create(5);
如果使用Java 8,你確定要回一個HashSet
(而不是LinkedHashSet
),你可以使用Stream API:
Set<String> newSet = set.stream()
.skip(set.size() - 5)
.collect(Collectors.<String>toSet());
使用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);
您的測試存在缺陷。第二個測試案例受益於第一種情況已經預熱了緩存。每個測試都需要在自己的運行時調用中運行。 –
@SteveKuo無論我是否單獨跑步並獲得更好的表現:) – muzahidbechara
這是問題所在。 LinkedHashSet
的迭代器是單向的;即不能向後迭代,即使底層數據結構具有雙向鏈接列表。這意味着你需要迭代到列表的最後。那是O(N)
。
在你的算法中,LinkedList
構造函數使用(可能)迭代器將該集合複製到新的數據結構中。
相反,TreeSet
API有一個descendingIterator()
方法,該方法返回一個Iterator
,它向後遍歷列表。如果你正確地使用它,你可以得到O(1)
中最後5個元素的集合。缺點是對於基於散列的集合,將元素添加到集合將是O(logN)
而不是O(1)
。
請解釋這是如何涉及到你問的問題。它是如何滿足你陳述的要求/實際要求的?你怎麼使用它? –