1

我想在java中有一个排序的集合,我可以迭代它。从我读到的 PriorityQueue 是我需要的东西,但是我无法弄清楚如何以排序方式检索元素......

我做了这个测试示例:

主.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);
    }
}
}

类1.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);
}

}

类2.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);
}

}

这将返回:

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]

我需要做什么才能以排序方式迭代此集合?

4

3 回答 3

2

元素仅在出队时按排序顺序返回给您。当您迭代队列而不出队时,顺序是优先级队列实现的内部。

用下面的代码替换循环会以正确的顺序为您提供数据:

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

由于保证出队以正确的顺序发生,因此会产生以下输出:

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]

这是ideone的演示。

于 2013-05-24T10:25:42.117 回答
1

APriorityQueue在遍历迭代器时不保证其元素的任何顺序。它只保证第一个元素是“最小的”元素。由于它是一个队列,它应该用作您从中轮询的临时集合。

相反,正如@BenjaminGruenbaum 评论的那样,您可以使用 aTreeSet来保证迭代器将返回元素顺序。

另一种选择是在需要对其进行排序时Collections.sort()对任何List内容进行排序。

PS 看起来你可以对 Class1 和 Class2 使用一些继承,因为它可以简化你的很多代码——你只需要这些toString()方法,因为它们是唯一不同的方法。

于 2013-05-24T10:32:09.873 回答
0

优先级队列并不是真正的排序容器。它更像是一个按排序顺序弹出元素的堆栈或队列。您需要使用一个实现SortedSet.

于 2013-05-24T10:22:58.000 回答