Eclipse Collections通过类似自定义比较器的函数对IntList进行排序而无需装箱

时间:2018-10-04 13:43:57

标签: java eclipse-collections

我正在尝试对几个(MutableIntList对象进行排序。将整数装箱/拆箱的成本在我的程序中是相关的(这正是我使用基本集合的原因)。我想按以下标准排序:

  • 所有负数先于非负数
  • 编号最小(最接近零)的数字

[1, 7, 0, -9, -3] -> [-3, -9, 0, 1, 7]

Eclipse Collections库中的IntList类是否有允许自定义比较器的排序方法?到目前为止,我还没有找到它,但是定义的符号列表很大,搜索框仅匹配精确的字符串,并且几乎不存在文档(我相信大多数是从方法签名自动生成的)。

我最后的选择是编写自己的int-int比较器和排序函数,这没什么大不了的,但我宁愿不要。

请不要浪费您的时间编写概念证明分类器,尽管我对此非常感激。.我知道如何对列表进行分类,我只是不知道如何找到Eclipse Collections文档中的内容。如果您可以提供帮助,请随时将其包含在您的答案中。

3 个答案:

答案 0 :(得分:3)

从 10.3 版开始,Eclipse Collections 中引入了对原始集合的间接排序支持。可变原始集合支持它。您可以在以下位置查看更多详细信息和使用示例 https://medium.com/javarevisited/eclipse-collections-now-supports-indirect-sorting-of-primitive-lists-e2447ca5dbc3

OP 示例如下所示:

@Test
public void soTest()
{
    // [1, 7, 0, -9, -3] -> [-3, -9, 0, 1, 7]
    MutableIntList list = IntLists.mutable.of(1, 7, 0, -9, -3);

    list.sortThis((a, b) -> {
        // negative before non-negative
        // otherwise, smallest numbers first
        if (a == b) { return 0; }
        if (a < 0 && b < 0) {
            return (a < b) ? 1 : -1;
        }
        return (a < b) ? -1 : 1;}
    );

    Assert.assertEquals(IntLists.immutable.of(-3, -9, 0, 1, 7), list);
}

比较器 lambda 可以简化为:

list.sortThis((a, b) ->
        (a < 0 && b < 0) ? Integer.compare(b, a) : Integer.compare(a, b));

答案 1 :(得分:1)

由于这里也没有“快速”答案,所以我继续自己实施了这种分拣设备。

public class IntListUtils {
    public interface IntIntComparator {
        int compare(int a, int b);
    }

    public static void sort(MutableIntList subject, IntIntComparator comparator) {
        quicksort(subject, 0, subject.size() - 1, comparator);
    }

    public static void quicksort(MutableIntList subject, int low, int high, IntIntComparator comparator) {
        if (low >= high) { return; }
        int pivot = partition(subject, low, high, comparator);
        quicksort(subject, low, pivot - 1, comparator);
        quicksort(subject, pivot, high, comparator);
    }

    private static int partition(MutableIntList subject, int low, int high, IntIntComparator comparator) {
        int pivot = subject.get(high);
        int i = low;
        for (int j = low; j <= high - 1; j++) {
            if (comparator.compare(subject.get(j), pivot) < 0) {
                int t = subject.get(i);
                subject.set(i, subject.get(j));
                subject.set(j, t);
                i += 1;
            }
        }
        int t = subject.get(i);
        subject.set(i, subject.get(high));
        subject.set(high, t);
        return i;
    }
}

可以将其用于如上所述的排序顺序:

MutableIntList list = ...;
IntListUtils.sort(list, (a, b) -> {
    // negative before non-negative
    // otherwise, smallest numbers first
    if (a == b) { return 0; }
    if (a < 0 && b < 0) {
        return (a < b) ? 1 : -1;
    }
    return (a < b) ? -1 : 1;
});

编辑:我知道这种快速排序并不是目前最快的排序方法,但是它所要做的比将我的整个IntList转换为List<Integer>并在排序后再分配回来要快得多。 O(n)内存(n大),而这种排序方法是就地发生的。

答案 2 :(得分:0)

IntList是MutableIntList和ImmutableIntList扩展的接口。

我看到有一个实现类,在这种情况下可以帮助您的是IntArrayList,它是MutableIntList的实现。

有一个正在执行的sortThis()方法

Arrays.sort(this.items,0,this.size);

因此,以您为例,它将返回-9,-3、0、1、7

但是我注意到您想要-3,-9、0、1、7。我不确定这是错字还是这是必需的。选中后,我们可以进一步讨论