Priority Queue转ArrayList异常:元素未全部复制问题排查
问题原因分析及解决方案
嘿,我来帮你揪出这个问题的根源~
你遇到的核心问题出在for循环的条件判断上:每次调用queue.poll()方法时,都会从PriorityQueue中移除并返回队首元素,这会导致队列的size()在循环过程中不断减小。举个具体的例子:
- 当队列初始有3个元素时,第一次循环
i=0,满足i<3,执行poll后队列size变成2,i自增到1; - 第二次循环
i=1,满足i<2,执行poll后队列size变成1,i自增到2; - 第三次循环
i=2,此时i<1不成立,循环直接结束,最终只复制了2个元素,和你描述的情况完全吻合。
几种正确的实现方式
方式一:用while循环判断队列是否为空(最推荐)
这种方式逻辑最直观,只要队列里还有元素,就持续取出并添加到列表中:
PriorityQueue<T> queue = new PriorityQueue<>(); List<T> list = new ArrayList<>(); while (!queue.isEmpty()) { list.add(0, queue.poll()); }
方式二:先记录初始队列大小
提前把队列的初始size存下来,避免循环中size变化影响循环次数:
PriorityQueue<T> queue = new PriorityQueue<>(); List<T> list = new ArrayList<>(); int initialSize = queue.size(); for (int i = 0; i < initialSize; i++) { list.add(0, queue.poll()); }
方式三:不修改原队列的复制(注意顺序问题)
如果你不想清空原队列,只是想复制元素,可以直接用ArrayList的构造方法或addAll方法,但要注意:PriorityQueue的迭代器不保证按优先级顺序遍历元素,所以这种方式得到的列表元素顺序可能和poll出来的顺序不一致:
// 直接用构造方法 PriorityQueue<T> queue = new PriorityQueue<>(); List<T> list = new ArrayList<>(queue); // 或者用addAll方法 List<T> list = new ArrayList<>(); list.addAll(queue);
如果需要严格按照PriorityQueue的优先级顺序来复制,还是建议用前两种方式哦~
内容的提问来源于stack exchange,提问作者Chip
相关产品推荐
相关产品推荐

