Как сдвинуть ArrayList - PullRequest
       1

Как сдвинуть ArrayList

4 голосов
/ 03 июня 2011

Я использую ArrayList для хранения истории объектов.Каждый новый объект, который я добавляю, используя метод .add, например:

if(event.getAction() == MotionEvent.ACTION_UP)
{
    if(currentWord != null)
    {
        wordHist.add(currentWord);
    }

    if(wordHist.size() > WORDHIST_MAX_COUNT)
    {
        wordHist.remove(0);
    }
}

Однако я не хочу, чтобы это увеличивалось бесконечно, но ограничивалось определенным значением.Если оно достигает этого максимального значения, я хочу, чтобы самый старый объект (индекс 0) был удален, а остальное было смещено влево, поэтому предыдущий индекс 1 теперь является индексом 0 и т. Д.

Как это можно сделать?

Спасибо

Ответы [ 7 ]

2 голосов
/ 03 июня 2011

ArrayList не очень хороший выбор в этом случае , но это можно сделать, вызвав remove (0) метод. Но если вы хотите сделать это эффективно, лучше использовать связанный список

(отредактировано, чтобы показать, что LinkedList обычно не лучше ArrayList, но только в этом случае)

1 голос
/ 03 июня 2011

Если оно достигает этого максимального значения, я хочу удалить самый старый объект (индекс 0)

Тогда сделай wordHist.remove(0). Это удалит элемент с индексом 0.

Чтобы быть точным:

wordHist.add(new Word("hello"));
if (wordHist.size() > MAX_SIZE)
    wordHist.remove(0);

Однако, как заявляет пользователь 658991, вы должны знать, что это линейная операция, т. Е. Требует времени, пропорционального количеству элементов в списке.

Вы можете сделать это в постоянное время, используя LinkedList методы add и removeFirst.

Другой вариант - обернуть массив или ArrayList в классе, который называется что-то вроде CircularArrayList. В структурах циклического списка вы переопределяете самый старый элемент при добавлении нового.

Edit:

Ваш код работает нормально:

import java.util.*;
class Test {

    static int WORDHIST_MAX_COUNT = 3;
    static List<String> wordHist = new ArrayList<String>();

    public static void add(String currentWord) {

        // VERBATIM COPY OF YOUR CODE

        if (true/*event.getAction() == MotionEvent.ACTION_UP*/)
        {
            if(currentWord != null)
            {
                wordHist.add(currentWord);
            }

            if(wordHist.size() > WORDHIST_MAX_COUNT)
            {
                wordHist.remove(0);
            }
        }
    }

    public static void main(String[] args) {
        add("a");
        add("b");
        add("c");

        for (int i = 0; i < wordHist.size(); i++)
            System.out.printf("i: %d, word: %s%n", i, wordHist.get(i));
        System.out.println();

        add("d");

        for (int i = 0; i < wordHist.size(); i++)
            System.out.printf("i: %d, word: %s%n", i, wordHist.get(i));
    }
}

Печать:

i: 0, word: a
i: 1, word: b
i: 2, word: c

i: 0, word: b        <-- b is now at index 0.
i: 1, word: c
i: 2, word: d
0 голосов
/ 14 июля 2012

Commons-collection имеет именно то, что вы ищете:

http://commons.apache.org/collections/apidocs/org/apache/commons/collections/buffer/CircularFifoBuffer.html

0 голосов
/ 13 июля 2012

Да, я тоже заметил это в списках адроидов. Это действительно раздражает.

В любом случае, есть способ обойти это, если я не возражаю против создания / уничтожения объекта и получающейся в результате сборки мусора (НИКОГДА не делайте этого в onDraw вида поверхности или чего-то еще).

То, что я делаю, в основном имеет два отслеживания int; один для размещения нового объекта и один для его удаления:

                int trackInt = 0;
                int removeInt = 0;

                //and then, in the method/class you use this:

                Object newobject = new Object();
                //add to list
                objectList.add(trackInt, newobject);
                trackInt++;
                if (bugList.size() > 20) //20 is the max number of object you want, ie the maximum size of the list
                {
                    objectList.remove(removeInt);
                    trackInt = removeInt;
                    removeInt++;
                    if (removeInt > 19) //remember, the list is zero indexed!
                    {
                        removeInt = 0;
                    }
                }
0 голосов
/ 03 июня 2011

Одна простая реализация того, что предложил Op De Cirkel

import java.util.ArrayList;
import java.util.List;


public class SimpleCircularHistory {

    private int sizeLimit, start = 0, end = 0;
    boolean empty = false;
    private List<String> history;

    public SimpleCircularHistory(int sizeLimit) {
        this.sizeLimit = sizeLimit;
        history = new ArrayList<String>(sizeLimit);
    }

    public void add(String state){ 
        empty = false;
        end = (end + 1) % sizeLimit;
        if(history.size() < sizeLimit){
            history.add(state);
        }else {
            history.set(end, state);
            start = (end + 1) % sizeLimit;
        }
    }

    public String rollBack(){
        if(empty){ // Empty
            return null;
        }else {
            String state = history.get(end);
            if(start == end){
                empty = true;
            }else {
                end = (end + sizeLimit - 1) % sizeLimit;
            }
            return state;
        }
    }

    public void print(){
        if(empty){
            System.out.println("Empty");
        }else {
            for(int i = start;; i = (i + 1) % sizeLimit){
                System.out.println(history.get(i));
                if(i == end) break;
            }
            System.out.println();
        }
    }

    public static void main(String[] args) {
        SimpleCircularHistory h = new SimpleCircularHistory(3);
        h.add("a");
        h.add("b");
        h.add("c");
        h.add("d");
        h.add("e");
        h.add("f");
        h.print();

        h.add("X");
        h.add("Y");
        h.rollBack();
        h.rollBack();
        h.print();
        h.add("t");
        h.add("v");
        h.add("w");
        h.print();
        h.rollBack();
        h.rollBack();
        h.rollBack();
        h.print();
        h.rollBack();
        h.print();
    }

}

Это напечатало бы:

d
e
f

f

t
v
w

Empty
Empty
0 голосов
/ 03 июня 2011

U может использовать list.remove (index) // здесь index равен '0', это внутренне сдвигает остаток массива вверх. Альтернативным решением будет использование очереди или очереди.

0 голосов
/ 03 июня 2011

Используйте метод remove( ).

Использование remove(0) удалит элемент из 0-го индекса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...