All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.slimgears.util.stream.Streams Maven / Gradle / Ivy

There is a newer version: 0.7.58
Show newest version
package com.slimgears.util.stream;

import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

@SuppressWarnings("WeakerAccess")
public class Streams {
    public static  Stream> toBatch(Stream source, int batchSize) {
        Spliterator> batchSpliterator = batch(source.spliterator(), batchSize);
        return StreamSupport.stream(batchSpliterator, false)
                .map(spliterator -> StreamSupport.stream(spliterator, false));
    }

    public static  Stream ofType(Class clazz, Stream source) {
        return source.filter(clazz::isInstance).map(clazz::cast);
    }

    public static  Function> ofType(Class clazz) {
        return item -> ofType(clazz, Stream.of(item));
    }

    public static  Function self() {
        return s -> s;
    }

    public static  Stream takeWhile(Stream stream, Predicate predicate) {
        return StreamSupport.stream(takeWhile(stream.spliterator(), predicate), false);
    }

    public static  Stream fromIterator(Iterator iterator) {
        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
    }

    public static  Stream fromIterable(Iterable iterable) {
        return fromIterator(iterable.iterator());
    }

    public static  Stream fromEnumeration(Enumeration enumeration) {
        return StreamSupport.stream(
                new Spliterators.AbstractSpliterator(Long.MAX_VALUE, Spliterator.ORDERED) {
                    public boolean tryAdvance(Consumer action) {
                        if(enumeration.hasMoreElements()) {
                            action.accept(enumeration.nextElement());
                            return true;
                        }
                        return false;
                    }
                    public void forEachRemaining(Consumer action) {
                        while(enumeration.hasMoreElements()) action.accept(enumeration.nextElement());
                    }
                }, false);
    }

    public static  Stream orderByTopology(Stream source, Function> childrenGetter) {
        return orderByTopology(source, childrenGetter, new HashSet<>());
    }

    private static  Stream orderByTopology(Stream source, Function> childrenGetter, Set visited) {
        return source
                .filter(visited::add)
                .flatMap(val -> Stream.concat(orderByTopology(childrenGetter.apply(val), childrenGetter, visited), Stream.of(val)));
    }

    private static  Spliterator takeWhile(Spliterator spliterator, Predicate predicate) {
        return new Spliterators.AbstractSpliterator(spliterator.estimateSize(), 0) {
            private boolean finished = false;

            @Override
            public boolean tryAdvance(Consumer action) {
                return spliterator.tryAdvance(item -> {
                    if (predicate.test(item)) {
                        action.accept(item);
                    } else {
                        finished = true;
                    }
                }) && !finished;
            }
        };
    }

    static class LimitedSpliterator extends Spliterators.AbstractSpliterator {
        private final Spliterator source;
        private final AtomicInteger remaining;
        private final AtomicBoolean finished = new AtomicBoolean(false);

        LimitedSpliterator(Spliterator source, int maxSize) {
            super(maxSize, 0);
            this.source = source;
            this.remaining = new AtomicInteger(maxSize);
        }

        @Override
        public boolean tryAdvance(Consumer action) {
            if (remaining.decrementAndGet() == 0) {
                return false;
            }
            finished.set(source.tryAdvance(action));
            return finished.get();
        }
    }

    private static  Spliterator> batch(Spliterator source, int batchSize) {
        return new Spliterators.AbstractSpliterator>(source.estimateSize() / batchSize, 0) {
            @Override
            public boolean tryAdvance(Consumer> action) {
                LimitedSpliterator spliterator = new LimitedSpliterator<>(source, batchSize);
                action.accept(spliterator);
                return !spliterator.finished.get();
            }
        };
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy