Java集合排序 - 帮我消除未经检查的警告

10
List<Question> questions = new ArrayList<Question>();
questions.addAll(getAllQuestions()); //returns a set of Questions
Collections.sort(questions, new BeanComparator("questionId")); //org.apache.commons.beanutils.BeanComparator

在Java 1.5中,上述代码可以正常工作,但 'new BeanComparator("questionId")' 会产生未经检查的警告。我不喜欢警告。有没有办法为 BeanComparator 提供类型,或者必须使用 @SuppressWarnings("unchecked")


你尝试过将 "new BeanComparator" 强制转换为 (Comparator<Question>) 吗? - Paul J. Lucas
那只会引发不同的警告。 - skaffman
完全不同的事情,你是否更喜欢在QuestionDAO中执行ORDER BY id操作? - BalusC
8个回答

10

选项如下:

  • BeanComparator改为实现Comparator<Question>。由于它是一个众所周知的外部库类,这里不是真正的选项。人们不会让你这么做。
  • 分叉并修改BeanComparator,将其作为上述内容进行修改,并给出不同的FQN。
  • 用一个实现了Comparator<Question>的类来包装现有的BeanComparator
  • questions的类型更改为List<?>
  • 添加抑制警告注释。

添加一个抑制警告的注解。这应该是最后的手段,仅在你百分之百确认是安全的情况下才使用。 - Marius Burz
3
好的。但在这种情况下,你可以百分之百确定。如果出现错误,最糟糕的情况只是在一个意想不到的地方得到一个"ClassCastException"。 - Stephen C

5

由于BeanComparator不是泛型的,所以您只需进行抑制。

更新:实际上,如果这让您感到困扰,您可以分叉代码库使其成为泛型,因为它是开源的。


1
创建一个通用的包装器类:
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);
  }
}

使用方法如下:

List<Question> questions = new ArrayList<Question>();
questions.addAll(getAllQuestions()); //returns a set of Questions
Collections.sort(questions, new GenericBeanComparator<Question>("questionId"));

1
除非在Apache Commons Beanutils中添加新的泛型类,否则我找到的最好方法是在我的“bean工具箱”中包装BeanComparator,如下所示:
/**
 * 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);
}

0
唯一消除警告的方法是更改BeanComparator的代码,但即使您能够这样做,除非您将其变成了一个特定的包装器,能理解您的特定类型,否则该概念也不会很好地工作。该类通过反射操作任何对象,这些对象可能具有或可能没有该方法。它本质上不是类型安全的。
最简单的绕过警告的方法是实现您自己的比较器:
 public class QuestionComparator extends Comparator<Question> {
      private BeanComparator peer = new BeanComparator("questionId");

      public int compare(Question o1, Question o2) {
             return peer.compare(o1, o2);
      }
 }

如果需要,您也可以实现 equals 方法,并像下面这样调用 BeanComparator 的 equals 方法:

   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);
   }

0

是的,你应该使用 @SuppressWarnings("unchecked")。在这种情况下,没有理由认为不使用泛型的比较器会引起问题。


0
你可以考虑切换到使用Google Collections。
它们支持泛型。

0

BeanComparator是一个非常小的类。获取源代码并将其修改如下:

public class BeanComparator<E> implements Comparator<E>, Serializable {

然后将您的调用修改为:

Collections.sort(yourCollection, new BeanComparator<yourBeanClass>(yourProperty));

那么,警告就消失了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接