4

我正在编写这样的代码:

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

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

4

6 回答 6

12

这是一行:

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

但更严重的是,Java 并不是真正适合单行代码的语言。此外,仅仅因为某些东西是单线的,并不意味着它会更好。例如,我最初惊讶地发现:

return condition ? a : b;

创建比

if( condition )
    return a;
else
    return b;

但这就是语言和编译器的样子。

如果你坚持你的单线,番石榴可以Ordering做到:

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

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

效率方面,我认为在开销方面有点浪费。而且您现在还依赖于第 3 方库。您实际上是在使用非常强大的工具来完成一项非常简单的任务。如果这就是你使用它的全部,那就太过分了。

于 2012-05-22T19:39:11.427 回答
4

我相信下面的函数会产生你想要的结果。只需将其放在您选择的类中即可。

public static <T> List<T> sort(List<T> list, Comparator<? super T> compare) {
    Collections.sort(list, compare);
    return list;
}
于 2012-05-22T19:32:22.817 回答
2

您可以使用 apache CollectionUtils 将列表与比较器和空列表进行比较。

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

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

对 use-more-lines 的经典反驳是 LOGGING。出于可读性目的而进行的日志记录不应超过一行。当您试图找出代码实际在做什么时,日志记录是一种静态噪音,但日志记录是相当关键的。

所以日志记录应该是紧凑的(一行)和安静的(不应该抛出异常/是空安全的)并且应该是高性能的(如果关闭不应该引入超出 isDebugOn() 检查的额外处理。

第二个反驳是流利的接口,如 JOOQ,它变得越来越流行。

于 2014-12-29T19:51:22.613 回答
1

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

return new ArrayList<Bean>(new TreeSet<Bean>(service.findBeans()));
于 2013-04-10T22:25:09.707 回答
1

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

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

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

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

由于“Collections.sort(..)”影响列表,我必须编写以下代码:

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

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

我发现“sortedBeans”的定义很难看。

如果“(Collections.sort(..)”(或类似的东西)返回一个新的集合并且不影响传入的集合,我可以写:

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

我认为Guava的答案Ordering是最好的。

于 2014-05-02T16:02:46.443 回答
1

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

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

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

但是,如果所需的行为是创建一个新的排序列表,并保持原来的状态不变,我猜流将是最简单的方法:

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

与上面相同的内容适用于这里的比较器。

于 2016-12-08T06:56:09.520 回答