Han*_*Sun 9 java oop interface list
在Java中,为了反转List中的元素,我需要使用:
Collections.reverse(list)
Run Code Online (Sandbox Code Playgroud)
我只是想知道为什么Java没有在List接口中实现反向方法,所以我可以这样做就地反向:
list.reverse()
Run Code Online (Sandbox Code Playgroud)
有没有人对此有任何想法?
Ste*_*n C 10
为什么
List.reverse()Java中没有方法?
因为有一种Collections.reverse(List)方法.
因为API设计者认为强制每个 List实现1实现一个99.9%的时间未使用的方法是一个坏主意2.这可以通过使方法"可选"来解决,但这也有缺点; 例如运行时异常.
因为对于某些类型的列表(例如流包装器/适配器),实现就地反向会有问题.它通过要求对其进行修改来更改列表的内存使用特性.
另请注意,通用实现(源代码)reverse()由交换元素的Collection用途提供set.它接近标准列表类型的最佳值.
@shmosel评论:
我假设OP问为什么它没有作为默认方法添加,就像List.sort()那样.
好问题.可能99.9%的论点适用.请记住,这只会帮助拥有使用Java 8或更高版本编译器等构建的代码库的人.
1 - 这包括代码库和第三方库中的实现.
2 - 86%的统计数据用于戏剧效果:-)
注意:这个问题是“为什么 Collections 类包含独立(静态)方法,而不是将它们添加到 List 接口?”的一个非常具体的案例。- 人们甚至可以将其视为重复项。除此之外,争论每个单独方法的决策背后的推理就像读茶叶一样,没有人能说出该方法的特定情况的设计决策的“原因” (reverse直到,也许乔什·布洛赫(Josh Bloch)在这里发布了答案)。有趣的是,这一点在Java Collections API Design FAQ中没有涉及到......
其他一些答案乍一看似乎很有说服力,但也提出了其他问题。特别是,其中一些根本没有给出设计决策的理由。即使有其他方法来模拟某个方法的行为,或者当“99.9% 的时间”都没有使用某个方法时,将其包含在接口中仍然有意义。
查看该List接口,您会发现您基本上可以基于另外两个方法来实现所有方法:
T get(int index)int size() (对于可变列表,您还需要set)。这些正是AbstractList. 因此,所有其他方法都是相当“方便”的方法,可以基于这两种方法规范地实现。在这方面,我认为Sam Estep 的答案包含一个重要的观点:人们可能会争论实施数十种其他方法。这样做肯定有充分的理由。看看实际的实现Collections#reverse(List):
public static void reverse(List<?> list) {
int size = list.size();
if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) {
for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--)
swap(list, i, j);
} else {
ListIterator fwd = list.listIterator();
ListIterator rev = list.listIterator(size);
for (int i=0, mid=list.size()>>1; i<mid; i++) {
Object tmp = fwd.next();
fwd.set(rev.previous());
rev.set(tmp);
}
}
}
Run Code Online (Sandbox Code Playgroud)
REVERSE_THRESHOLD这个和那里的东西是什么RandomAccess?说真的,如果我觉得有必要引入像 一样的标签界面RandomAccess,我会强烈质疑我的设计。每当你有像这样的方法
void doSomethingWith(Type x) {
if (x instanceof Special) doSomethingSpecial((Special)x);
else doSomethingNormal(x);
}
Run Code Online (Sandbox Code Playgroud)
那么这是一个强烈的信号,表明这实际上应该是一个多态方法,应该针对该Special类型相应地实现。
reverse因此,是的,将方法拉入接口中以允许多态实现是合理的。这同样适用于fill rotate、shuffle、swap、sort和其他。同样,我们可以引入一个静态方法,例如
Collections.containsAll(containing, others);
Run Code Online (Sandbox Code Playgroud)
这提供了现在使用该方法所做的事情Collection#containsAll。但总的来说:设计师选择了一套他们认为合适的特定方法。省略某些方法背后的原因之一可能是Joshua Bloch (Java Collections API 的核心设计者之一)关于“如何设计一个好的 API 及其重要性”的演讲的底线之一:
List有趣的是,在所有合理的多态实现(通过接口中的方法)的方法中,有一个实际上使用 Java 8 方法找到了进入接口的default方式:List#sort()。也许其他的,比如reverse,稍后会添加......