有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在循环链表和迭代器API中缺乏确定性

我试图使用List接口创建一个循环链表实现,并注意到了一个有趣的副作用

虽然CircularLinkedList满足列表契约,但它破坏了 其他当前实现的collection

问题在于,ListIterator接口提供了以下内容 hasNext()和hasPrevious()方法的约定:

public boolean hasNext()

Returns true if this list iterator has more elements when traversing the list in the forward direction. (In other words, returns true if next would return an element rather than throwing an exception.)

public boolean hasPrevious()

Returns true if this list iterator has more elements when traversing the list in the reverse direction. (In other words, returns true if previous would return an element rather than throwing an exception.)

现在在一个循环列表中,如果且仅当列表为空时,根据合同,每个列表都应返回false

当您尝试使用addAll()方法将带有适当列表迭代器的循环列表添加到另一个集合时,问题就会显现出来——该方法在添加每个元素时使用hasNext()来约束迭代。因此 循环永不终止

我目前正在考虑打破ListIterator的约定,如果您正在查看hasNext()方法,则使列表看起来像一个链表,或者创建一个迭代器的子类,其中hasNext被迭代器()方法重写以返回

两个问题:

  1. 有没有更好的方法在不破坏迭代器的情况下实现这一点 还是列表迭代器合同

  2. 还有人认为这是AbstractCollection类中的一个缺陷吗(继承行为就是从这个类中产生的)。请注意,有些集合确实以更稳健的方式执行添加,方法是调用要添加的集合的toArray()方法,然后添加数组的每个元素


共 (1) 个答案

  1. # 1 楼答案

    在我看来,这既不是集合API中的缺陷,也不是方法hasNexthasPrevious的契约的定义方式中的缺陷

    问题源于你对循环列表的思考方式:

    • 列表有固定大小的元素,因此迭代器应该能够以一种有开始和结束的方式对它们进行排序
    • 在列表中如何组织元素来回答hasNexthasPrevious并不重要。排序只定义返回哪个元素的时间

    如果您的迭代器返回相同的元素(根据列表中的绝对位置确定身份),那么您的迭代器实现是错误的

    您必须将如何对元素排序的想法与列表中包含的元素数量分离开来。列表中的元素数由size的结果定义。因此,如果只向前导航,hasNext应该回答true次。当从hasNext获得false作为答案后向后导航时,对于hasPrevious也是如此