You need to reverse the effects
of
a Comparator
. You need to return less than when
this Comparator
returns greater than, and greater
than when it returns less than.
Use
ReverseComparator
to reverse the effects of a Comparator
. Supply an
existing Comparator
to the constructor of
ReverseComparator
, and it reverses the effects of
that Comparator
. The following example
demonstrates the use of ReverseComparator
to
reverse the result of a custom MyComparator
instance:
Comparator myComparator = new MyComparator( );Comparator reverseComparator = new ReverseComparator( myComparator );
Book book1 = new Book( ); Book book2 = new Book( ); int comparison = myComparator.compare( book1, book2 );int reversedComparison = reverseComparator( book1, book2);
The value of reversedComparison
is simply the
negative of comparison
; if
MyComparator
decides that book1
is less than book2
, the
ReverseComparator
returns the opposite
result—greater than. ReverseComparator
simply wraps the original Comparator
and
multiplies the result by negative one.
Example 4-1 is an implementation of a
Comparator
that is reversed using the
ReverseComparator
. This
BookComparator
compares two
Book
objects by the name
and
author
bean properties. Sorting a list of books
using this Comparator
results in a list sorted
alphabetically by book name and author name; if two books have the
same name, they are sorted by author name.
Example 4-1. A Comparator that compares Book objects by name and author
package com.discursive.jccook.collections.compare; import java.util.*; import org.apache.commons.lang.StringUtils; import org.apache.commons.collections.comparators.ReverseComparator; public class BookComparator implements Comparator { public int compare(Object o1, Object o2) { int comparison = -1; if( o1 instanceof Book && o2 instanceof Book ) { Book b1 = (Book) o1; Book b2 = (Book) o2; String b1Name = b1.getName( ); String b2Name = b2.getName( ); String b1Author = b1.getAuthor( ); String b2Author = b2.getAuthor( ); if( StringUtils.isNotEmpty( b1Name ) && StringUtils.isNotEmpty( b2Name ) ) { comparison = b1Name.compareTo( b2Name ); } if( comparison == 0 && StringUtils.isNotEmpty( b1Author ) && StringUtils.isNotEmpty( b2Author ) ) { comparison = b1Author.compareTo( b2Author ); } } return comparison; } }
Example 4-2 sorts an array of
Book
objects in reverse order.
Example 4-2. Using ReverseComparator to sort Book objects
package com.discursive.jccook.collections.compare; import java.util.*; import org.apache.commons.collections.comparators.ReverseComparator; public class ReverseExample { public static void main(String[] args) throws Exception { ReverseExample example = new ReverseExample( ); example.start( ); } public void start( ) throws Exception {// Create a Reversed BookComparator
Comparator bookCompare = new BookComparator( );
Comparator reverseComparator = new ReverseComparator( bookComparator );
// Create a List of Book objects List books = new ArrayList( ); Book book1 = new Book( ); book1.setName( "TitleA" ); book1.setAuthor( "John" ); books.add( book1 ); Book book2 = new Book( ); book2.setName( "TitleB" ); book2.setAuthor( "Donald" ); books.add( book2 ) Book book3 = new Book( ); book3.setName( "TitleA" ); book3.setAuthor( "Doug" ); books.add( book3 );// Sort the List of Book objects with the Reversed BookComparator
Collections.sort( books, reverseComparator );
} }
After Collections.sort( )
, the
books
array is sorted in reverse alphabetical
order by book name and author name: “TitleB by
Donald” followed by “TitleA by
John” followed by “TitleA by
Doug.”
If you were using a simple Comparator
to sort an
array, you could sort and reverse the resulting array with
Arrays.reverse( )
, or you could reverse a
List
with Collections.reverse( )
. Wrapping a Comparator
in
ReverseComparator
may help you avoid the call to
reverse( )
, but the benefit is miniscule.
ReverseComparator
makes more sense when used in
the context of a ChainedComparator
; see
Recipe 4.4 for more information about the
ChainedComparator
.
Note that use of StringUtils.isNotEmpty( )
is used
in BookComparator
to check if either of the bean
properties are null or blank. This utility,
is from
StringUtils
, and it is introduced in Recipe 2.2.
Get Jakarta Commons Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.