2

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")
Community
  • 1
  • 1
Madushan Perera
  • 2,568
  • 2
  • 17
  • 36

4 Answers4

5

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));
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
3

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.
ernest_k
  • 44,416
  • 5
  • 53
  • 99
  • `enum` are already Comparable, you could do `day.compareTo(otherWeekSales.day)` – Peter Lawrey Feb 08 '16 at 13:50
  • Effective Java 2nd ed Item 31 ("Use instance fields instead of ordinals") suggests that such a use of ordinals is not a good idea, e.g. there is nothing to stop somebody "innocently" changing the order of members in the enum, which changes the ordering. – Andy Turner Feb 08 '16 at 13:50
2

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());
  }
}
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
2

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;
    }
};
jBeenenga
  • 317
  • 2
  • 11