【问题标题】:Iterate over non-null portion of array in class implementing Iterable<Item>在实现 Iterable<Item> 的类中迭代数组的非空部分
【发布时间】:2020-01-04 09:58:20
【问题描述】:

我在其他语言方面经验丰富,但对 Java 很陌生。作为针对特定情况的优化,我正在尝试从数组中实现一个可迭代的容器类,因为我知道我的容器一次最多可容纳 4 个项目,并且这些项目每个都属于特定索引,而不是第一个in 获取可用的最低索引。

为了避免在迭代列表时检查 null,我只希望为迭代返回非 null 值...下面的“iterator()”覆盖是否有效?垃圾收集器有没有机会在我迭代它之前清除我返回的可迭代列表?或者有没有更好的方法来实现这一点?

class FixedArray<T> implements Iterable<T> {

    FixedArray() {}

    public void add(byte index, T item) {
        array[index] = item;
    }

    @Override
    public Iterator<T> iterator() {
        List<T> listWithoutNull = new ArrayList<>();
        for (Item item: array) {
            if (item != null) {
                listWithoutNull.add(item);
            }
        }
        return listWithoutNull.iterator();
    }

    private final T[] array = { null, null, null, null };
}

【问题讨论】:

  • 在这种情况下,你为什么需要List - 也许改用Set
  • "...据我所知,我的容器一次最多可容纳 4 个项目,并且这些项目每个都属于特定索引,而不是首先获得可用的最低索引。 " - 为什么不创建一个有四个属性的类呢?
  • 迭代器方法中的 Set 是否替换了 List listWithoutNull?又有什么优势呢?
  • @Turing85 好问题,因为为了四叉树的位置识别,扁平化的索引是用基本的二维位置编码的
  • @IronAttorney 你认为这比public class Square { private Point bottomLeft; private Point bottomRight; private Point upperLeft; private Poiint upperRight; } 更易读或更容易理解吗?

标签: java arrays iterator subclass implements


【解决方案1】:

下面的 'iterator()' 覆盖会起作用吗?

是的,为什么不呢?覆盖iterator() 非常好。然而,这不是一个有效的实现。我会这样写:

@Override
public Iterator<T> iterator() {
    return Arrays.stream(array).filter(Objects::nonNull).iterator();
}

这里不会创建中间集合,所以没有开销。

垃圾收集器有没有机会清理 我在迭代之前返回的可迭代列表?

不,当您持有对 Iterator 对象的强引用时,不允许垃圾收集器执行此操作(除非您的 Iterator 实现在内部使用了类似弱引用的东西,但这不是您的情况)。

【讨论】:

    猜你喜欢
    • 2021-09-14
    • 1970-01-01
    • 2019-03-24
    • 2020-06-03
    • 2021-08-13
    • 1970-01-01
    • 2019-06-25
    • 2016-03-30
    • 1970-01-01
    相关资源
    最近更新 更多