2011-05-19 348 views
3
  • 假设列表b是一个LinkedList。
  • 假设List a也是一个LinkedList。

问:将LinkedHashSet转换为列表

  • 如何追加,这些名单在不断的时间?

这是可能的,因为LinkedList大概是一个双向链表(否则它不能实现Deque接口)。追加双向链表是一个0(1)操作。

addAll方法不会在恒定时间内运行。

问:

  • 如何变换LinkedHashSet成在固定时间列表?

这也可能是因为LinkedHashSet“维护通过其所有条目运行的双向链接列表”。

回答

5

您的假设是基于没有封装 - 即LinkedHashSet愿意将其内部LinkedList暴露给外部世界,当我怀疑它不是。

同样加入两个链接列表 - 我不知道每个节点是否知道它在哪个列表中,但这肯定是一种可能性,它会减少你的常量附加。即使他们不这样做,只要您将一个列表的头部附加到另一个列表的尾部,最终会出现问题 - 您有两个列表都指向相同的数据,这会导致一些奇怪的后果。

换句话说,从计算机科学的角度来看,这两种操作都是可行的,并且您可以构建自己的实现来支持它们,但这并不意味着Java API会以启用它的方式公开其内部那些操作。

+0

Java是否已经有追加LinkedList的方法?这些方法当然应该使用LinkedList而不是List,因为它们根本无法使用ArrayList。将LinkedHashSet转换为LinkedList也是如此。实际上,这是我的问题。 – Klems 2011-05-19 16:24:36

+0

@Klems:不,我不相信它 - 因为你有两个共享节点的LinkedList对象。同样,如果调用者修改返回的列表,您将如何建议从LinkedHashSet创建LinkedList而不引入可能的损坏? (我想可能会返回一个不可变的视图。) – 2011-05-19 16:36:46

+0

哦,我现在看到了问题。那么,正如你所说,它可能会返回一个只读列表。这有点像返回一个迭代器。但是,要附加2列表,该方法可以清除2个初始列表并返回结果列表。但我明白你的观点。 – Klems 2011-05-19 16:45:19

5

你需要实现你自己的类。 LinkedList类不公开其内部节点结构,因此您不能将其最后一个节点指向另一个LinkedList的第一个节点。

答案与LinkedHashSet类似:虽然它确实保留了这个双向链表,但您无法访问它。

+0

由于LinkedHashSet实现了抽象集合接口,因此您可以访问该列表。请参阅@Michael McGrady答案 – 2017-10-08 08:39:12

1

你不能访问它,但我怀疑集合的确如此,所以你不应该放弃希望这是对你的问题可行和快速的解决方案。

我看得更远,你是对的。如果你有Set<Whatever> whatever = SOME CONSTRUCTOR那么你可以编码List<Whatever> list = new LinkedList(whatever);,因为LinkedList有一个集合构造函数,而集合有一个集合接口。