aQute.lib.collections.Iterables Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of biz.aQute.bnd.runtime.snapshot Show documentation
Show all versions of biz.aQute.bnd.runtime.snapshot Show documentation
biz.aQute.bnd.runtime.snapshot
The newest version!
package aQute.lib.collections;
import static java.util.Collections.emptyEnumeration;
import static java.util.Objects.requireNonNull;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.Spliterator;
import java.util.Spliterators.AbstractSpliterator;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
public class Iterables {
private Iterables() {}
final static class Distinct implements Iterable {
private final Set extends T> first;
private final Iterable extends T> second;
private final Function super T, ? extends R> mapper;
private final Predicate super R> filter;
Distinct(Set extends T> first, Iterable extends T> second, Function super T, ? extends R> mapper,
Predicate super R> filter) {
this.first = requireNonNull(first);
this.second = requireNonNull(second);
this.mapper = requireNonNull(mapper);
this.filter = requireNonNull(filter);
}
@Override
public void forEach(Consumer super R> action) {
requireNonNull(action);
for (T t : first) {
R r = mapper.apply(t);
if (filter.test(r)) {
action.accept(r);
}
}
for (T t : second) {
R r = mapper.apply(t);
if (filter.test(r) && !first.contains(t)) {
action.accept(r);
}
}
}
@Override
public Iterator iterator() {
return new DistinctIterator();
}
final class DistinctIterator implements Iterator {
private final Iterator extends T> it1;
private final Iterator extends T> it2;
private boolean hasNext = false;
private R next;
DistinctIterator() {
this.it1 = first.iterator();
this.it2 = second.iterator();
}
@Override
public boolean hasNext() {
if (hasNext) {
return true;
}
while (it1.hasNext()) {
T t = it1.next();
R r = mapper.apply(t);
if (filter.test(r)) {
next = r;
return hasNext = true;
}
}
while (it2.hasNext()) {
T t = it2.next();
R r = mapper.apply(t);
if (filter.test(r) && !first.contains(t)) {
next = r;
return hasNext = true;
}
}
return false;
}
@Override
public R next() {
if (hasNext()) {
R r = next;
hasNext = false;
return r;
}
throw new NoSuchElementException();
}
@Override
public void forEachRemaining(Consumer super R> action) {
requireNonNull(action);
if (hasNext) {
R r = next;
action.accept(r);
hasNext = false;
}
while (it1.hasNext()) {
T t = it1.next();
R r = mapper.apply(t);
if (filter.test(r)) {
action.accept(r);
}
}
while (it2.hasNext()) {
T t = it2.next();
R r = mapper.apply(t);
if (filter.test(r) && !first.contains(t)) {
action.accept(r);
}
}
}
}
@Override
public Spliterator spliterator() {
return new DistinctSpliterator();
}
final class DistinctSpliterator extends AbstractSpliterator implements Consumer {
private Spliterator extends T> it2;
private Spliterator extends T> it1;
private T t;
DistinctSpliterator() {
super(Long.MAX_VALUE, Spliterator.DISTINCT | Spliterator.ORDERED);
}
private Spliterator extends T> first() {
Spliterator extends T> spliterator = it1;
if (spliterator != null) {
return spliterator;
}
return it1 = first.spliterator();
}
private Spliterator extends T> second() {
Spliterator extends T> spliterator = it2;
if (spliterator != null) {
return spliterator;
}
return it2 = second.spliterator();
}
@Override
public boolean tryAdvance(Consumer super R> action) {
requireNonNull(action);
for (Spliterator extends T> spliterator = first(); spliterator.tryAdvance(this);) {
R r = mapper.apply(t);
if (filter.test(r)) {
action.accept(r);
return true;
}
}
for (Spliterator extends T> spliterator = second(); spliterator.tryAdvance(this);) {
R r = mapper.apply(t);
if (filter.test(r) && !first.contains(t)) {
action.accept(r);
return true;
}
}
return false;
}
@Override
public void forEachRemaining(Consumer super R> action) {
requireNonNull(action);
first().forEachRemaining((T t) -> {
R r = mapper.apply(t);
if (filter.test(r)) {
action.accept(r);
}
});
second().forEachRemaining((T t) -> {
R r = mapper.apply(t);
if (filter.test(r) && !first.contains(t)) {
action.accept(r);
}
});
}
@Override
public long estimateSize() {
long est = first().estimateSize() + second().estimateSize();
if (est < 0L) {
return super.estimateSize();
}
return est;
}
@Override
public void accept(T t) {
this.t = t;
}
}
}
public static Iterable distinct(Set extends T> first, Iterable extends T> second) {
return new Distinct<>(first, second, t -> t, t -> true);
}
public static Iterable distinct(Set extends T> first, Iterable extends T> second,
Function super T, ? extends R> mapper) {
return new Distinct<>(first, second, mapper, r -> true);
}
public static Iterable distinct(Set extends T> first, Iterable extends T> second,
Function super T, ? extends R> mapper, Predicate super R> filter) {
return new Distinct<>(first, second, mapper, filter);
}
final static class IterableEnumeration implements Iterable {
private final Enumeration extends T> enumeration;
private final Function super T, ? extends R> mapper;
private final Predicate super R> filter;
private final AtomicBoolean consume = new AtomicBoolean();
IterableEnumeration(Enumeration extends T> enumeration, Function super T, ? extends R> mapper,
Predicate super R> filter) {
this.enumeration = enumeration != null ? enumeration : emptyEnumeration();
this.mapper = requireNonNull(mapper);
this.filter = requireNonNull(filter);
}
private void consume() {
if (consume.compareAndSet(false, true)) {
return;
}
throw new IllegalStateException("enumeration already consumed");
}
@Override
public void forEach(Consumer super R> action) {
requireNonNull(action);
consume();
while (enumeration.hasMoreElements()) {
T t = enumeration.nextElement();
R r = mapper.apply(t);
if (filter.test(r)) {
action.accept(r);
}
}
}
@Override
public Iterator iterator() {
consume();
return new EnumerationIterator();
}
final class EnumerationIterator implements Iterator {
private boolean hasNext = false;
private R next;
EnumerationIterator() {}
@Override
public boolean hasNext() {
if (hasNext) {
return true;
}
while (enumeration.hasMoreElements()) {
T t = enumeration.nextElement();
R r = mapper.apply(t);
if (filter.test(r)) {
next = r;
return hasNext = true;
}
}
return false;
}
@Override
public R next() {
if (hasNext()) {
R r = next;
hasNext = false;
return r;
}
throw new NoSuchElementException();
}
@Override
public void forEachRemaining(Consumer super R> action) {
requireNonNull(action);
if (hasNext) {
R r = next;
action.accept(r);
hasNext = false;
}
while (enumeration.hasMoreElements()) {
T t = enumeration.nextElement();
R r = mapper.apply(t);
if (filter.test(r)) {
action.accept(r);
}
}
}
}
@Override
public Spliterator spliterator() {
consume();
return new EnumerationSpliterator();
}
final class EnumerationSpliterator extends AbstractSpliterator {
EnumerationSpliterator() {
super(Long.MAX_VALUE, Spliterator.ORDERED);
}
@Override
public boolean tryAdvance(Consumer super R> action) {
requireNonNull(action);
while (enumeration.hasMoreElements()) {
T t = enumeration.nextElement();
R r = mapper.apply(t);
if (filter.test(r)) {
action.accept(r);
return true;
}
}
return false;
}
@Override
public void forEachRemaining(Consumer super R> action) {
requireNonNull(action);
while (enumeration.hasMoreElements()) {
T t = enumeration.nextElement();
R r = mapper.apply(t);
if (filter.test(r)) {
action.accept(r);
}
}
}
}
}
public static Iterable iterable(Enumeration extends T> enumeration) {
return new IterableEnumeration<>(enumeration, t -> t, t -> true);
}
public static Iterable iterable(Enumeration extends T> enumeration,
Function super T, ? extends R> mapper) {
return new IterableEnumeration<>(enumeration, mapper, r -> true);
}
public static Iterable iterable(Enumeration extends T> enumeration,
Function super T, ? extends R> mapper, Predicate super R> filter) {
return new IterableEnumeration<>(enumeration, mapper, filter);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy