当前位置: 首页 > 知识库问答 >
问题:

制作一份自己维持相反顺序的清单

魏硕
2023-03-14

我被赋予了以下问题:创建一个集合ReverseList,将实现列表。通过遍历带有for循环(for(E e: list))的类型为ReverseList的对象列表,我们将获得与它们所包含的顺序相反的项。在从ArrayList扩展时实现以下类

因此,本质上我需要创建一个集合,它不遵循插入的自然顺序。让我澄清一下,我不希望在创建列表并添加类似集合的项目后,反转列表。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?

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

共有1个答案

房子昂
2023-03-14

您的ReverseIteratorReverseList的子类。这意味着,它本身就是一个列表。然后,您将混合这两个列表的状态。在ReverseIterator(ReverseList

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

除此之外,您的列表显然违反了list接口的约定,并将在将来导致许多其他问题,因为它的iterator()与其他list功能不一致,如所有基于索引的操作或listediterator()

您不应该仅仅为了一个操作(即向后迭代)而更改类的基础知识。相反,将这个单一操作作为一个独特的操作来实现。

例如:

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()视图本身没有存储空间,但总是以相反的顺序反映列表的当前内容。原始的列表继续履行其合同。

请注意,除了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);
    }
}

 类似资料:
  • 问题内容: 我有一个LinkedHashMap: 我需要从给定键的位置向后迭代。因此,如果为我提供了第十个项目的密钥,则需要向后迭代哈希表9、8、7等。 问题答案: 您不必遍历它。但是拔下钥匙并将其存储在列表中会很方便。这就是执行indexOf()类型操作的唯一方法。

  • 我按直接顺序列出了列表1<代码>列表 如何更改顺序。我不知道如何重写扩展类中的方法,请用例子写或说清楚。

  • 问题内容: 我需要阅读该文件,该文件提供了我的课程,但是当我使用时: 我MANIFEST从第一个加载到Java运行时中就得到了。 我的应用程序将从或运行, 所以我无法访问自己的文件。 我实际上是想从启动的中读取属性,因此可以将这些包公开给Felix。有任何想法吗? 问题答案: 你可以执行以下两项操作之一: 调用并遍历返回的URL集合,将它们作为清单读取,直到找到你的URL: 你可以尝试检查是否是的

  • 我只需要反转字符串中的字母,并使用将符号和数字保持在相同的位置,并且我还需要保持反转单词的相同顺序。我的代码反转字符串并将符号和数字保持在适当的位置,但更改单词的顺序,例如: 我的输入字符串: a1bcd efg!H 我的输出字符串: h1gfe dcb!A. 相反,我的输出应该是: d1cba hgf! e

  • 都会用到cur的值。但是默认先执行的click。那我现在的代码逻辑就有问题。需要全部在click里判断了。 有办法先执行 change 么。