commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "MATHUS Baptiste" <mathu...@mipih.fr>
Subject [collections] Multi property BeanComparator
Date Wed, 15 Mar 2006 14:48:00 GMT
Hi everybody,

I recently needed to be able to sort a list of beans on many properties. So I thought I would
try and pick one of the collections comparators.  

I had to to the sorting close to the sql way : be able to sort on n properties, some ascending,
some descending.

I haven't found what I'm looking for (:p), but I found some comparators I used to do this
: I used BeanComparator, NullComparator and ComparatorChain to create a class : MultiPropertyBeanComparator.

Is there already something in one of the commons package that could be used instead of it
? 

If not, I'd be glad to contribute the small piece of code if wanted. It has dependencies against
commons-beanutils (BeanComparator, which is moving from one package to another at the moment,
no ?) and commons-lang (StringUtils.isBlank()). I think some things might not satisfactory
for everybody, but hey, could still be improved without problems, that's not big work :p.

Here it is :

=======================================
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.collections.ComparatorUtils;
import org.apache.commons.collections.comparators.NullComparator;
import org.apache.commons.collections.comparators.ReverseComparator;
import org.apache.commons.lang.StringUtils;

/**
 * This comparator lets you sort a list using a list of properties. You can specify ascending
or
 * descending order on these properties.
 * <p>
 * For example, if you want to sort with natural order a list of beans with properties firstname,
 * nickname and address, sorting the firstname descending, you can do it this way:
 * </p>
 * <code>List l = ...</code>
 * <code>...</code>
 * <code>MultiPropertyBeanComparator multiPropBeanComp = new MultiPropertyBeanComparator();</code>
 * <code>multiPropBeanComp.append("firstname", true).append("nickname").append("address");</code>
 * <code>Collections.sort(l,multiPropBeanComp);</code>
 * 
 * @author Baptiste MATHUS
 */
public class MultiPropertyBeanComparator implements Comparator, Serializable
{
	private static final long serialVersionUID = -1431852774261001458L;

	private List comparatorList = new ArrayList();

	/**
	 * Use this method to add a comparator to the list.
	 * 
	 * @param property
	 *            the property on which to apply the given comparator.
	 * @param comparator
	 *            the comparator to be added. If null, natural order will be used.
	 * @param reverse
	 *            <p>
	 *            must be true if the given comparator must be used in opposite order to sort.
For
	 *            example, if the comparator is designed to sort in ascending order, put this
	 *            parameter to <code>true</code> if you want descending order.
	 *            </p>
	 *            <p>
	 *            If the comparator is null, then the reversed natural order is used.
	 *            </p>
	 */
	public MultiPropertyBeanComparator append(String property, Comparator comparator,
			boolean reverse)
	{
		if (StringUtils.isBlank(property))
		{
			throw new IllegalArgumentException("The given property is blank");
		}

		// If the comparator is null, then compare only on the given property
		// with a natural sort.
		if (comparator == null)
		{
			comparator = new BeanComparator(property, new NullComparator(false));
		}
		// Else : compare on the property, but with given comparator.
		else
		{
			comparator = new BeanComparator(property, comparator);
		}
		// Here, the comparator cannot be null anymore, so reverse it if
		// necessary.
		if (reverse)
		{
			comparator = new ReverseComparator(comparator);
		}

		comparatorList.add(comparator);

		return this;
	}

	public MultiPropertyBeanComparator append(String property, Comparator c)
	{
		return append(property, c, false);
	}

	public MultiPropertyBeanComparator append(String property)
	{
		return append(property, null, false);
	}

	public MultiPropertyBeanComparator append(String property, boolean reverse)
	{
		return append(property, null, reverse);
	}

	/**
	 * Use this method to clear the
	 */
	public void clear()
	{
		comparatorList.clear();
	}

	/**
	 * Considered to be equal when all properties and comparators equal.
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 * @overrides
	 */
	public boolean equals(Object obj)
	{
		MultiPropertyBeanComparator comp = (MultiPropertyBeanComparator) obj;

		if (this.comparatorList.size() != comp.comparatorList.size())
		{
			return false;
		}

		for (int i = 0; i < comparatorList.size(); ++i)
		{
			if (!this.comparatorList.get(i).equals(comp.comparatorList.get(i)))
			{
				return false;
			}
		}
		return true;
	}

	/**
	 * @see Comparator#compare(T, T)
	 * @overrides
	 */
	public int compare(Object arg0, Object arg1)
	{
		return getComparator().compare(arg0, arg1);
	}

	private Comparator getComparator()
	{
		return ComparatorUtils.chainedComparator(comparatorList);
	}
}
=======================================

Thanks for the answers.

Baptiste

-- 
Baptiste MATHUS - mathus.b@mipih.fr
Systèmes & Méthodes
MIPIH - Midi Pyrénées Informatique Hospitalière

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Mime
View raw message