commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Brian Westrich" ...@mcwestcorp.com>
Subject [COLLECTIONS (Comparator)] Proposal: add parent bean null checking
Date Thu, 26 Feb 2004 14:43:46 GMT
Hello commons collections developers,

When using commons comparators to sort collections, I need to handle cases
where a null (top level) element is found in the collection (I know this is
not a usual error condition, but the sorting code I'm replacing with a
Jakarta commons approach does this check so my new code needs to do it as
well).

The NullComparator class works fine for handling null properties on
elements, e.g. ...

        List comparators = new ArrayList();
        comparators.add(new BeanComparator("name", new NullComparator()));
        Comparator comparator = new ComparatorChain(comparators);
        Collections.sort(toSort, comparator); // works fine

but using NullComparator (with the default constructor) to detect null top
level elements currently only works if all elements implement the Comparable
interface. Specifically, the following code throws a ClassCastException if
one or more list elements do not implement Comparable ....

        List comparators = new ArrayList();
        comparators.add(new NullComparator());
        comparators.add(new BeanComparator("name", new NullComparator()));
        Comparator comparator = new ComparatorChain(comparators);
        Collections.sort(toSort, comparator); // throws a ClassCastException
if all list elements don't implement comparable interface

One alternative would be to create a new class (named something like
NullBeanComparator or NullObjectComparator) similar to NullComparator except
that when both objects were non-null it would return 0, e.g.

    public int compare(Object o1, Object o2) {
        if(o1 == o2) { return 0; }
        if(o1 == null) { return (this.nullsAreHigh ? 1 : -1); }
        if(o2 == null) { return (this.nullsAreHigh ? -1 : 1); }
	  return 0;
    }

This new class would be appropriate for use as the first comparator in the
above comparator chain. One would also add analogous methods to
ComparatorUtils such as nullObjectLowComparator and
nullObjectHighComparator.

Another (less preferable?) alternative would be to change
NullComparator.compare(Object, Object) to treat two objects as equal if both
are not null and either does not implement the comparable interface. e.g.

    public int compare(Object o1, Object o2) {
        if(o1 == o2) { return 0; }
        if(o1 == null) { return (this.nullsAreHigh ? 1 : -1); }
        if(o2 == null) { return (this.nullsAreHigh ? -1 : 1); }
        if ((o1 instanceof Comparable == false) || (o2 instanceof Comparable
== false)) return 0; // a line such as this would be added
        return this.nonNullComparator.compare(o1, o2);
    }

But this latter approach seems problematic when nonNullComparator does not
require the compared objects to implement Comparable (for example, when one
constructs a NullComparator using a FixedOrderComparator). In such cases it
seems preferable to call nonNullComparator.compare(). So I prefer the first
alternative over the second.

I appreciate hearing people's thoughts on the above alternatives as well as
any other possible alternatives.

-- Brian

_________________________________________________

Brian Westrich
McWest Corp.
612-508-1827 (bw@mcwestcorp.com)
www.mcwestcorp.com
_________________________________________________




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


Mime
View raw message