为什么要使用Deque而不是内置的Stack<>?

9 浏览
0 Comments

为什么要使用Deque而不是内置的Stack<>?

Java Doc中提到,最好使用Deque来创建Stack,而不是使用传统的Stack类。不幸的是,它没有强调为什么要这样做。\nDeque也可以用作LIFO(后进先出)堆栈。应该优先使用这个接口,而不是传统的Stack类。当将Deque用作堆栈时,元素从Deque的开头推入和弹出。\n有人可以指出为什么要这样做吗?同样地,是否还有其他情况下我们应该避免使用内置的Collections对象?我是一位从C++转向Java的开发人员,因此任何这类微妙的指示都会有帮助。\n谢谢。

0
0 Comments

为什么要使用Deque而不是内置的Stack<>?

Java泛型是在集合的初始实现之后添加的;Stack是Java 1.0版本中的类 - 而不是在添加泛型时破坏现有代码,决定添加重复功能的类(但提供一致的API)。因此,您应该偏好使用Deque - 它提供了与其他Java集合一致的API。

那么,明确一下,您的意思是实现Deque接口而不是Stack<>?

我的措辞可能有些笨拙。集合是在Java 2中添加的,泛型是在Java 5中添加的,而Deque是在Java 6中添加的。但是Stack比所有这些都要早!

泛型与此原因无关,因为Stack支持泛型。原因更多地与Stack和Vector一样,由于其同步工作方式的固有缺陷有关。他们不能修复这个问题,因为显式依赖于同步逻辑的类将会出现问题。

泛型是后来添加的是正确的。与Java已有的内容相比,泛型并不是创建集合层次结构的原因。

0
0 Comments

为什么要使用Deque而不是内置的Stack?

当使用内置的Stack<>时,它继承自Vector类,这意味着它对每个单独的操作进行同步。然而,通常情况下,只会有一个线程访问数据结构,所以在每个操作上进行同步是浪费CPU时间的。这样做会花费大量时间来获取和释放对象上的锁,而实际上添加或删除项目的时间非常少。

这个问题的出现主要是因为Stack<>类继承了Vector类,而Vector类在每个操作上都进行了同步。这样的设计在多线程环境中可能是有用的,但在单线程环境中会浪费CPU时间。因此,为了提高性能,我们需要一种替代方案。

解决方法是使用Deque(Double Ended Queue)类。Deque是一种可以在两端添加或删除元素的数据结构。它提供了与Stack类相似的功能,但在单线程环境中没有同步的开销。

下面是使用Deque的示例代码:

Deque deque = new ArrayDeque<>(); // 创建一个Deque对象
deque.push(1); // 在头部添加元素
deque.push(2);
deque.push(3);
int top = deque.peek(); // 获取头部元素,但不删除
System.out.println("Top element: " + top);
int popped = deque.pop(); // 删除并返回头部元素
System.out.println("Popped element: " + popped);
boolean isEmpty = deque.isEmpty(); // 检查Deque是否为空
System.out.println("Is Deque empty? " + isEmpty);

通过使用Deque,我们可以避免不必要的同步开销,并提高性能。在单线程环境中,使用Deque而不是内置的Stack<>是一个更好的选择。

0