从数组中生成高效的Java 8排序Spliterator

时间:2013-11-19 15:43:58

标签: java java-8 spliterator

在Java 8中,提供了各种convenient utilities来从阵列构建高效的Spliterator。但是,没有提供工厂方法来构建带有比较器的Spliterator。显然,Spliterators可以附加比较器;他们有getComparator()方法和SORTED属性。

图书馆作者如何构建SORTED Spliterators?

2 个答案:

答案 0 :(得分:8)

似乎没有预见到这样的Spliterator具有除自然之外的顺序。但实施它并不难。它看起来像这样:

class MyArraySpliterator implements Spliterator.OfInt {
    final int[] intArray;
    int pos;
    final int end;
    final Comparator<? super Integer> comp;

    MyArraySpliterator(int[] array, Comparator<? super Integer> c) {
        this(array, 0, array.length, c);
    }
    MyArraySpliterator(int[] array, int s, int e, Comparator<? super Integer> c) {
        intArray=array;
        pos=s;
        end=e;
        comp=c;
    }
    @Override
    public OfInt trySplit() {
        if(end-pos<64) return null;
        int mid=(pos+end)>>>1;
        return new MyArraySpliterator(intArray, pos, pos=mid, comp);
    }
    @Override
    public boolean tryAdvance(IntConsumer action) {
        Objects.requireNonNull(action);
        if(pos<end) {
            action.accept(intArray[pos++]);
            return true;
        }
        return false;
    }
    @Override
    public boolean tryAdvance(Consumer<? super Integer> action) {
        Objects.requireNonNull(action);
        if(pos<end) {
            action.accept(intArray[pos++]);
            return true;
        }
        return false;
    }
    @Override
    public long estimateSize() {
        return end-pos;
    }
    @Override
    public int characteristics() {
        return SIZED|SUBSIZED|SORTED|ORDERED|NONNULL;
    }
    @Override
    public Comparator<? super Integer> getComparator() {
        return comp;
    }
}

但Java 8还没有完全修复。也许在决赛中会有JRE提供的解决方案。

答案 1 :(得分:4)

您可以创建一个ORDERED Spliterator:

  • starting from a Collection与适当的iterator()

      

    如果相应的Collection.iterator()记录订单,则集合具有遭遇订单。如果是,则遇到订单与记录的订单相同。否则,集合没有遭遇订单。

    通常,TreeSet.spliterator#getComparator返回TreeSet的Comparator,但ArrayList.spliterator#getComparator返回null:顺序是通过递增索引。

  • 或者,如果您有数组,则使用Arrays帮助程序类中提供的新便捷方法,例如Arrays.spliterator(double[])

      

    分裂器报告Spliterator.SIZED,Spliterator.SUBSIZED,Spliterator.ORDERED和Spliterator.IMMUTABLE。

  • 通过明确提供特征来
  • 或(这是Arrays.spliterator所做的),例如:Spliterators.spliterator(array, Spliterator.ORDERED);

当集合与特定的比较器(或数组)没有关联时,在“分裂”之前进行排序是有意义的。