Discussions

Web tier: servlets, JSP, Web frameworks: Sorting line items in a ShoppingCart

  1. Sorting line items in a ShoppingCart (6 messages)

    Hi...
    For example, if I have a ShoppingCart object which contains an ArrayList of lineItem objects. Each lineitem
    object contains the attribute productName, productPrice, productCode, and quantity.

    Here's the expected behavior.

    For example... initially it's sorted by
    productCode, productName, productPrice, and quantity.

    If the user clicks productName then it will be sorted by
    productName, productCode, productPrice, and quantity.

    If the user clicks productPrice then it will be sorted by
    productPrice, productName, productCode, and quantity.

    and so on...

    Initially I planned to use Comparator but this can only be used for sorting a single column.

    How do I implement such functionality?

    thank you very much your help will be very much appreciated.


    Jerson

    Threaded Messages (6)

  2. I believe Comparator can be used for sorting any number of columns. The Comparator interface has two methods, only one of which is important, the compare method that accepts two objects to be compared. If you're sorting a list of objects all of which are either the same class or which implement the same interface, you can write your comparator(s) to compare any number of attributes in those objects. Your other option - the one I found handiest - is to write a generic sorter that accepts any list of objects (of the same class) and sorts them by any number of attributes (which you identify using reflection).
  3. I know how to use the comparator but the problem is how do I derive the value returned in the compareTo method.

    If I have product code, product name, price, date available...

    How do I know that row1 is less than or greater than rowX?

    Someone told me to concatenate all columns and use the compareTo method of String? This will not work if I have a date object in one of the columns so my solution is to use the millisecond representation of the date. This will also not work if the columns have different length. I can pad the column but I feel that this is just a work around.

    Any suggestions?

    Thanks...
    Jerson
  4. Jerson, I had much the same sorting problem in an application I wrote last year. The solution is fairly straightforward. Assume you have to sort a group of objects on 3 separate fields of information and that your objects have a get property for each one, for instance:

    public class Thing {
       ...
       public Date getDate() { return date; }
       public String getName() { return name; }
       public int getSize() { return size; }
    }

    If you want to sort by ascending name, date, and size, you'd write your comparator as follows:

    public int compare(Object obj1, Object obj2) {
       Thing thing1 = (Thing)obj1;
       Thing thing2 = (Thing)obj2;
       return compareName(thing1,thing2);
    }
    private int compareName(Thing thing1, Thing thing2)
    {
       int result = thing1.getName().compareTo(thing2.getName());
       return (result == 0) ? compareDate(thing1,thing2) : result;
    }

    private int compareDate(Thing thing1, Thing thing2)
    {
       int result = thing1.getDate().compareTo(thing2.getDate());
       return (result == 0) ? compareSize(thing1,thing2) : result;
    }

    private int compareSize(Thing thing1, Thing thing2)
    {
       int result = thing1.getSize() - thing2.getSize();
       return result;
    }

    You check each value (name,date,size) separately, only moving onto the next sort field when the current one indicates equality. Hope this helps!

    Regards,

    Gordon Reynolds
  5. Hi Gordon...
    After posting to several forums and mailing lists, you're the only person who were able to answer my query. Thank you very much.

    I'll try to implement it in such a way that it can sort the columns in any order. I think this will be a recursive method.


    Again... thank you...
    Jerson
  6. Here's a rought draft of my implementation. Thank you very much. I wouldn't be able to do this without you. It can now sort the columns in any order.

    import java.util.Date;
    import java.util.*;

    class LineItem {
    private int quantity;
    private String productName;
    private Date dateAvailable;

    public LineItem(String _productName, int _quantity, Date _dateAvailable) {
    productName = _productName;
    quantity = _quantity;
    dateAvailable = _dateAvailable;
    }

    public String getProductName() {
    return productName;
    }

    public int getQuantity() {
    return quantity;
    }

    public Date getDateAvailable() {
    return dateAvailable;
    }

    public String toString() {
    return productName + ", " + quantity + ", " + dateAvailable;
    }
    }

    class MyComparator implements Comparator {
    private String[] columnOrder;
    public void setColumnOrder(String[] _columnOrder) {
    columnOrder = _columnOrder;
    }

    public int compare(Object obj1, Object obj2) {
    return compareColumn(0 , (LineItem) obj1, (LineItem) obj2);
    }

    private int compareColumn(int columnIndex, LineItem l1, LineItem l2) {
    int result = 0;
    if (columnOrder[columnIndex].equals("productName")) {
    result = l1.getProductName().compareTo(l2.getProductName());
    } else if (columnOrder[columnIndex].equals("quantity")) {
    result = new Integer(l1.getQuantity()).compareTo(new Integer(l2.getQuantity()));
    } else if (columnOrder[columnIndex].equals("dateAvailable")) {
    result = l1.getDateAvailable().compareTo(l2.getDateAvailable());
    }

    if (columnIndex + 1 == columnOrder.length) {
    return result;
    }
    return (result == 0) ? compareColumn(++columnIndex , l1 , l2) : result;
    }

    public static void main(String[] args) {
    LineItem[] items = new LineItem[8];
    items[0] = new LineItem("aaaa", 4, new Date());
    items[1] = new LineItem("aaaa", 3, new Date());
    items[2] = new LineItem("bbbb", 0, new Date());
    items[3] = new LineItem("dddd", 0, new Date());
    items[4] = new LineItem("cccc", 0, new Date());
    items[5] = new LineItem("aaaa", 0, new Date());
    items[6] = new LineItem("dddd", 0, new Date());
    items[7] = new LineItem("aaaa", 5, new Date());

    MyComparator mc = new MyComparator();
    mc.setColumnOrder(new String[] {"quantity", "productName", "dateAvailable"});
    Arrays.sort(items, mc);

    for (int i = 0; i < items.length; i++) {
    System.out.println(items[i]);
    }
    }
    }

    Jerson
  7. Glad to have helped.