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

发布于 2025-01-09 02:22:03 字数 1457 浏览 0 评论 0原文

我的任务是解决以下问题:创建一个将实现 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?

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

I've been tasked with the following question: create a collection ReverseList that would implement List. by iterating over an object list of type ReverseList with a for loop (for(E e:list)) we would get the items in an order reversed of what they were entered.
implement the following class while extending from ArrayList

so essentially I need to create a collection that doesnt follow the natural ordering of insertion
let me clarify that i am not looking to reverse the list after its creation and adding items with something like Collections.reverse() but rather have the list maintain its own order

what I've tried so far is making a custom Iterator. however for some reason when trying to iterate over the list im getting thrown out with an IndexOutOfBoundsException (even though the list isnt empty)
my code:

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

error thrown: Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 3 out of bounds for length 0 ( thrown at the for loop )

why is the list at length 0?

is my approach even possible? is there a better way to do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

猥琐帝 2025-01-16 02:22:03

您的 ReverseIteratorReverseList 的子类。这意味着,它本身就是一个列表。然后,您混淆了这两个列表的状态。在 ReverseIterator(ReverseListr) 中,您在 next()< 中使用 r 的大小来初始化 pos /code> 您使用 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继续履行它的契约。

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

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

Your ReverseIterator is a subclass of ReverseList. This means, it is a list on its own. Then, you are mixing up the state of these two lists. In the ReverseIterator(ReverseList<E> r), you use r’s size to initialize pos, in next() you use super.get(pos--), accessing the other list’s content. This other list is always empty.

An iterator should never be a collection. When you implement an iterator as an inner class, you can access the outer collection’s state implicitly.

Besides that, your list clearly violates the contract of the List interface and will cause a lot of other problems in the future, as its iterator() is inconsistent with other List features, like all index based operations or listIterator().

You should not change the fundamentals of a class, just for the sake of a single operation (i.e. iterate backwards). Rather, implement this single operation as a distinct operation.

For example:

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

The reverse() view has no storage of its own but always reflects the current contents of the list, in reverse order. The original List keeps fulfilling its contract.

Note that it is possible to create reversed view to a list supporting other operations of the List interface beyond 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);
    }
}
和我恋爱吧 2025-01-16 02:22:03

自然顺序插入顺序

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

这是一个矛盾的术语。自然排序不是插入顺序。

  • 自然顺序表示按类的compareTo 比较接口。
  • 显然,插入顺序是指将项目添加到集合中的顺序。

列表#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:排序集合

Natural order versus insertion order

create a collection that doesnt follow the natural ordering of insertion

That is a contradiction in terms. Natural ordering is not insertion order.

  • Natural order means sorting by the class’s implementation of the compareTo method required by the Comparable interface.
  • Insertion order, obviously, means the order in which an item was added to the collection.

List#reversed

i am not looking to reverse the list after its creation

So build the list in the normal direction. Afterwards, in Java 21+, simply call List#reversed to get a view on that list that presents an encounter order that is the opposite of the default encounter order.

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

When run:

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

To learn more, see JEP 431: Sequenced Collections.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文