Madushan Perera February 2016

Sorting an arraylist of object base on its property in custom order

I need to sort my array list in custom order (not alphabetical order) by its own String property.

List<WeekSales> saleList = new ArrayList<>();
...

WeekSales:

public class WeekSales{

private String day;
private int amount;

// getters setters
...

}

Property day is always a day of the week. ("Sunday","Monday", etc...) So I need to order the elements of the list according to the order of the week.("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")

So I tried with google.common.collect.Ordering. But it gives me an error

Cannot compare value: com.certus.controllers.WeekSales

Comparator<WeekSales> com = Ordering.explicit(new WeekSales("Monday",0), new WeekSales("Tuesday",0), new WeekSales("Wednesday",0), new WeekSales("Thursday",0), new WeekSales("Friday",0), new WeekSales("Saturday",0),new WeekSales("Sunday",0));
                saleList.sort(com);

Any help would be appreciable. Thank you.

UPDATE :

This question has no any solution for my problem. I have got a custom order in my case.

("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")

Answers


Andy Turner February 2016

Unless you actually try to sort a list containing the items listed in the parameters of Ordering.explicit, it doesn't know how to sort them. It's also not clear if you've overridden your WeekSales.equals (and hashCode), which would be required for that to work too.

You need to actually tell it the fields to compare:

class YourComparator implements Comparator<WeekSales> {
  private final Ordering<String> dayOrdering = Ordering.explicit(
    "Monday", "Tuesday", ... );

  @Override public int compare(WeekSales a, WeekSales b) {
    return dayOrdering.compare(a.getDay(), b.getDay());
  }
}


Peter Lawrey February 2016

You could use a Map to help.

Map<String, Integer> dayToOrder= new HashMap<>();
for (String day: "Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday".split(","))
    dayToOrder.put(day, dayToOrder.size());

To sort your collection

List<WeekSales> saleList = new ArrayList<>();

saleList.sort(Comparator.comparing(ws -> dayToOrder.get(ws.day)));

Another solution is to use an enum from the start.

enum WeekDay {
    Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday;
}

public class WeekSales {

    private WeekDay day; // can only be a valid week day
    private int amount;

    // getters setters
    WeekDay getDay() { return day; }
    ...

}

then to sort you can use the ordinal()

 saleList.sort(Comparator.comparing(WeekDay::getDay));


jBeenenga February 2016

Can't you implement your Comparator in this way:

Comparator<WeekSales> com = new Comparator<WeekSales>() {

    @Override
    public int compare(WeekSales o1, WeekSales o2) {
    //do stuff with o1 and o2 by getDay()
    return 0;
    }
};


Ernest Kiwele February 2016

You could use an enum for your week days:

public enum WeekDay {
   MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}

And then your class would look like this:

public class WeekSales implements Comparable<WeekSales>{
    private WeekDay day;
    private int amount;

    //Add a comparison method
    public int compareTo(WeekSales otherWeekSales) {
        return this.day.ordinal() - otherWeekSales.day.ordinal();
    }
}

That code implements the comparable interface and the compareTo method uses the order of the WEEKDAY value to compare.

And to sort:

Collections.sort(saleList); //That will use the compareTo method implemented in the class.

Post Status

Asked in February 2016
Viewed 2,000 times
Voted 7
Answered 4 times

Search




Leave an answer