简体   繁体   中英

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

  • not_paid
  • paid
  • part_paid

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;
    }
};

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())); 

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 enum s 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.

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