Skip to content
Advertisement

The program cannot do compareTo function after the object’s update information

I am trying to change the position of the product in the print menu after updating some information of the product. Specifically, arrange “Quantity” in descending order. If the products have same quantity, the list will be sorted with the ascending “UnitPrice” field.

Initially, if i add one more product, compareTo() function works fine, but after i use product update function, the compareTo() function doesn’t work. I use TreeSet for this project. Can anyone explain this case to me? Thank you very much.

This is my compareTo() function

    @Override
public int compareTo(Product o) {
    if (this.getQuantity() < o.getQuantity()) {
        return 1;
    }
    if (this.getQuantity() == o.getQuantity()) {
        return this.unitPrice-o.unitPrice;
    }
    return -1;
}

This is my update function

    public void updateInfo() {
    Scanner sc = new Scanner(System.in);
    String id, productName, quantity, unitPrice, numberForAvail;
    while (true) {
        try {
            System.out.print("Input products's id: ");
            id = sc.nextLine().toUpperCase();
            if (id.isEmpty()) {
                this.id = this.id;
            } else {
                if (!id.matches(letter_regEx) || id.length() < 5) {
                    throw new Exception();
                }
                this.id = id;
            }
            break;
        } catch (Exception e) {
            System.out.println("ID must be character and lenght > 5");
        }
    }

    while (true) {
        try {
            System.out.print("Input prodct's name: ");
            productName = sc.nextLine().toUpperCase();
            if (productName.isEmpty()) {
                this.productName = this.productName;
            } else {
                if (!productName.matches(letter_regEx)) {
                    throw new Exception();
                }
                this.productName = productName;
            }
            break;
        } catch (Exception e) {
            System.out.println("Invalid name");
        }
    }
    while (true) {
        try {
            System.out.print("Input Unit Price: ");
            unitPrice = sc.nextLine();
            if (unitPrice.isEmpty()) {
                this.unitPrice = this.unitPrice;
            } else {
                if (!unitPrice.matches("^([1-9][0-9]{0,3}|10000)$")) {
                    throw new Exception();
                }
                this.unitPrice = Integer.parseInt(unitPrice);
            }
            break;
        } catch (Exception e) {
            System.out.println("Unit price must be > 0 and < 10000");
        }
    }
    while (true) {
        try {
            System.out.print("Input quantity: ");
            quantity = sc.nextLine();
            if (quantity.isEmpty()) {
                this.quantity = this.quantity;
            } else {
                if (!quantity.matches("^([1-9][0-9]{0,2}|1000)$")) {
                    throw new Exception();
                }
                this.quantity = Integer.parseInt(quantity);
            }
            break;
        } catch (Exception e) {
            System.out.println("Quantity must be > 0 and < 1000");
        }
    }

    while (true) {
        try {
            System.out.print("Input status [0(not available)/ 1 (available)]: ");
            numberForAvail = sc.nextLine();
            if (numberForAvail.isEmpty()) {
                this.numberForAvail = this.numberForAvail;
            } else {
                if (!numberForAvail.matches("^[01]$")) {
                    throw new Exception();
                }
                this.numberForAvail = Integer.parseInt(numberForAvail);
                break;
            }
        } catch (Exception e) {
            System.out.println("Status must 0 for NOT AVAILABLE and 1 for AVAILABLE");
        }
    }
    if (this.numberForAvail == 0) {
        status = "Not available";
    } else {
        status = "Available";
    }

}

This is my output

When I add in a product: When I add in a product:

When I changed NGUYEN’s quantity to 125, it didn’t work When I changed NGUYEN's quantity to 125, it didn't work

Advertisement

Answer

Elements are added to a collection at a position based on how they compare to elements at insertion time. If you change an element so that its ordering changes, then all of the invariants of a data structure like TreeSet are broken, and anything could happen. You should never change these properties of an element after inserting it into a data structure that relies upon them. That means that, when using ordering-based data structures like TreeSet, you shouldn’t change fields that alter the order, and when using hash-based structures like HashSet, you shouldn’t change fields that alter the hash code.

If you really need to mutate the value, you need to remove it from the TreeSet, then mutate it, then put it back in with the new ordering. Or, even better, have an immutable class and simply create a new instance to replace it. Having classes immutable by default avoids all of this messy business in the first place.

8 People found this is helpful
Advertisement