How to sort Java collection on multiple columns
Java collection API, provide Comparator interface to sort the Java collection such as List. However, multi column sort is not possible. Multi column sort can be achieved using two Comparators in two different Collections.sort(Comparator...) calls. I am wonder why sort() method doesn't allow for varargs which is new in Java 5. Due to the limitation of sorting one column at once may giving performance problem (I don't know). Apache common has facility do multi column sorting.
package com.oj.ex; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; import org.apache.commons.collections.comparators.ComparatorChain; public class TestSorting { /** * @param args */ @SuppressWarnings("unchecked") public static void main(String[] args) { List<Payment> payments = new ArrayList<Payment>(); DateFormat df = new SimpleDateFormat("dd/MM/yyyy"); try { payments.add(new Payment("200503",df.parse("21/03/2010"),"A")); payments.add(new Payment("200502",df.parse("10/02/2010"),"B")); payments.add(new Payment("200602",df.parse("22/03/2010"),"C")); payments.add(new Payment("200605",df.parse("22/02/2010"),"D")); payments.add(new Payment("200511",null,"E")); payments.add(new Payment("200511",null,"F")); payments.add(new Payment("200503",null,"G")); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } ComparatorChain chain = new ComparatorChain(); chain.addComparator(new Comparator<Payment>(){ @Override public int compare(Payment first, Payment second) { return first.getCalcid().compareTo(second.getCalcid()); }},true); chain.addComparator(new Comparator<Payment>(){ @Override public int compare(Payment first, Payment second) { if (first.getPaymentDate()==null && second.getPaymentDate()!=null) return 1; else if (first.getPaymentDate()!=null && second.getPaymentDate()==null) return -1; else if (first.getPaymentDate()==null && second.getPaymentDate()==null) return 0; else { if (first.getPaymentDate().before(second.getPaymentDate())) return -1; else if (first.getPaymentDate().after(second.getPaymentDate())) return 1; else return 0; } }},true); Collections.sort(payments, chain); for (Payment payment : payments) { System.out.println(payment.getName()+" | "+payment.getCalcid()+" | "+payment.getPaymentDate()); } } } class Payment { private String calcid; private Date paymentDate; private String name; Payment(String calcid, Date paymentDate, String name){ this.paymentDate = paymentDate; this.calcid = calcid; this.name = name; } public String getCalcid() { return calcid; } public void setCalcid(String calcid) { this.calcid = calcid; } public Date getPaymentDate() { return paymentDate; } public void setPaymentDate(Date paymentDate) { this.paymentDate = paymentDate; } public String getName() { return name; } public void setName(String name) { this.name = name; } }if you have any suggestion please comment.
Comments
Post a Comment
commented your blog