one.util.streamex.RangeBasedSpliterator Maven / Gradle / Ivy
/*
* Copyright 2015, 2016 Tagir Valeev
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package one.util.streamex;
import java.util.List;
import java.util.Map.Entry;
import java.util.Spliterator;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.DoubleBinaryOperator;
import java.util.function.DoubleConsumer;
import java.util.function.IntBinaryOperator;
import java.util.function.IntConsumer;
import java.util.function.LongBinaryOperator;
import java.util.function.LongConsumer;
import static one.util.streamex.StreamExInternals.*;
/**
* @author Tagir Valeev
*/
/* package */abstract class RangeBasedSpliterator> extends CloneableSpliterator {
int cur;
int limit;
public RangeBasedSpliterator(int fromInclusive, int toExclusive) {
this.cur = fromInclusive;
this.limit = toExclusive;
}
@Override
public long estimateSize() {
return limit - cur;
}
@Override
public int characteristics() {
return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
}
@Override
public S trySplit() {
int size = limit - cur;
if (size >= 2) {
S clone = doClone();
clone.limit = this.cur = this.cur + size / 2;
return clone;
}
return null;
}
static final class AsEntry extends RangeBasedSpliterator, AsEntry> {
private final List list;
public AsEntry(List list) {
super(0, list.size());
this.list = list;
}
@Override
public boolean tryAdvance(Consumer super Entry> action) {
if (cur < limit) {
action.accept(new ObjIntBox<>(list.get(cur), cur));
cur++;
return true;
}
return false;
}
@Override
public void forEachRemaining(Consumer super Entry> action) {
int l = limit, c = cur;
List list = this.list;
while (c < l) {
action.accept(new ObjIntBox<>(list.get(c), c));
c++;
}
cur = limit;
}
}
static final class OfSubLists extends RangeBasedSpliterator, OfSubLists> {
private final List source;
private final int length;
private final int shift;
private final int listSize;
public OfSubLists(List source, int length, int shift) {
super(0, Math.max(0, source.size() - Math.max(length - shift, 0) - 1) / shift + 1);
this.source = source;
this.listSize = source.size();
this.shift = shift;
this.length = length;
}
@Override
public boolean tryAdvance(Consumer super List> action) {
if (cur < limit) {
int start = cur * shift;
int stop = listSize - length > start ? start + length : listSize;
action.accept(source.subList(start, stop));
cur++;
return true;
}
return false;
}
@Override
public void forEachRemaining(Consumer super List> action) {
int l = limit, c = cur, ll = length, sf = shift, ls = listSize;
int start = cur * sf;
while (c < l) {
int stop = ls - ll > start ? start + ll : ls;
action.accept(source.subList(start, stop));
start += sf;
c++;
}
cur = limit;
}
}
static final class ZipRef extends RangeBasedSpliterator> {
private final List l1;
private final List l2;
private final BiFunction super U, ? super V, ? extends T> mapper;
public ZipRef(int fromInclusive, int toExclusive, BiFunction super U, ? super V, ? extends T> mapper,
List l1, List l2) {
super(fromInclusive, toExclusive);
this.l1 = l1;
this.l2 = l2;
this.mapper = mapper;
}
@Override
public boolean tryAdvance(Consumer super T> action) {
if (cur < limit) {
action.accept(mapper.apply(l1.get(cur), l2.get(cur)));
cur++;
return true;
}
return false;
}
@Override
public void forEachRemaining(Consumer super T> action) {
int l = limit, c = cur;
while (c < l) {
action.accept(mapper.apply(l1.get(c), l2.get(c)));
c++;
}
cur = limit;
}
}
static final class ZipInt extends RangeBasedSpliterator implements Spliterator.OfInt {
private final IntBinaryOperator mapper;
private final int[] arr1, arr2;
public ZipInt(int fromInclusive, int toExclusive, IntBinaryOperator mapper, int[] arr1, int[] arr2) {
super(fromInclusive, toExclusive);
this.mapper = mapper;
this.arr1 = arr1;
this.arr2 = arr2;
}
@Override
public boolean tryAdvance(IntConsumer action) {
if (cur < limit) {
action.accept(mapper.applyAsInt(arr1[cur], arr2[cur]));
cur++;
return true;
}
return false;
}
@Override
public void forEachRemaining(IntConsumer action) {
int l = limit, c = cur;
while (c < l) {
action.accept(mapper.applyAsInt(arr1[c], arr2[c]));
c++;
}
cur = limit;
}
}
static final class OfByte extends RangeBasedSpliterator implements Spliterator.OfInt {
private final byte[] array;
public OfByte(int fromInclusive, int toExclusive, byte[] array) {
super(fromInclusive, toExclusive);
this.array = array;
}
@Override
public boolean tryAdvance(IntConsumer action) {
if (cur < limit) {
action.accept(array[cur]);
cur++;
return true;
}
return false;
}
@Override
public void forEachRemaining(IntConsumer action) {
int l = limit, c = cur;
while (c < l) {
action.accept(array[c++]);
}
cur = limit;
}
}
static final class OfChar extends RangeBasedSpliterator implements Spliterator.OfInt {
private final char[] array;
public OfChar(int fromInclusive, int toExclusive, char[] array) {
super(fromInclusive, toExclusive);
this.array = array;
}
@Override
public boolean tryAdvance(IntConsumer action) {
if (cur < limit) {
action.accept(array[cur]);
cur++;
return true;
}
return false;
}
@Override
public void forEachRemaining(IntConsumer action) {
int l = limit, c = cur;
while (c < l) {
action.accept(array[c++]);
}
cur = limit;
}
}
static final class OfShort extends RangeBasedSpliterator implements Spliterator.OfInt {
private final short[] array;
public OfShort(int fromInclusive, int toExclusive, short[] array) {
super(fromInclusive, toExclusive);
this.array = array;
}
@Override
public boolean tryAdvance(IntConsumer action) {
if (cur < limit) {
action.accept(array[cur]);
cur++;
return true;
}
return false;
}
@Override
public void forEachRemaining(IntConsumer action) {
int l = limit, c = cur;
while (c < l) {
action.accept(array[c++]);
}
cur = limit;
}
}
static final class ZipLong extends RangeBasedSpliterator implements Spliterator.OfLong {
private final LongBinaryOperator mapper;
private final long[] arr1, arr2;
public ZipLong(int fromInclusive, int toExclusive, LongBinaryOperator mapper, long[] arr1, long[] arr2) {
super(fromInclusive, toExclusive);
this.mapper = mapper;
this.arr1 = arr1;
this.arr2 = arr2;
}
@Override
public boolean tryAdvance(LongConsumer action) {
if (cur < limit) {
action.accept(mapper.applyAsLong(arr1[cur], arr2[cur]));
cur++;
return true;
}
return false;
}
@Override
public void forEachRemaining(LongConsumer action) {
int l = limit, c = cur;
while (c < l) {
action.accept(mapper.applyAsLong(arr1[c], arr2[c]));
c++;
}
cur = limit;
}
}
static final class OfFloat extends RangeBasedSpliterator implements Spliterator.OfDouble {
private final float[] array;
public OfFloat(int fromInclusive, int toExclusive, float[] array) {
super(fromInclusive, toExclusive);
this.array = array;
}
@Override
public boolean tryAdvance(DoubleConsumer action) {
if (cur < limit) {
action.accept(array[cur]);
cur++;
return true;
}
return false;
}
@Override
public void forEachRemaining(DoubleConsumer action) {
int l = limit, c = cur;
while (c < l) {
action.accept(array[c++]);
}
cur = limit;
}
}
static final class ZipDouble extends RangeBasedSpliterator implements Spliterator.OfDouble {
private final DoubleBinaryOperator mapper;
private final double[] arr1, arr2;
public ZipDouble(int fromInclusive, int toExclusive, DoubleBinaryOperator mapper, double[] arr1, double[] arr2) {
super(fromInclusive, toExclusive);
this.mapper = mapper;
this.arr1 = arr1;
this.arr2 = arr2;
}
@Override
public boolean tryAdvance(DoubleConsumer action) {
if (cur < limit) {
action.accept(mapper.applyAsDouble(arr1[cur], arr2[cur]));
cur++;
return true;
}
return false;
}
@Override
public void forEachRemaining(DoubleConsumer action) {
int l = limit, c = cur;
while (c < l) {
action.accept(mapper.applyAsDouble(arr1[c], arr2[c]));
c++;
}
cur = limit;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy