Java的集合接口和类层次结构是否做得不好?
我知道在Java中,^{
在计算机科学教学大纲中,我从未被教导队列可以是一个列表,或者更准确地说,队列可以像一个列表一样工作。也就是说,列表可以做一些事情,但是队列不能。但是列表可以像队列一样工作。例如,List
接口有the following methods:
add(E e)
add(int index, E element)
但是Queue
{a3}
add(E e)
所以显然Queue
不允许在特定索引处插入,这在List
中是允许的。其他操作的情况也是如此,比如Queue.remove()
对List.remove(int index)
,List.get(int index)
对Queue.peek()
。
换句话说,list是一种更通用的数据结构,可以模拟Queue
现在,能够模仿与拥有契约子集是不同的。也就是说,Queue
不允许对List
进行某些操作(索引),并且只允许以特定方式进行某些操作(仅在尾部插入,仅从头部移除)。所以Queue
并不是真的对List
的合同进行“添加”。这正是为什么Queue
在Java集合框架中不扩展List
,而是扩展Collection
接口的原因。我认为,这也是为什么任何类都不能同时实现这两个方面,因为Queue
的契约与List
的契约冲突(这就是为什么它们分别从Collection
接口分叉)。然而,LinkedList
实现了这两个接口
我还遇到了this答案:
The
LinkedList
implementation happens to satisfy theDeque
contract, so why not make it implement the interface?
我仍然不明白我们怎么能说“LinkedList
实现恰好满足了Deque
契约”。队列的概念不允许在任意索引处插入。因此,Queue
接口没有这样的方法
然而,我们只能通过接口执行合同,不能禁止某些方法的实现。作为list(名称中有“list”),我觉得在peek()
、pop()
和add(int index, E element)
中有队列方法是不正确的
我认为,相反,我们应该有单独的类LinkedQueue
,它可以有队列的链接实现,类似于LinkedBlockingQueue
,它包含BlockingQueue
的链接实现
还要注意LinkedList
是从列表和队列家族继承的唯一类,也就是说,没有其他类同时实现List
和Queue
(AFAIK)。这是否表明LinkedList
做得不好
我是不是完全错了,想得不必要
# 1 楼答案
LinkedList
是一个类,实现了List
和Deque
接口。这些接口中的每一个都定义了一个包含操作的契约,并且在这些契约中指定了这些操作必须执行的操作。但是,没有明确说明这些操作应该如何工作LinkedList
是一个类,实现了List
和Deque
接口。因此,尽管后缀List
是LinkedList
类名称的一部分,但LinkedList
实际上既是List
又是Deque
,因为它实现了List
和Deque
接口中定义的所有操作所以}。这并不意味着
LinkedList
是一个aList
,它也是一个{List
应该是Deque
,或者Deque
应该是List
例如,查看以下界面:
上面的每个接口都有一个操作,并定义了一个契约。
drinkBlood
操作定义了BloodDrinker
必须做什么,但没有定义如何做。这同样适用于FlyingInsect
:它的flyAround
操作定义了它必须做什么,而不是如何做现在考虑^ {CD25>}类:
现在,这意味着一个
Mosquito
既是一个FlyingInsect
又是一个BloodDrinker
,但是为什么一个嗜血者必然是一个飞虫,或者一个飞虫必然是一个嗜血者呢?例如,吸血鬼是吸血鬼,但不是飞虫,而蝴蝶是飞虫,但不是吸血鬼现在,关于你关于} 没有明确提到实现者永远无法在任何给定的索引中添加/删除/检查元素。它只是说
Queue
不允许某些List
的操作(索引),并且只允许以FIFO方式在其末端添加/删除的论点。。。我认为这一基本原理是不正确的,至少在Java集合框架的上下文中是这样The contract of ^{Deque
是:它还说:
(我的)
几段之后,它明确表示:
(再次强调我的观点)
这里的关键部分是不提供支持。它从不禁止实现者通过索引访问元素。只是通过
Deque
接口不支持索引访问想想我上面的例子:为什么a
BloodDrinker
会禁止其实现者喝血液以外的东西,即水?或者为什么aFlyingInsect
会禁止其实现者以不同于飞行的方式移动,即步行归根结底,一个实现可以按照自己的意愿遵守任意多个契约,只要这些契约彼此不矛盾。正如用Java编写的一样(我必须承认,这是一个非常谨慎而微妙的措辞),
Deque
的契约与List
的契约并不矛盾,因此可以完美地存在一个实现两个接口的类,而这个类恰好是LinkedList