Java список лучших практик - PullRequest
3 голосов
/ 27 августа 2011

Мне нужен контейнер для хранения элементов, поэтому, если я попытаюсь получить элемент size () + i, я получу номер элемента i.Или с итератором, который начинается с начала контейнера после того, как он пытается получить последний элемент?Каковы лучшие практики в обоих случаях?Я имею в виду производительность и простоту использования.

Ответы [ 4 ]

9 голосов
/ 27 августа 2011

Вы можете создать простой подкласс ArrayList<T> и переопределить метод get(int n) следующим образом:

public T get(int n)
{
    return super.get(n % this.size());
}

Что касается итератора, вам потребуется реализовать свой собственный, который не должен бытьвсе это сложно.

РЕДАКТИРОВАТЬ:

Предполагая, что ваш новый класс называется RingList, вот пример RingIterator (не проверено):

public class RingIterator<T> implements Iterator<T>
{
    private int cur = 0;
    private RingList<T> coll = null;

    protected RingIterator(RingList<T> coll) { this.coll = coll; }
    public boolean hasNext() { return size() > 0; }
    public T next() 
    { 
        if (!hasNext()) 
            throw new NoSuchElementException();
        int i=cur++; 
        cur=cur%size(); 
        return coll.get(i);
    }
    public void remove() { throw new UnsupportedOperationException(); }
}

Затем вы переопределите iterator() метод в RingList<T> как

public Iterator<T> iterator()
{
    return new RingIterator(this);
}
2 голосов
/ 27 августа 2011

Для первой части просто спросите n % list.size() возможно?

Для части итератора создайте класс, который обертывает итератор, и когда next () вернет значение null, просто сбросьте итератор.

1 голос
/ 27 августа 2011

Спасибо всем, вот что я создал:

public class RingIterator<E> {
private List<E> _lst;
private ListIterator<E> _lstIter;

public RingIterator(ListIterator<E> iter, List<E> lst) {
    super();
    _lstIter = iter;
    _lst = lst;
}

public E next() {
    if(!_lstIter.hasNext())
        _lstIter = _lst.listIterator();
    return _lstIter.next();
}

public E previous() {
    if(!_lstIter.hasPrevious())
        _lstIter = _lst.listIterator(_lst.size());
    return _lstIter.previous();
}

}

Тогда получите метод:

/*
 * Returns ring iterator,
 * use it with 'ParentClass' type.
 */
public RingIterator<SubClass> getRingIter(int i) {
    return new RingIterator(_subs.listIterator(i),_subs);
}

И я им пользуюсь:

RingIterator<SubClass> ri = _logic.getRingIter(1);
ParentClass ai = ri.next();

Я хотел сделать доступным только тип ParentClass (не SubClass) через getRingIter, но я не вижу способа сделать это без создания List - преобразование List.

0 голосов
/ 27 августа 2011

Расширьте класс ArrayList и реализуйте метод get(Integer) так, как вам нравится.Я думаю, что это «лучшая практика».

...