java优先级队列不存在';根据hashmap的频率,无法获得正确的顺序 Map Map=newhashmap(); for(int n:arr)map.put(n,map.getOrDefault(n,0)+1); PriorityQueue pq=newpriorityqueue((a,b)->map.get(a)-map.get(b)); 对于(内部编号:arr)pq,添加(n); 而(!pq.isEmpty()){ System.out.print(pq.poll()+); }

java优先级队列不存在';根据hashmap的频率,无法获得正确的顺序 Map Map=newhashmap(); for(int n:arr)map.put(n,map.getOrDefault(n,0)+1); PriorityQueue pq=newpriorityqueue((a,b)->map.get(a)-map.get(b)); 对于(内部编号:arr)pq,添加(n); 而(!pq.isEmpty()){ System.out.print(pq.poll()+); },java,hashmap,priority-queue,Java,Hashmap,Priority Queue,假设输入arr为[4,3,1,1,3,3,2,2] 在我们把他们都放到pq里,一个一个地投票之后。 正确的顺序应为频率顺序的4 1 2 3 3 但是输出顺序是4 1 2 1 3 3 3,这没有输出正确的顺序。顺序是正确的PriorityQueue不能保证系结是如何断开的,1和2是系结的: 如果多个元素以最小值绑定,则头部就是这些元素之一——绑定被任意断开 如果您想选择领带的订单,那么您的比较器应该这样做。最简单的方法是编写比较器。comparingit(i->map.get(i))。然后comp

假设输入arr为[4,3,1,1,3,3,2,2] 在我们把他们都放到pq里,一个一个地投票之后。 正确的顺序应为频率顺序的4 1 2 3 3


但是输出顺序是4 1 2 1 3 3 3,这没有输出正确的顺序。

顺序是正确的
PriorityQueue
不能保证系结是如何断开的,1和2是系结的:

如果多个元素以最小值绑定,则头部就是这些元素之一——绑定被任意断开


如果您想选择领带的订单,那么您的比较器应该这样做。最简单的方法是编写
比较器。comparingit(i->map.get(i))。然后comparingit(i->i)
以升序打破联系。

数组中
1
2
都出现两次,就优先级队列而言,它们是“相等的”,因为您只是告诉优先级队列仅比较它们的频率。因为它们是相等的,所以它们可以以任何顺序出现

所以要解决这个问题,您需要告诉优先级队列当元素相等时该做什么。尽管您可以尝试将此逻辑添加到lambda中,但通过调用
比较
然后比较
可以更轻松地完成此操作:

       Map<Integer, Integer> map = new HashMap<>();
        
        for (int n : arr) map.put(n, map.getOrDefault(n, 0) + 1);

        PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> map.get(a) - map.get(b));
        for (int n : arr) pq.add(n);
        
        while (!pq.isEmpty()) {
            System.out.print(pq.poll() + " ");
        }
PriorityQueue pq=新的PriorityQueue(
比较(map::get)
.Then比较(Function.identity())
);
这意味着“比较从地图上获得的值,然后比较数字本身”。这意味着它将在2之前排序1,即使1和2都出现了两次

PriorityQueue<Integer> pq = new PriorityQueue<>(
    Comparator.<Integer, Integer>comparing(map::get)
        .thenComparing(Function.identity())
);