如何创建根据列表的自然顺序排序的 PQ?

发布于 2024-10-03 22:49:38 字数 2378 浏览 3 评论 0原文

我的 SSCE:

public class ComparableItem implements Comparable<ComparableItem> {

    private final int itemNo;

    public ComparableItem(final int itemNo) {
        this.itemNo = itemNo;
    }

    @Override
    public int compareTo(ComparableItem o) {
        if (this.itemNo < o.itemNo) {
            return -1;
        } else if (this.itemNo > o.itemNo) {
            return 1;
        }
        return 0;
    }
}

这是一个演示该问题的测试。创建 PQ 后代码就会中断。上面几行是为了证明由compareTo(..)定义的自然排序按预期工作。 打印 PQ 的元素:14,9,15,5,6,3 与预期的 15,14,9,6,5,3。有人可以向我解释为什么会出现这种情况吗?

import org.junit.Test;
import java.util.*;
import static org.junit.Assert.*;

public class CompTest{

@Test
public void aTest() {

    Integer[] order = {9, 3, 14, 15, 6, 5};
    List<ComparableItem> items = new ArrayList<ComparableItem>(order.length);
    for (int i = 0; i < order.length; i++) {
        items.add(new ComparableItem(order[i]));
    }

    List<ComparableItem> greater = new ArrayList<ComparableItem>();
    testCompare(items, items.get(3), greater, true);
    testCompare(items, items.get(2), greater, true);
    testCompare(items, items.get(0), greater, true);
    testCompare(items, items.get(4), greater, true);
    testCompare(items, items.get(5), greater, true);
    testCompare(items, items.get(1), greater, true);

    final PriorityQueue<ComparableItem> itemsQueue = new PriorityQueue<ComparableItem>(items);
    greater = new ArrayList<ComparableItem>();
    for (ComparableItem c : itemsQueue) {
        testCompare(itemsQueue, c, greater, false);
    }
}

public static void testCompare(final Collection<ComparableItem> items, final ComparableItem item, final List<ComparableItem> greater, boolean bigger) {
    final int exp = (bigger)? -1:1;
    for (ComparableItem c : items) {
        final int expected = c.equals(item) ? 0 : greater.contains(c) ? exp : exp*-1;
        assertEquals(expected, item.compareTo(c));
        assertEquals(expected * -1, c.compareTo(item));
    }
    greater.add(item);
}

}

new PriorityQueue<ComparableItem>(items);

创建一个包含以下内容的 PriorityQueue 指定集合中的元素。 如果指定的集合是 SortedSet 的实例或者是另一个 PriorityQueue,这个优先级队列 将按照相同的顺序进行排序 订购。否则,此优先级 队列将根据 其元素的自然顺序。

My SSCE:

public class ComparableItem implements Comparable<ComparableItem> {

    private final int itemNo;

    public ComparableItem(final int itemNo) {
        this.itemNo = itemNo;
    }

    @Override
    public int compareTo(ComparableItem o) {
        if (this.itemNo < o.itemNo) {
            return -1;
        } else if (this.itemNo > o.itemNo) {
            return 1;
        }
        return 0;
    }
}

Here's a test that demonstrates the problem. The code breaks after the PQ is created. The lines above are to prove that the natural ordering defined by compareTo(..) works as expected.
Printing the elements of the PQ they are: 14,9,15,5,6,3 versus the expected 15,14,9,6,5,3. Could someone explain to me why this is the case?

import org.junit.Test;
import java.util.*;
import static org.junit.Assert.*;

public class CompTest{

@Test
public void aTest() {

    Integer[] order = {9, 3, 14, 15, 6, 5};
    List<ComparableItem> items = new ArrayList<ComparableItem>(order.length);
    for (int i = 0; i < order.length; i++) {
        items.add(new ComparableItem(order[i]));
    }

    List<ComparableItem> greater = new ArrayList<ComparableItem>();
    testCompare(items, items.get(3), greater, true);
    testCompare(items, items.get(2), greater, true);
    testCompare(items, items.get(0), greater, true);
    testCompare(items, items.get(4), greater, true);
    testCompare(items, items.get(5), greater, true);
    testCompare(items, items.get(1), greater, true);

    final PriorityQueue<ComparableItem> itemsQueue = new PriorityQueue<ComparableItem>(items);
    greater = new ArrayList<ComparableItem>();
    for (ComparableItem c : itemsQueue) {
        testCompare(itemsQueue, c, greater, false);
    }
}

public static void testCompare(final Collection<ComparableItem> items, final ComparableItem item, final List<ComparableItem> greater, boolean bigger) {
    final int exp = (bigger)? -1:1;
    for (ComparableItem c : items) {
        final int expected = c.equals(item) ? 0 : greater.contains(c) ? exp : exp*-1;
        assertEquals(expected, item.compareTo(c));
        assertEquals(expected * -1, c.compareTo(item));
    }
    greater.add(item);
}

}

new PriorityQueue<ComparableItem>(items);

Creates a PriorityQueue containing the
elements in the specified collection.
If the specified collection is an
instance of a SortedSet or is another
PriorityQueue, this priority queue
will be ordered according to the same
ordering. Otherwise, this priority
queue will be ordered according to the
natural ordering of its elements.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

少女情怀诗 2024-10-10 22:49:38

我认为问题不在于队列,而在于您测试它的方式。特别是 < 的 javadoc code>PriorityQueue.iterator() 状态:

返回对此队列中元素的迭代器。迭代器不按任何特定顺序返回元素。

javadoc 类是这样说的:

方法 iterator() 中提供的迭代器不保证以任何特定顺序遍历优先级队列的元素。如果需要有序遍历,请考虑使用 Arrays.sort(pq.toArray())。

I think that the problem is not in the queue, but in the way that you are testing it. In particular, the javadoc for PriorityQueue.iterator() states:

Returns an iterator over the elements in this queue. The iterator does not return the elements in any particular order.

And the class javadoc says this:

The Iterator provided in method iterator() is not guaranteed to traverse the elements of the priority queue in any particular order. If you need ordered traversal, consider using Arrays.sort(pq.toArray()).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文