簡體   English   中英

如何使用Java ArrayList提高性能

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM