简体   繁体   English

PriorityQueue检索排序的元素

[英]PriorityQueue retrieve elements sorted

I'd like to have a sorted collection in java that I can iterate over it. 我想在Java中有一个可以对它进行迭代的排序集合。 From what I read a PriorityQueue is the thing that I need but hen I can't figure out how to retrieve the elements ins a sorted manner... 从我读到的内容中,我需要一个PriorityQueue,但是由于我不知道如何以一种排序的方式来检索元素,所以……

I did this test example: 我做了这个测试示例:

Main.java Main.java

import java.util.PriorityQueue;
public class Main {

public static void main(String[] args) {
    PriorityQueue<Object> queue=new PriorityQueue<Object>();
    Object o1=new Class1("o1");
    Object o2=new Class2("o2");
    Object o3=new Class1("o3");
    Object o4=new Class1("o4");
    Object o5=new Class2("o5");
    Object o6=new Class2("o6");
    Object o7=new Class1("o7");
    Object o8=new Class2("o8");
    Object o9=new Class1("o9");
    Object o0=new Class1("o0");
    queue.add(o7);
    queue.add(o4);
    queue.add(o3);
    queue.add(o8);
    queue.add(o5);
    queue.add(o1);
    queue.add(o2);
    queue.add(o9);
    queue.add(o0);
    queue.add(o6);

    for (Object object : queue) {
            System.out.println(object);
    }
}
}

Class1.java: Class1.java:

public class Class1 implements Comparable<Object>{
String name;

public Class1(String name) {
    super();
    this.name = name;
}

@Override
public String toString() {
    return "Class1 [name=" + name + "]";
}

@Override
public int compareTo(Object o) {
    return (o instanceof Class1)?compareTo((Class1)o):compareTo((Class2)o);
}

public int compareTo(Class1 o){
    return name.compareTo(o.name);
}

public int compareTo(Class2 o){
    return name.compareTo(o.name2);
}

}

Class2.java: Class2.java:

public class Class2 implements Comparable<Object>{
String name2;

public Class2(String name) {
    super();
    this.name2 = name;
}

@Override
public String toString() {
    return "Class2 [name=" + name2 + "]";
}

@Override
public int compareTo(Object o) {
    return (o instanceof Class1)?compareTo((Class1)o):compareTo((Class2)o);
}

public int compareTo(Class1 o){
    return name2.compareTo(o.name);
}

public int compareTo(Class2 o){
    return name2.compareTo(o.name2);
}

}

This returns: 返回:

Class1 [name=o0]
Class1 [name=o1]
Class2 [name=o2]
Class2 [name=o5]
Class2 [name=o6]
Class1 [name=o4]
Class1 [name=o3]
Class1 [name=o9]
Class2 [name=o8]
Class1 [name=o7]

What do I need to do to iterate in a sorted fashion over this collection? 我需要做些什么来以某种方式遍历此集合?

The elements are returned to you in the sorted order only on dequeueing them. 元素仅在出队时才以排序顺序返回给您。 When you iterate the queue without dequeueing, the order is internal to the implementation of the priority queue. 当您在不使队列出队的情况下进行迭代时,该顺序是优先级队列的内部执行。

Replacing the loop with the code below gives you the data in the correct order: 使用以下代码替换循环,可以按正确的顺序为您提供数据:

Object last;
while ((last = queue.poll()) != null) {
        System.out.println(last);
}

Since dequeueing is guaranteed to happen in the correct order, this produces the following output: 由于保证出队以正确的顺序发生,因此将产生以下输出:

Class1 [name=o0]
Class1 [name=o1]
Class2 [name=o2]
Class1 [name=o3]
Class1 [name=o4]
Class2 [name=o5]
Class2 [name=o6]
Class1 [name=o7]
Class2 [name=o8]
Class1 [name=o9]

Here is a demo on ideone. 这是有关ideone的演示。

A PriorityQueue does not guarantee any ordering of it's elements when traversing through the iterator. 在遍历迭代器时, PriorityQueue不保证其元素的任何顺序。 It only guarantees that the first element is the "smallest" one. 它仅保证第一个元素是“最小”的元素。 As it is a Queue, it is supposed to be used as a temporary collection that you poll from. 由于它是一个队列,因此应该用作从中轮询的临时集合。

Instead, as @BenjaminGruenbaum commented you can use a TreeSet which guarantees that the iterator will return the elements order. 相反,正如@BenjaminGruenbaum所说,您可以使用TreeSet来确保迭代器将返回元素顺序。

Another option is to use Collections.sort() to sort any List when you need it to be sorted. 另一种选择是在需要对List进行排序时,使用Collections.sort()对任何List进行排序。

PS It looks like you could use some inheritance with Class1 and Class2 as it could simplify a lot of your code - you would only need the toString() methods as they're the only ones that are different. PS看来您可以对Class1和Class2使用某些继承,因为它可以简化很多代码-您只需要toString()方法,因为它们是唯一的不同。

A priority queue isn't really a sorted container; 优先级队列并不是真正的排序容器。 it's more like a stack or queue that pops off elements in sorted order. 它更像是按顺序弹出元素的堆栈或队列。 You'll want to use a container that implements SortedSet . 您将要使用实现SortedSet的容器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM