tech.mohit.garg
tech.mohit.garg

Reputation: 680

Sort Array list of objects based on object attributes

I have list which contains a property class object, In the list i have 3 status

I want to sort my list below mentioned order.

First - not_paid second- part_paid third -paid

How can I sort my list using Comparator class.?

public static Comparator<OrderHistoryItemData> COMPARE_BY_PAYMENT = new Comparator<OrderHistoryItemData>() {
    public int compare(OrderHistoryItemData one, OrderHistoryItemData other) {
        String p1 = one.getAttributes().getFieldPaymentStatus();
        String p2 = other.getAttributes().getFieldPaymentStatus();
        if (p1.equals(p2)) {
            return 0;
        }
        if (p1.equals("not_paid") && (p2.equals("part_paid") || p2.equals("not_paid"))) {
            return -1;
        }
        if (p1.equals("not_paid") && p2.equals("not_paid")) {
            return -1;
        }
        return 1;
    }
};

This is my Code. i am getting below order using this code.

paid-->not_paid-->part_paid

This is my Update Code. I got my result.

public static Comparator<OrderHistoryItemData> COMPARE_BY_PAYMENT = new Comparator<OrderHistoryItemData>() {
    public int compare(OrderHistoryItemData one, OrderHistoryItemData other) {
        String p1 = one.getAttributes().getFieldPaymentStatus();
        String p2 = other.getAttributes().getFieldPaymentStatus();
        if (p1.equals(p2)) {
            return 0;
        }
        if (p1.equals("not_paid") && (p2.equals("part_paid") || p2.equals("paid"))) {
            return -1;
        }
        if (p1.equals("part_paid") && p2.equals("paid")) {
            return -1;
        }
        return 1;
    }
};

Upvotes: 3

Views: 128

Answers (2)

MC Emperor
MC Emperor

Reputation: 22967

What you can do is first mapping the strings to integers in the desired order, and then simply subtracting them from eachother.

private static Comparator<Payments> comparator = new Comparator<Payments>() {

    // Use this mapping function to map the statuses to ints.
    // The lowest number comes first
    private int map(String str) {
        switch (str) {
            case "not_paid":
                return 0;
            case "part_paid":
                return 1;
            case "paid":
                return 2;
            default:
                return 3;
        }
    }
    // Alternatively, you can use the Map interface to define the sorting
    // order.

    @Override
    public int compare(Payments o1, Payments o2) {
        return map(o1.status) - map(o2.status);
    }
};

I suggest – Schidu Luca already mentioned it in his answer – that you use enums to define a fixed set of known values, like payment statuses. This provides compile-time safety.

Note: I wouldn't, however, suggest to bind the enum declaration order to the sorting order.

Upvotes: 4

Schidu Luca
Schidu Luca

Reputation: 3947

To avoid complex comparator, I encourage you to export your statuses to an enum. (Plus this will work if you will add more statuses in the future, without the need to change logic in your comparator):

enum PaymentStatus { // Write them in order you want to be sorted
    NOT_PAID,
    PART_PAID,
    PAID
}

Then sorting will be as simple as :

list.sort(Comparator.comparing(item ->item.getAttributes().getFieldPaymentStatus())); 

Upvotes: 6

Related Questions