用Java返回排序列表

时间:2012-05-22 19:25:05

标签: java oop sorting collections refactoring

我正在编写这样的代码:

List<Bean> beans = service.findBeans();
Collections.sort(beans, new BeanComparator());
return beans;

完美无缺。我正在寻找的只是一行的快捷方式:

return somelibrary.Collections.sort(service.findBeans(), new BeanComparator());

或者:

return somelibrary.newList(service.findBeans(), new BeanComparator());

请注意,它需要一个可变列表。

6 个答案:

答案 0 :(得分:11)

这是一行:

List<Bean> beans = service.findBeans(); Collections.sort(beans, new BeanComparator()); return beans;

但更严重的是,Java并不是单行的正确语言。而且,仅仅因为某种东西是单线并不意味着它更好。例如,我最初惊讶地发现这个:

return condition ? a : b;

创建比

更长的字节码
if( condition )
    return a;
else
    return b;

但这就是语言和编译器的用法。

如果你坚持单行,GuavaOrdering可以做到:

return Ordering.from( new BeanComparator() ).sortedCopy( service.findBeans() );

返回的列表是可修改的,可序列化的,并且具有随机访问权。

效率方面我认为在开销方面存在一些浪费。此外,您现在依赖于第三方库。你本质上是使用非常强大的工具来完成一项非常简单的任务。如果您正在使用它,那就太过分了。

答案 1 :(得分:4)

我相信以下功能会产生您想要的效果。把它放在你选择的班级里。

public static <T> List<T> sort(List<T> list, Comparator<? super T> compare) {
    Collections.sort(list, compare);
    return list;
}

答案 2 :(得分:2)

您可以使用apache CollectionUtils来使用比较器和空列表整理列表。

CollectionUtils.collate(service.findBeans().iterator(),Collections.EMPTY_LIST.iterator(),new beanComparator())

CollectionUtils确实应该添加一个返回排序列表的实用工具方法......

使用更多行的经典反驳是LOGGING。为可读性而进行日志记录不应占用多行。当您尝试找出实际执行的代码时,记录是静态噪声,但记录非常关键。

因此,日志记录应该是紧凑的(在一行中)并且安静(不应该抛出异常/是nullsafe)并且应该是高性能的(如果关闭则不应该引入超出isDebugOn()检查的多余处理。

第二个反驳是流畅的界面,例如JOOQ,它正变得越来越普遍。

答案 3 :(得分:1)

我想如果你没有重复,并且不介意你可以使用的hacky代码:

return new ArrayList<Bean>(new TreeSet<Bean>(service.findBeans()));

答案 4 :(得分:1)

我认为发布的原始问题是有效的。因为&#34; Collections.sort(..)&#34;方法具有排序传入集合的预期副作用,如果您想维护原始集合,则必须执行以下操作:

List<Bean> beans = service.findBeans();
List<Bean> sortedBeans = new ArrayList<Bean>(beans);
Collections.sort(sortedBeans, new BeanComparator());
return sortedBeans;

在上面的例子中,我们对服务方法返回的Collection进行排序可能不是那么大。但是,如果我们正在排序的Collection是一个方法参数,并且调用者不希望Collection传入已排序呢?

我通常更喜欢没有后果的方法。

自&#34; Collections.sort(..)&#34;影响列表,我必须编写以下代码:

public void doSomethingWithBeansInOrder(List<Bean> beans) {
    Collection<Bean> sortedBeans = new ArrayList<Bean>(beans);
    Collections.sort(sortedBeans, ...comparator...;

    for (Bean bean : sortedBeans) {
        .. do something
    }
}

我找到&#34; sortedBeans&#34;的定义。难看。

如果&#34;(Collections.sort(..)&#34;(或类似的东西),返回一个新的Collection并且不影响传入的Collection,我可以写:

public void doSomethingWithBeansInOrder(List<Bean> beans) {
    for (Bean bean : Collections.sort(beans, ...comparator...) {
        .. do something
    }
}

我认为Guava Ordering的答案最好。

答案 5 :(得分:1)

首先,Java 8在List接口上引入了sort() metod。因此,对实际列表进行排序的一个示例是:

List<Integer> integerList = Arrays.asList(3, 2, 1);
integerList.sort(Comparator.naturalOrder());
return integerList;

在这里,我使用了预定义的naturalOrder()比较器,后者又依赖于Comparable,但也可以使用自定义比较器。这仍然需要两个陈述。

但是,如果所需的行为是创建一个新的排序列表,并保留之前的orignial,我想一个流将是最简单的方法:

integerList.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());

同样的事情适用于这里的比较器。