Java Collections.sort - help me remove the unchecked warning
List<Question> questions = new ArrayList<Question>();
quest开发者_运维百科ions.addAll(getAllQuestions()); //returns a set of Questions
Collections.sort(questions, new BeanComparator("questionId")); //org.apache.commons.beanutils.BeanComparator
Under Java 1.5, the above works fine except that the 'new BeanComparator("questionId")' generates an unchecked warning. I do not like warnings. Is there a way I can provide the BeanComparator a type, or do I have to use @SuppressWarnings("unchecked")
?
Options are:
- Change
BeanComparator
to implementComparator<Question>
. This is not a real option here, given it is a well-known external library class. People ain't going to let you do it. - Fork and modify
BeanComparator
as above, giving it a different FQN. - Wrap the existing
BeanComparator
with a class that implementsComparator<Question>
. - Change the type of
questions
toList<?>
. - Add a suppress warnings annotation.
Since BeanComparator
isn't generic, you'll just have to suppress.
UPDATE: Actually, if it bothers you enough, you could fork the codebase to make it generic, since it's Open Source.
Unless adding a new generic class at Apache Commons Beanutils, the best I found was to wrap BeanComparator in a new method in my "bean toolbox" :
/**
* Wrapping of Apache communs BeanComparator. Create a comparator which compares two beans by the specified bean
* property. Property expression can use Apache's nested, indexed, combinated, mapped syntax. @see <a
* href="http://commons.apache.org/beanutils/api/org/apache/commons/beanutils/BeanComparator.html">Apache's Bean
* Comparator</a> for more details.
* @param <T> generic type
* @param propertyExpression propertyExpression
* @return the comparator
*/
@SuppressWarnings("unchecked")
public static <T> Comparator<T> createPropertyComparator(final String propertyExpression) {
return new BeanComparator(propertyExpression);
}
Create a generic wrapper class:
public class GenericBeanComparator<T> implements Comparator<T> {
private final BeanComparator myBeanComparator;
public GenericBeanComparator(String property) {
myBeanComparator = new BeanComparator(property);
}
public int compare(T o1, T o2) {
return myBeanComparator.compare(o1, o2);
}
}
Use it like this:
List<Question> questions = new ArrayList<Question>();
questions.addAll(getAllQuestions()); //returns a set of Questions
Collections.sort(questions, new GenericBeanComparator<Question>("questionId"));
Yes, you are supposed to use @SuppressWarnings("unchecked"). There is no reason to think the comparator not using generics can cause a problem in that case.
You could always switch to using Google Collections.
They support Generics.
The only way to remove the warning would be to change the code of BeanComparator, but even if you could, unless you made it a specific wrapper that understands your particular type, the concept wouldn't work well. The class operates on any object by reflection which may or may not have the method. It is inherently not typesafe.
The simplest way around the warning is to implement your own comparator:
public class QuestionComparator extends Comparator<Question> {
private BeanComparator peer = new BeanComparator("questionId");
public int compare(Question o1, Question o2) {
return peer.compare(o1, o2);
}
}
You could also implement equals if it matters, and call the BeanComparator equals method like this:
public boolean equals(Object o) {
//boiler plate code here to ensure o is an instance of Question and not null
return ((QuestionComparator) o).peer.equals(peer);
}
BeanComparator is a very small class. Grab the source code and modify it like this:
public class BeanComparator<E> implements Comparator<E>, Serializable {
And modify your invocation like this:
Collections.sort(yourCollection, new BeanComparator<yourBeanClass>(yourProperty));
And voilà warnings disappeared.
精彩评论