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

时间:2017-04-24 05:25:40

标签: java list data-structures circular-list

我正在尝试使用List界面创建循环链表实现,并注意到一个有趣的副作用。

虽然CircularLinkedList满足List合约,但它打破了 其他当前实施的collection类!

问题是这个 - ListIterator接口提供以下内容 hasNext()和hasPrevious()方法的合同:

  

public boolean hasNext()

     

如果此列表迭代器具有更多元素,则返回true      在前进方向遍历列表。 (换句话说,回报      如果next将返回一个元素而不是抛出异常,则为true。)

     

public boolean hasPrevious()

     

如果此列表迭代器具有更多元素,则返回true      以相反的方向遍历列表。 (换句话说,回报      如果previous返回一个元素而不是抛出异常,则为true。)

现在在循环列表中,当且仅当List为空时,合同中的每一个都应该返回 false

当您尝试使用 addAll()方法将具有相应列表迭代器的循环列表添加到另一个Collection时,问题就会出现 - 该方法使用 hasNext()在添加每个元素时约束迭代。因此 循环永远不会终止!

我目前正在考虑违反ListIterator的合同,如果您正在查看hasNext()方法,则使列表看起来像链接列表,或者创建迭代器的子类,并重写hasNext以返回iterator()方法。

两个问题:

  1. 在不破坏迭代器的情况下,有更好的方法吗? 或ListIterator合同?

  2. 是否有其他人认为这是AbstractCollection类(继承行为来自哪里)的缺陷。请注意,某些集合通过调用要添加的集合的toArray()方法并添加数组的每个元素,以更强大的方式执行添加。

1 个答案:

答案 0 :(得分:1)

在我看来,这既不是 Collections API 中的缺陷,也不是定义hasNexthasPrevious方法的合同的方式。

问题在于您对循环列表的思考方式:

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

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

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