制作一个自己维护倒序的列表

making a list that maintains a reverse order by its own

我的任务是解决以下问题:创建一个将实现 List 的集合 ReverseList。通过使用 for 循环 (for(E e:list)) 迭代 ReverseList 类型的对象列表,我们将按照与输入顺序相反的顺序获取项目。 从 ArrayList

扩展时实现以下 class

所以基本上我需要创建一个不遵循自然插入顺序的集合 让我澄清一下,我不打算在创建列表并添加类似 Collections.reverse() 的项目后反转列表,而是让列表保持自己的顺序

到目前为止我尝试过的是制作自定义迭代器。但是由于某种原因,当我尝试遍历列表时,我被 IndexOutOfBoundsException 抛出(即使列表不为空) 我的代码:

public class ReverseList<E> extends ArrayList<E> implements List<E>{    
private class ReverseIterator<E> extends ReverseList<E> implements Iterator<E> 
{
    private int pos;
    public ReverseIterator()
    {
        pos = super.size()-1;
    }
    public ReverseIterator(ReverseList<E> r)
    {
        pos = r.size()-1;
    }
    
    @Override
    public boolean hasNext() {          
        return pos >= 0;
    }

    @Override
    public E next() {
        return super.get(pos--);
    }
    
}
@Override
public Iterator<E> iterator() {
    // TODO Auto-generated method stub
    return new ReverseIterator<E>(this);
}

public static void main(String[] args)
{
    ReverseList<Integer> r = new ReverseList<>();
    r.add(new Integer(1));
    r.add(new Integer(2));
    r.add(new Integer(3));
    r.add(new Integer(4));
    
    for(Integer i:r)
    {
        System.out.println(i);
    }
}
}

抛出错误:线程“main”中出现异常java.lang.IndexOutOfBoundsException:索引 3 超出长度 0 的范围(在 for 循环中抛出)

为什么列表长度为 0?

我的方法可行吗?有更好的方法吗?

您的 ReverseIteratorReverseList 的子class。这意味着,它本身就是一个列表。然后,您混淆了这两个列表的状态。在 ReverseIterator(ReverseList<E> r) 中,您使用 r 的大小来初始化 pos,在 next() 中,您使用 super.get(pos--),访问其他列表的内容。此其他列表始终为空。

迭代器绝不应该是集合。当您将迭代器实现为内部集合时 class,您可以隐式访问外部集合的状态。

除此之外,您的列表显然违反了List接口的约定并且将来会引起很多其他问题,因为它的iterator()与其他List不一致功能,例如所有基于索引的操作或 listIterator().

您不应该为了单个操作(即向后迭代)而更改 class 的基本原理。相反,将此单个操作作为一个不同的操作来实现。

例如:

public class ReversibleList<T> extends ArrayList<T> {
    private class ReverseIterator implements Iterator<T> {
        private int pos = size() - 1;
  
        @Override
        public boolean hasNext() {          
            return pos >= 0;
        }
  
        @Override
        public T next() {
            return get(pos--);
        }      
    }
  
    public Iterable<T> reverse() {
        return () -> new ReverseIterator();
    }
  
    public static void main(String[] args) {
        ReversibleList<Integer> r = new ReversibleList<>();
        r.add(1);
        r.add(2);
        r.add(3);
        r.add(4);
  
        for(Integer i: r.reverse()) {
            System.out.println(i);
        }
    }
}

reverse() 视图没有自己的存储空间,但始终以相反的顺序反映列表的当前内容。原来的List继续履行它的合同。

请注意,可以创建支持 List 接口的其他操作的列表的反向视图 iterator():

public class ReversibleList<T> extends ArrayList<T> {
    private class ReversedList extends AbstractList<T> implements RandomAccess {
      @Override
      public T get(int index) {
        return ReversibleList.this.get(size() - index - 1);
      }

      @Override
      public int size() {
        return ReversibleList.this.size();
      }
    }

    public List<T> reverse() {
        return new ReversedList();
    }

    public static void main(String[] args) {
        ReversibleList<Integer> r = new ReversibleList<>();
        r.add(1);
        r.add(2);
        r.add(3);
        r.add(4);

        r.reverse().subList(1, 4).stream().forEach(System.out::println);
    }
}