
org.paumard.spliterators.TraversingSpliterator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of streams-utils Show documentation
Show all versions of streams-utils Show documentation
Streams Utils is a set of operations written on Java 8 Streams. It allows several basic operations that
are not available in the the Java 8, and that have proven to be very useful in some cases.
/*
* Copyright (C) 2015 José Paumard
*
* 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 org.paumard.spliterators;
import org.paumard.streams.StreamsUtils;
import java.util.Objects;
import java.util.Spliterator;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import java.util.stream.Stream;
/**
* See the documentation and patterns to be used in this class in the {@link StreamsUtils} factory class.
*
* Created by José
*/
public class TraversingSpliterator implements Spliterator> {
private final Spliterator[] spliterators;
private final AtomicBoolean firstGroup = new AtomicBoolean(true);
@SafeVarargs
public static TraversingSpliterator of(Spliterator... spliterators) {
Objects.requireNonNull(spliterators);
if (spliterators.length < 2) {
throw new IllegalArgumentException ("Why would you want to traverse less than two streams?");
}
if (Stream.of(spliterators).mapToInt(Spliterator::characteristics).reduce(Spliterator.ORDERED, (i1, i2) -> i1 & i2) == 0) {
throw new IllegalArgumentException ("Why would you want to traverse non ordered spliterators?");
}
return new TraversingSpliterator<>(spliterators);
}
@SafeVarargs
private TraversingSpliterator(Spliterator... spliterators) {
this.spliterators = spliterators;
}
@Override
public boolean tryAdvance(Consumer super Stream> action) {
Stream.Builder builder = Stream.builder();
boolean hasMore = true;
for (Spliterator spliterator : spliterators) {
hasMore &= spliterator.tryAdvance(builder::add);
}
if (hasMore) {
action.accept(builder.build());
firstGroup.getAndSet(false);
}
if (!hasMore && firstGroup.getAndSet(false))
action.accept(Stream.empty());
return hasMore;
}
@Override
public Spliterator> trySplit() {
@SuppressWarnings("unchecked")
TraversingSpliterator[] spliterators =
Stream.of(this.spliterators).map(Spliterator::trySplit).toArray(TraversingSpliterator[]::new);
return new TraversingSpliterator<>((Spliterator[]) spliterators);
}
@Override
public long estimateSize() {
return Stream.of(spliterators).mapToLong(Spliterator::estimateSize).min().getAsLong();
}
@Override
public int characteristics() {
return Stream.of(spliterators).mapToInt(Spliterator::characteristics).reduce(0xFFFFFFFF, (i1, i2) -> i1 & i2);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy