制作一个自己保持相反顺序的列表

问题描述 投票:0回答:2

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

所以本质上我需要创建一个不遵循插入自然顺序的集合 让我澄清一下,我不希望在创建列表后反转列表并使用 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?

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

java collections iterator
2个回答
3
投票

您的

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

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

除此之外,您的列表显然违反了

List
接口的约定,并且将来会导致很多其他问题,因为它的
iterator()
与其他
List
功能不一致,例如所有基于索引的操作或
listIterator() 
.

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

例如:

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

0
投票

自然顺序 插入顺序

创建一个不遵循插入自然顺序的集合

这是一个矛盾的说法。自然顺序不是插入顺序。

  • 自然顺序 表示按照
    compareTo
    接口所需的
    Comparable
    方法的类实现进行排序。
  • 插入顺序显然是指将项目添加到集合中的顺序。

List#reversed

我不打算在创建后反转列表

所以按照正常方向构建列表。之后,在 Java 21+ 中,只需调用

List#reversed
即可获取该列表上的视图,该视图显示与默认遭遇顺序相反的遭遇顺序。

List < Integer > integers = new ArrayList <>( 3 );
integers.add( 42 );
integers.add( 99 );
integers.add( 7 );
System.out.println( "integers = " + integers );

Collections.sort( integers );  // Sort in natural order.
List < Integer > reversedIntegers = integers.reversed( );  // Present encounter order that is opposite of the previously set natural order.

System.out.println( "integers = " + integers );
System.out.println( "reversedIntegers = " + reversedIntegers );

运行时:

integers = [42, 99, 7]
integers = [7, 42, 99]
reversedIntegers = [99, 42, 7]

要了解更多信息,请参阅 JEP 431:排序集合

© www.soinside.com 2019 - 2024. All rights reserved.