3

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;
    }
};
2
  • Please add some data and code to your question. Commented Sep 6, 2018 at 10:54
  • You forgot add your code? Commented Sep 6, 2018 at 10:57

2 Answers 2

6

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())); 
Sign up to request clarification or add additional context in comments.

3 Comments

i am trying to use your code but where i have to pass the "PaymentStatus" below is my code Collections.sort(list, Comparator.comparing((OrderHistoryItemData orderListResult) -> orderListResult.getAttributes().getFieldPaymentStatus()));
It's just an enum you can create a separate file for this.
Also in OrderHistoryItemData, you have to replace your String field with the create enum field
4

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.