1

i have a list that contains product items and when it was purchased. is it possible to use comparator java to first sort this list out by the product description, and then sort it by date purchased as well?

So far i can use it sort out the list in order of dates or description or another field but i want to know if it is possible to sort it by using multiple fields?

here is what i have so far that sorts the dates fine.

public int compare(Transaction aTransaction1, Transaction aTransaction2)
    {
        Date lTransactionDate1 = aTransaction1.getTransactionDate();
        Date lTransactionDate2 = aTransaction2.getTransactionDate();

        return lTransactionDate2.compareTo(lTransactionDate1);
    }

Thanks in advance.

user648036
  • 11
  • 1
  • 3
  • 2
    possible duplicate of [Best way to compare objects by multiple fields?](http://stackoverflow.com/questions/369512/best-way-to-compare-objects-by-multiple-fields) – dogbane Mar 07 '11 at 11:20
  • umm so creating another Compare object seems like the way to go? Or will using enums work too? the enum approach looks better – user648036 Mar 07 '11 at 11:24

3 Answers3

0

Depends on your comparator. If it compares first the product description, then the date, I think you should get what you are after, i.e. the product items get sorted first by description, then the items with the same description are sorted by date.

Péter Török
  • 114,404
  • 31
  • 268
  • 329
  • Umm im not sure what u mean. does the java compare method goes through the list once? or multiple times? i dont want to firts compare the product description and order it by that and then do another compare sorting it by date because that would "break" the previous ordered product description sort. – user648036 Mar 07 '11 at 11:26
  • @user648036 This isn't what Peter suggested you do. However, since you brought the subject up, it is possible to sort the entire list by date first and then by product description, and that will give you the result you need, because the sort algorithm in `Collections.sort()` is conservative. Of course you shouldn't do this but it's good to know that you could. – biziclop Mar 07 '11 at 11:39
  • @user648036, I mean that by implementing and using the right comparator, you can order the list according to your wishes in one pass. @Emil in the meantime added example code which - albeit with different properties, but - illustrates the idea. – Péter Török Mar 07 '11 at 12:33
0

Here is an example for sorting with multiple field.Here the implementation is to sort according to latitude ,longitude and then by height.

public class LatLongHt implements Comparable<LatLongHt> {
    public double lat,lng,ht;
    public LatLongHt(double latitude, double longitude, double ht2) {
        this.lat=latitude;
        lng=longitude;
        ht=ht2;
    }
    @Override
    public int compareTo(LatLongHt obj) {
        int result;
        if((result=compareValue(this.lat,obj.lat))==0)      
            if((result=compareValue(this.lng, obj.lng))==0) 
                result=compareValue(this.ht, obj.ht);
        return result;
    }
    private int compareValue(double val1, double val2) {
        if(val1==val2)
            return 0;
        if(val1>val2)
            return 1;       
        return -1;
    }

    @Override
    public String toString(){
        return "("+lat+','+lng+','+ht+')';

    }


    @ Override
    public boolean equals(Object o){
        if(!(o instanceof LatLongHt))       
            return false;
        LatLongHt that=(LatLongHt)o;
        return that.lat==this.lat && that.lng==this.lng && that.ht==this.ht;
    }

  @Override
  public int hashCode() {
     int result=11;  
     result=(int)(31*result+Double.doubleToLongBits(lat));
     result=(int)(31*result+Double.doubleToLongBits(lng));
     result=(int)(31*result+Double.doubleToLongBits(ht));
    return result;
}

}

I hope this will help you to get an idea how sorting with multiple field works.You can then write a comparator according to your needs.

Emil
  • 13,577
  • 18
  • 69
  • 108
0

The Bean Comparator allows you to sort on a field in your class so you can create a separate comparator for both the description and date. Then you can combine the Comparators into one by using the Group Comparator. Your code would look like:

BeanComparator description = new BeanComparator(Transaction.class, "getDescription");
BeanComparator date = new BeanComparator(Transaction.class, "getTransactionDate");
GroupComparator gc = new GroupComparator(description, date);
Collections.sort(yourList, gc);

Or you can use the individual custom Comparators you have manually created and just use the GroupComparator to do both sorts in one pass.

camickr
  • 321,443
  • 19
  • 166
  • 288