[英]How to increase the performance with Java ArrayList
我在下面的代碼中使用了巨大的ArrayList
public final List<MyClass> list = new ArrayList<>();
public void update(MyClass myClass) {
int i;
for (i=0; i < list.size(); i++) {
if (myClass.foo(list.get(i))) {
list.set(i, myClass);
break;
}
}
if (i == list.size()) {
list.add(myClass);
}
}
該列表非常大。 在這種情況下,我還可以采取其他措施來提高性能嗎? 也許使用某些Java 8功能,替換ArrayList或類似的東西。
與該列表相關的另一個運行時間過長的代碼是以下代碼:
public List<MyClass> something(Integer amount) {
list.sort((m1, m2) -> Double.compare(m2.getBar(), m1.getBar()));
return list.stream()
.limit(amount)
.collect(Collectors.toList());
}
歡迎任何幫助,謝謝大家
似乎ArrayList
的選擇不好。
在第一種情況下,您嘗試通過列表中對象的屬性查找對象。 要在列表中找到對象,您必須檢入列表中的每個元素。 列表越大,則列表越長。 (在最差情況下,使用ArrayList的復雜度為O(N))
如果使用HashMap
而不是List
,則可以將屬性用作地圖的鍵。 這樣,您可以選擇需要直接更新的對象,而無需檢查列表中的每個元素。 執行時間將不再取決於條目數。 (使用HashMap的情況下,復雜度為O(1))
如果您使用HashMap
而不是ArrayList
,則更新代碼將如下所示:
public void update(MyClass myClass) {
map.put(myClass.getKey(), myClass);
}
(其中getKey()
是您嘗試在foo方法中等於的屬性)。
但這僅適用於第一種情況。 有了這些信息,我們似乎是最好的解決方案。
在這種情況下,我還可以采取其他措施來提高性能嗎?
問題是您的算法必須將myClass.foo
應用於列表的每個元素,直到找到第一個匹配項為止。 如果串行執行此操作,則最壞情況下的復雜度是O(N)
,其中N
是列表大小。 (並且列表很大。)
現在,您可以並行進行搜索。 但是,如果可以有多個匹配項,則匹配列表中的第一個將很棘手。 而且您仍然以O(N/C)
結尾,其中C
是可用的內核數。
比O(N)
更好的唯一方法是使用不同的數據結構。 但是,不知道MyClass::foo
方法的作用,很難說出該數據結構應該是什么。
您的第二個問題似乎是試圖解決“ N的前K個”問題。 這可以在O(N log K)
實現,並且可能更好。 請參閱用於從長度為N的數組返回前k個值的最佳算法 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.