Java中实现的栈or队列两种方式对比
我们知道,在Java中,可以直接使用Stack
来实现栈,这是一种看到名字就会自动想到栈的类,但是现代Java编程中却不推荐使用Stack
来实现栈,这是为什么?首先来看一下Java中的Collection接口继承图:
Stack
1.线程安全,但是带来的开销大,效率低
Stack
是直接继承自Vector
类,对于Vector
类,该类是数组的古老实现,它是线程安全的,但是同样的,带来的效率会比较低下,所以在现代Java中不适合被使用。
2.使用数组实现,在频繁增减时效率低,随机查找带来的优势不明显
既然是基于Vector
实现,那么Stack
的底层数据结构就是数组,对于数组,它具有查找快,删除数据慢的特点。对于栈栈这种只在一端进行数据操作的结构,链表是最适合的。
3.灵活性不好
对于Stack
,它只能用来实现栈的功能,而我们对于一些集合、散列表,都会采用面向接口编程(至于为什么普遍采用面向接口编程,这个我会在下面解释),而Stack的实现的接口是List
,这就和栈的理念不符合,从接口层面来说,Stack
不具备灵活性。
LinkedList
LinkedList
是基于双向链表实现的,具有效率较快的对一端的元素进行增删的功能,而且它实现的接口也有Queue
和Deque
,分别代表队列和双端队列,我们可以使用Queue<Integer> queue = new LinkedList<>();
方便的创建一个队列,也可以将Queue
改为Deque
来实现双端队列。
即灵活性好
因为栈本质上就是在一端进行增删,那么这个需求完全可以由Deque
这个双端队列来实现,Deque
实现了两端的增、删、查的api(addLast. addFirst. removeLast. removeFirst. peekLast. peekFirst
)。
public static void main(String[] args) { Deque<Integer> stack = new LinkedList<>(); stack.addLast(1); stack.addLast(2); stack.removeLast(); System.out.println(stack); }
上面是使用LinkedList
构造的一个栈。同样的,可以用这些api来构建队列、双端队列等等。
而且LinkedList本身是线程不安全的,可以省去一些线程同步的开销,当然你也可以把线程同步的这个步骤放在LinkedList之外来做。
为什么建议采用面向接口编程?
上面我说的,为什么大家使用集合类的时候,都喜欢初始化一个接口的引用呢?例如Map<String,Integer> map = new HashMap<>(); List<Integer> list = new ArrayList<>()
;
而不是直接使用ArrayList<Integre> list = new ArrayList<>()
?
其实对于功能上来说,这两种写法都是可以的,没有任何问题,并且使用ArrayList<Integre> list = new ArrayList<>()
来初始化一个list反而可以使用的方法比使用接口来初始化的要多(它可以使用一些ArrayList
特有的方法),比如public void trimToSize()
,把一个ArrayList
的实际大小缩小为它所持有的对象的数量(节省空间)。
那么究竟为什么提倡采用接口命名呢?
我们考虑一个场景,对于一个ArrayList<Integre> list = new ArrayList<>()
,list的引用在初始化后,它就只能指向ArrayList
及它的子类,假如你想把list指向另一个也可以提供列表功能的类的对象时,这个时候你就会发现,你做不到。
假如我是用接口命名List<Integer> list = new ArrayList<>();
,我的list时属于接口的,它可以指向任何实现了这个List接口的类的对象,灵活性大大增加了,并且接口的规范性,可以让我们忽略每个实现类内部的一些细节,当我只关注我想使用的集合的类型时(比如列表、哈希表等),我完全就可以使用接口命名,而这种场景也是我们在编程中遇到最多的,一言以蔽之:接口可以增加引用指向的灵活性,同时可以帮我们屏蔽一些实现类内部的细节,从而让我们更关注的使用集合的功能。
有的朋友就会问了,实现List
的类,Java里也就那么几个,而且Vector
现在也不用了,那为什么还要用接口呢?那假如我们的项目里用的List接口来实现列表,项目上线并运行了,但是过了一段时间发现这个List无法满足我们的业务需求,这个时候我们就可以使用重写一个实现List
接口的类,直接改变引用即可,即我们可能会自己创建一些实现List
接口的类,不必局限于Java中的几个实现了List
接口的类。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY