为什么要使用Deque而不是内置的Stack<>?
为什么要使用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已有的内容相比,泛型并不是创建集合层次结构的原因。
为什么要使用Deque而不是内置的Stack?
当使用内置的Stack<>时,它继承自Vector类,这意味着它对每个单独的操作进行同步。然而,通常情况下,只会有一个线程访问数据结构,所以在每个操作上进行同步是浪费CPU时间的。这样做会花费大量时间来获取和释放对象上的锁,而实际上添加或删除项目的时间非常少。
这个问题的出现主要是因为Stack<>类继承了Vector类,而Vector类在每个操作上都进行了同步。这样的设计在多线程环境中可能是有用的,但在单线程环境中会浪费CPU时间。因此,为了提高性能,我们需要一种替代方案。
解决方法是使用Deque(Double Ended Queue)类。Deque是一种可以在两端添加或删除元素的数据结构。它提供了与Stack类相似的功能,但在单线程环境中没有同步的开销。
下面是使用Deque的示例代码:
Dequedeque = 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<>是一个更好的选择。