【问题标题】:Java list best practiceJava 列表最佳实践
【发布时间】:2011-08-26 20:21:28
【问题描述】:

我需要一些容器来保存元素,所以如果我尝试获取 size()+i 元素,我将获得元素编号 i。还是使用迭代器,它在尝试获取最后一个元素后从容器的开头开始?两种情况下的最佳做法是什么?我的意思是性能和易用性。

【问题讨论】:

  • 我认为这被称为“环形缓冲区”或“循环缓冲区”。不确定 Java,C++ 在 Boost 中有一个...
  • 你确定拥有这样的数据结构是个好主意吗?你需要它做什么?
  • 我有一个 DodgerAI 类,它为游戏中的某些英雄处理 AI。它有一个字段——英雄和字段的索引,代表游戏逻辑。 AI中有很多情况(DodgerAI中的方法),必须分析除英雄之外的所有英雄,由AI控制。这就是为什么我想使用某种“环”。

标签: java iteration containers


【解决方案1】:

您可以创建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(); }
}

然后您将覆盖RingList&lt;T&gt; 中的iterator() 方法

public Iterator<T> iterator()
{
    return new RingIterator(this);
}

【讨论】:

  • 不应该所有方法(remove 等)都使用相同的索引,而不仅仅是 get?小错误:当cur 换行时..
  • @dacwe:当然。我可以说“留给读者作为练习”:-)
  • :-) 太好了,现在只是一个空列表的情况,但我们离开了 ;-)
  • 上面的代码中似乎也实现了空列表状态,所以没有留下:)。
【解决方案2】:

对于第一部分,也许只要求n % list.size()

对于迭代器部分,创建一个包装迭代器的类,当next()返回null时,让它重置迭代器。

【讨论】:

    【解决方案3】:

    谢谢大家,这就是我创建的:

    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();
    }
    

    }

    然后get方法:

    /*
     * 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();
    

    我想通过 getRingIter 只提供类型 ParentClass(而不是 SubClass),但我没有看到不创建 List 的方法 - List 的转换。

    【讨论】:

      【解决方案4】:

      扩展 ArrayList 类并以您喜欢的方式实现get(Integer) 方法。我认为这是“最佳实践”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-03-22
        • 1970-01-01
        • 2015-03-14
        • 2019-07-10
        • 1970-01-01
        • 2010-09-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多