簡體   English   中英

我應該使用哪種Java集合類型?

[英]Which Java collection type should I use?

我正在嘗試在Java中創建“受限列表”。 如果我添加新條目,它將刪除舊條目。

例如,如果列表大小為3,並且我添加了第4個項目,則應該刪除第一個項目。 目前,我在ArrayList使用remove(0)解決了此問題,但我聽說ArrayList的速度非常慢。

有沒有更快的方法來解決這個問題? 我當前的代碼是:

public class LimitedList<T> extends ArrayList<T> {
    private int maximum;

    public LimitedList(int maximum) {
        this.maximum = maximum;
    }

    @Override
    public boolean add(T t) {
        boolean r = super.add(t);
        while (size() > maximum) {
            remove(0);
        }
        return r;
    }

}

但是我聽說ArrayList的速度很慢。

對於ArrayList 某些操作很慢,而對於其他集合, 某些操作則很慢。 這是因為ArrayList在窗簾后面使用了一個數組,並且為了在頭部執行刪除操作,它必須將所有元素向左移動。 因此,就大哦而言,從頭移除是ArrayListO(n) ,而從LinkedList的頭是O(1)

如果您只想在集合的末尾添加項目,並在頭部刪除元素,那么我建議您使用LinkedList

public class LimitedList<T> extends LinkedList<T> {

    private int maximum;

    public LimitedList(int maximum) {
        this.maximum = maximum;
    }

    @Override
    public boolean add(T t) {
        boolean r = super.add(t);
        int n = this.size();
        while (n > maximum) {
            this.removeFirst();
            n--;
        }
        return r;
    }

}

@JBNizet的一個重要說明是,您應該直接從ArrayListLinkedList繼承,但是要實現Collection<T> ,例如:

public class LimitedList<T> implements Collection<T> {

    private final LinkedList<T> list;
    private int maximum;

    public LimitedList(int maximum) {
        this.list = new LinkedList<T>();
        this.maximum = maximum;
    }

    @Override
    public boolean add(T t) {
        boolean r = this.list.add(t);
        int n = this.list.size();
        while (n > maximum) {
            this.list.removeFirst();
            n--;
        }
        return r;
    }

    //implement other Collection methods...

}

請:不要在“您聽到的內容”上多說幾句。 編程是關於硬事實,而不是傳聞。 您可以確定所有收集實現都是由該領域的專家編寫的; 因此,第一件事是查看那里的各種文檔,以評估您所需的操作是否確實帶有顯着的性能標簽 是的,收集操作具有不同的成本,但是所有這些都已記錄在案。

然后:如果您真的只在談論3、4個要素……您真的真的認為績效很重要嗎? 僅當您將此列表每分鍾(數千次)數千次使用時才是這種情況。 請記住,當今的現代CPU在幾微秒內能做什么? 以及需要多少次方法調用才能使“調用B慢5納秒”。

換句話說:爭取良好,干凈(基於SOLID的)設計; 而不用擔心潛在的性能問題。 與在此類主題上花費數小時相比,這將帶來10倍的回報。

您會看到:應該對“性能問題”非常小心。 因為:當用戶提出投訴時,您才意識到自己只有一個...。 而且,如果發生這種情況,您就不會盲目地嘗試改善這一點; 不,那么您首先要進行性能分析以衡量問題的根源。 然后您修復那些需要改進的東西。

編輯:所以您的最后一條評論表明您進行了某種衡量(提示:如果您直接這么說,而不是寫“我聽說列表很慢”……可能您已經得到了不同的答案)。 好的,假設您進行了良好的性能分析(其中:即使一種收集類型對您而言執行速度較慢,問題仍然是:它會經常被調用而引起麻煩)。 無論如何:您真正想要做的是了解您對代碼執行的訪問模式 您是否需要隨機訪問,是否在列表中進行迭代等等?通常您會看到一個容器,該容器會遺忘元素……聽起來更像是一個緩存,而不是列表。 從這個意義上說:您是否依賴於對象的快速順序檢索? 或如何訪問數據? 這些是您必須問自己的問題; 只有這樣,您才能決定是否應該實施自己的特殊限制列表; 或者是否有現有組件(可能來自apache commons或番石榴)滿足您的需求。

我認為您應該使用隊列,因為這種收集使用FIFO過程(先進先出)。 因此,您插入的第一個元素將是第一個出現的元素,您可以使用Enqueue和Dequeue(均在O(1)中運行)之類的方法來簡單地管理隊列。

如果您擅長編寫代碼,最好的選擇是不要擴展任何現有集合並創建自己的集合。 對於列表,可以實現列表接口。(推薦的方法是采用AbstractList抽象類)

這將為您提供更多控制權,並且可以設計速度。

最快的選擇是轉儲集合並僅使用數組(類中的包裝操作)。 但是,這可能不適合您,因為它不在集合層次結構中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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