Создание эффективного отсортированного Spliterator в Java 8 из массива

В Java 8 множество удобных утилит предназначены для создания эффективных разветвителей из массивов. Однако там не предусмотрены фабричные методы для сборки Spliterator с компаратором. Ясно, что сплитераторам разрешено иметь подключенные компараторы; у них есть метод getComparator() и свойство SORTED.

Как авторы библиотек должны создавать SORTED сплиттеры?


person Louis Wasserman    schedule 19.11.2013    source источник


Ответы (2)


Кажется, не предвидится такой 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.

person Holger    schedule 21.11.2013

Вы можете создать ORDERED Spliterator:

  • #P2# <блочная цитата> #P3# #P4#
  • #P5# <блочная цитата> #P6#
  • или (что и делает Arrays.spliterator) путем явного указания характеристик, таких как: Spliterators.spliterator(array, Spliterator.ORDERED);

Когда коллекция не связана с конкретным компаратором (или с массивами), имеет смысл выполнить сортировку перед «разбиением».

person assylias    schedule 19.11.2013