繁体   English   中英

如何在自定义中实现subList() ArrayList

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM