【问题标题】:How to sort an Iterable如何对可迭代对象进行排序
【发布时间】:2016-08-01 21:38:33
【问题描述】:

我有一个实现 Iterable 的自定义列表(不是集合!!)。我没有实现 List,因为这会带来太多我不想要的方法,而且我不需要。

关于我的 CustomList 的更多信息:

  • 所有成员均为最终成员
  • 每个 CustomList 都可以有一个“SubList”,它是另一个 CustomList
  • 每个 CustomList 都必须有一个 MyThing
  • 示例:假设 A 是 MyThing 的对象,B 是 MyThing 的对象,可以有一个只有 A 的 CustomList(我们称之为 AList)和一个带有 Item B 和 AList 作为子列表的 CustomList。
  • CustomList 有一个可以接受 MyThings 数组的构造函数

这是我的班级:

public class CustomList implements Iterable<MyThing> {

   private final CustomList sublist;

   private final MyThing thing;

   // getters and other methods
}

我有一个

Comparator<MyThing>

MyThing:

public class MyThing {

   private final IntArrayList values;
   // more members and methods
}

我想获得一个已排序的副本作为我的一个 CustomLists 的 CustomList(如果我不需要 Comparator 那不会是一个问题,但这就是我迄今为止解决它的方法)

到目前为止我所做的是:

  1. 将我的 CustomList 转换为列表
  2. 对该列表进行排序(使用比较器)
  3. 将其转移回 CustomList

这很好用,但我想知道是否有另一种(也许更优雅的方式)来实现我的目标。

【问题讨论】:

  • 什么是MyThing?它的字段和属性是什么?你的排序标准是什么?
  • 你能解释一下为什么你实现一个Iterable而不是扩展一些Collection吗?
  • 使用 Guava 的Ordering(扩展Comparator),你可以做到ordering.sortedCopy(iterable)。但这基本上完成了你已经在做的事情。
  • 优雅的方法是让你的类实现List 而不仅仅是Iterable。你为什么选择不这样做?
  • 我不认为目前建议的“重复”是真正的重复。第一个没有任何意义,第二个是关于对 Iterator 的元素进行排序,而不是对父 Iterable 本身做任何事情。

标签: java sorting iterable


【解决方案1】:

从 Iterable 创建一个 Stream,然后对 Stream 进行排序。

CustomList list = new CustomList();
Stream<MyThing> sorted = StreamSupport.stream(
        list.spliterator(), false)
    .sorted();

【讨论】:

    【解决方案2】:

    核心 Java 库不公开与 Iterable 一起使用的排序算法。

    内置将复制元素排序到临时数组。 (ArrayList 通过将其内部数组传递给排序函数对此进行了优化。)我建议对您当前方法的一个小改进是在Object[] 而不是List 之间来回复制元素。然后使用Arrays.sort() 而不是Collections.sort()。这样可以避免创建一个未真正使用的 List 对象。

    如果您想对自定义集合执行就地排序,您可以自己实现排序算法。这并不难,但更多的代码意味着更多的错误、更多的维护,并且您不会从与 JRE 捆绑在一起的改进中受益(比如从“MergeSort”移动到“TimSort”)。只有你能说好处是否值得。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-26
      相关资源
      最近更新 更多