制作一个自己维护倒序的列表
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?
我的方法可行吗?有更好的方法吗?
您的 ReverseIterator
是 ReverseList
的子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);
}
}
我的任务是解决以下问题:创建一个将实现 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?
我的方法可行吗?有更好的方法吗?
您的 ReverseIterator
是 ReverseList
的子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);
}
}