[英]How to implement subList() in Custom ArrayList
我正在实现我自己的通用 ArrayList,一切都很好,但我对最后一个方法有问题 - List subList(int fromIndex, int toIndex)。 我已经尝试实现它,但我仍然只创建了主列表的副本并仅对其进行了修改。 我目前的代码是
public List<T> subList(int fromIndex, int toIndex) {
if (fromIndex < 0 || toIndex > size() || fromIndex > toIndex)
throw new IndexOutOfBoundsException();
Object subarray[] = new Object[toIndex - fromIndex];
for (int i = 0; i < subarray.length; i++) {
subarray[i] = array[fromIndex + i];
}
List<T> subList = Arrays.asList((T) subarray);
return subList;
}
我也尝试使用 ArrayList 而不是数组来完成它,但它仍然不起作用(只修改我的新子列表而不是整个列表)。 我该如何修复它? 我必须实施另一个 class 吗?
编辑我也添加了我的测试方法,我仍然失败(主列表中的值没有改变)
@Test
void subListWithoutNulls() {
CustomArrayList<Integer> array = new CustomArrayList<>();
array.add(3);
array.add(7);
array.add(2);
array.add(5);
array.add(8);
array.add(3);
array.subList(1, 4).set(0, 12);
assertEquals(12, array.get(1));
}
如果您从AbstractList
派生,将为您提供一个实现: https://docs.oracle.com/javase/7/docs/api/java/util/AbstractList.html#subList(int,%20int)
否则,您将不得不编写一个新的 class 来正确地将所有内容委托给原始列表。
假设您这样做是一种学习练习,下面是创建具有传递行为的子列表的一种方法。 它涉及实现List
接口。 几乎每个方法的实现都是专门为了迎合子列表的想法。 正如规范所说,您不必考虑对基础列表进行结构更改的情况(例如,如果在创建子列表和在该子列表上调用 size() 之间,有人在顶部调用.clear()
-level 列表?这是否意味着子列表现在应该返回 0?您可以根据java.util.List
的规范自行定义会发生什么。
public List<T> subList(int fromIndex, int toIndex) {
if (fromIndex < 0) throw new IndexOutOfBoundsException("fromIndex is below 0");
if (toIndex > size()) throw new IndexOutOfBoundsException("toIndex is above 'size'");
if (toIndex < fromIndex) throw new IndexOutOfBoundsException("toIndex is before fromIndex");
return new List<T>() {
public void size() {
return toIndex - fromIndex;
}
public void get(int idx) {
return MyList.this.get(idx + fromIndex);
}
public boolean add(T elem) {
return MyList.this.add(toIndex++, elem);
}
// and so on.
};
}
看一下add
方法的 impl(它假设底层add
方法总是返回 true - 如果你的列表 impl 不返回 true,则不要递增 toIndex 除非返回 true):它可能有点复杂。 在这里,向 subList 添加一个项目意味着 subList 现在比原来大了一个。 就此而言,基础列表也是如此。 此外,对 subList 的添加到末尾操作并不一定意味着您要添加到基础列表的末尾,因此您将调用中间添加版本。 Outer.this.method()
是java-ese,用于调用外部class的方法,我们在这里需要它,因为内部class和外部class的方法非常相似,因此我们在调用时需要清楚 eg add(idx, elem)
- 是调用子列表的添加方法,还是底层(外部类的)添加方法? Outer.this.x
可以用来说明这一点(如果你不这样做,你会得到内部列表,因此如果你尝试它很可能会出现大量 StackOverflowErrors)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.