简体   繁体   中英

Why does PriorityQueue peek() return the wrong maximum value?

I'm using PriorityQueue to get the maximum integer, but I could not figure out why the first method returns the correct maximum integer but the second method doesn't. Second method tries to update the target item's big number; but when I tried peek() method after update method is called, it still prints out the older maximum number instead of the new one after update.

Here is my code:

void add(String name, int number) {
    Item item = new Item(name, number, allItems.size());
    allItems.add(item);
    hashMap.put(name, item);
}

void update(String name, int number) {
    Item item = hashMap.get(name);

    // EDITED: 
    allItems.remove(item);

    item.setNumber(item.getNumber() + number);
    allItems.add(item);
    hashMap.put(name, item);    
}

EDITED: It seems like it only works if I removed the target item from allItems(Refer to EDITED in update method). Why is this so?

class Item implements Comparable<Item>{
        private String name;
        private int number;
        private int arrived;

        public Item(String name, int number, int arrived) {
            this.name = name;
            this.number = number;
            this.arrived = arrived;
        }

        @Override
        public int compareTo(Item o) {

            int x = this.getNumber();
            int y = o.getNumber();

            if (y > x) return 1;
            if (y < x) return -1;


            if (this.arrived > o.arrived) return 1;
            if (this.arrived < o.arrived) return -1;

            return 0;
        }

    }

Most likely, your implementation of Comparable is incorrect.

Your Comparable implementation is what PriorityQueue uses to know how to sort the items based on the value of a field. You must implement Comparable in DECREASING order. You want it to return -1 if the other item is bigger, and return 1 if this item is bigger; in your code you are doing the opposite. In other words, make sure your Item class definition looks like this:

public class Item implements Comparable<Item> {
  private int number;
  private int arrived;

  // the rest of your code

  public int compareTo(Item other) {
    int numberCompare = Integer.compare(other.number, this.number);
    if (numberCompare == 0) {
      return Integer.compare(other.arrived, this.arrived);
    } else {
      return numberCompare;
    }
  }
}

You can also use PriorityQueue(int initialCapacity, Comparator comparator) if you don't want to change the class definition of Item .

According to the Javadoc for PriorityQueue :

An unbounded priority queue based on a priority heap. The elements of the priority queue are ordered according to their natural ordering , or by a Comparator provided at queue construction time, depending on which constructor is used. A priority queue does not permit null elements. A priority queue relying on natural ordering also does not permit insertion of non-comparable objects (doing so may result in ClassCastException ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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