如何根据Element属性从PriorityQueue中删除元素?

med*_*070 9 java search priority-queue

我试着Maximum Waiting Time进入我的内心PQueue.这 Maximum Waiting TimePQueue自动检查我是否有任何links等待Maximum Waiting Time删除它.我对我的代码进行了这项更改,但它在删除链接后正好停止了.我想PQueue根据等待时间条件删除我的所有元素.你能告诉我这里缺少什么吗?

这是我的班级:

public class MyClass {

    public static PriorityQueue <LinkNodeLight> PQueue = new PriorityQueue <> (); 


    private static Set<String> DuplicationLinksHub = new LinkedHashSet <> ();         

    private static Integer IntraLinkCount = new Integer (0);                 
    private static Integer InterLinkCount = new Integer (0);                 
    private static Integer DuplicationLinksCount = new Integer (0);     
    private static Integer MaxWaitTime = new Integer (60000); // 1 M= 60000 MS


    @SuppressWarnings("null")
    LinkNode deque(){

        LinkNode link = null;
        synchronized (PQueue) {

            link = (LinkNode) PQueue.poll();
            if (link != null) {
                link.setDequeTime(new DateTime());
                if (link.isInterLinks())
                    synchronized (InterLinkCount) {
                        InterLinkCount--;
                        }
                else
                    synchronized (IntraLinkCount) {
                        IntraLinkCount--;
                        }
            }

            synchronized (PQueue) {
                if (link.waitingInQueue()>MaxWaitTime) {

                    link = (LinkNode) PQueue.remove();
                                    System.out.println("*********************************");
                                    System.out.println("This Link is Deopped: " + link);
                                    System.out.println("%%% MaX Waiting Time:" + (MaxWaitTime/60000)+"Min");

                                    System.out.println("*********************************");
                  }
            }
            return link;


        }
Run Code Online (Sandbox Code Playgroud)

Tom*_*mas 3

你的问题有点不透明,但如果我理解正确的话,你想检查一下PriorityQueue是否有等待时间超过特定时间的项目。

synchronized正如已经提到的,您对IntraLinkCountand的用法InterLinkCount有点奇怪。有一个相当未知的替代方案,原子整数类AtomicInteger(在包中java.util.concurrent.atomic

private static AtomicInteger IntraLinkCount = Integer.valueOf(0);
Run Code Online (Sandbox Code Playgroud)

这将按您的意愿工作。

第二个问题是你使用的poll()方法。这将从队列中删除顶部的项目。也许您想peek()改为使用,然后仅remove()在返回的链接对象满足时才使用link.waitingInQueue() > MaxWaitTime

顺便说一句,您的队列将根据项目的“自然顺序”返回项目。这意味着compareTo使用该方法,并且将首先从队列中返回“最小”。我想您可能想要实现一个将最长等待compareTo链接放在第一位的自定义?

您也可以使用自定义对象来创建您的PriorityQueueComparator对象。

像这样的东西:

public class MyClass {
    public static PriorityQueue<LinkNodeLight> PQueue = new PriorityQueue<>();

    private static AtomicInteger IntraLinkCount = new AtomicInteger(0);
    private static AtomicInteger InterLinkCount = new AtomicInteger(0);

    private static Integer MaxWaitTime = Integer.valueOf(60_000); // 1 M= 60000 MS

    LinkNode deque() {
        LinkNode link = null;

        synchronized (PQueue) {
            link = PQueue.peek();

            if (link != null) {
                link.setDequeTime(LocalDateTime.now());

                if (link.isInterLinks())
                    InterLinkCount.decrementAndGet();
                else
                    IntraLinkCount.decrementAndGet();

                if (link.waitingInQueue() > MaxWaitTime) {
                    link = PQueue.remove();

                    System.out.println("*********************************");
                    System.out.println("This Link is Deopped: " + link);
                    System.out.println("%%% MaX Waiting Time:" + MaxWaitTime / 60000 + "Min");
                    System.out.println("*********************************");

                    return link;
                } else
                    return null;
            }
        }

        return link; // Not sure what you want to return here
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您足够幸运能够使用 Java 8,那么像这样的一些魔法可能会很有用:

synchronized (PQueue) {
    link = PQueue.stream().filter(node -> node.waitingInQueue() > MaxWaitTime).findFirst().orElse(null);

    if (link != null)
        PQueue.remove(link);
}
Run Code Online (Sandbox Code Playgroud)