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

org.jooq.lambda.SeqImpl Maven / Gradle / Ivy

Go to download

jOOλ is part of the jOOQ series (along with jOOQ, jOOX, jOOR, jOOU) providing some useful extensions to Java 8 lambdas.

There is a newer version: 0.9.15
Show newest version
/**
 * Copyright (c) 2014-2016, Data Geekery GmbH, [email protected]
 *
 * 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.jooq.lambda;

import static java.util.Comparator.naturalOrder;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.Spliterator;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;
import org.jooq.lambda.tuple.Tuple;

/**
 * @author Lukas Eder
 */
class SeqImpl implements Seq {

    static final Object               NULL = new Object();

    private final Stream stream;
    private Object[]                  buffered;

    SeqImpl(Stream stream) {
        this.stream = stream.sequential();
    }

    @SuppressWarnings("unchecked")
    @Override
    public Stream stream() {
        // This cast is safe as  in Stream is effectively declaration-site
        // covariant.
        return (Stream) (buffered == null ? stream : Stream.of(buffered));
    }

    @Override
    public Seq filter(Predicate predicate) {
        return Seq.seq(stream().filter(predicate));
    }

    @Override
    public  Seq map(Function mapper) {
        return Seq.seq(stream().map(mapper));
    }

    @Override
    public IntStream mapToInt(ToIntFunction mapper) {
        return stream().mapToInt(mapper);
    }

    @Override
    public LongStream mapToLong(ToLongFunction mapper) {
        return stream().mapToLong(mapper);
    }

    @Override
    public DoubleStream mapToDouble(ToDoubleFunction mapper) {
        return stream().mapToDouble(mapper);
    }

    @Override
    public  Seq flatMap(Function> mapper) {
        return Seq.seq(stream().flatMap(mapper));
    }

    @Override
    public IntStream flatMapToInt(Function mapper) {
        return stream().flatMapToInt(mapper);
    }

    @Override
    public LongStream flatMapToLong(Function mapper) {
        return stream().flatMapToLong(mapper);
    }

    @Override
    public DoubleStream flatMapToDouble(Function mapper) {
        return stream().flatMapToDouble(mapper);
    }

    @Override
    public Seq distinct() {
        return Seq.seq(stream().distinct());
    }

    @Override
    public Seq sorted() {
        return Seq.seq(stream().sorted());
    }

    @Override
    public Seq sorted(Comparator comparator) {
        return Seq.seq(stream().sorted(comparator));
    }

    @Override
    public Seq peek(Consumer action) {
        return Seq.seq(stream().peek(action));
    }

    @Override
    public Seq limit(long maxSize) {
        return Seq.seq(stream().limit(maxSize));
    }

    @Override
    public Seq skip(long n) {
        return Seq.seq(stream().skip(n));
    }

    @Override
    public void forEach(Consumer action) {
        stream().forEach(action);
    }

    @Override
    public void forEachOrdered(Consumer action) {
        stream().forEachOrdered(action);
    }

    @Override
    public Object[] toArray() {
        return stream().toArray();
    }

    @Override
    public  A[] toArray(IntFunction generator) {
        return stream().toArray(generator);
    }

    @Override
    public T reduce(T identity, BinaryOperator accumulator) {
        return stream().reduce(identity, accumulator);
    }

    @Override
    public Optional reduce(BinaryOperator accumulator) {
        return stream().reduce(accumulator);
    }

    @Override
    public  U reduce(U identity, BiFunction accumulator, BinaryOperator combiner) {
        return stream().reduce(identity, accumulator, combiner);
    }

    @Override
    public  R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner) {
        return stream().collect(supplier, accumulator, combiner);
    }

    @Override
    public  R collect(Collector collector) {
        return stream().collect(collector);
    }

    @Override
    public long count() {
        return stream().count();
    }

    @Override
    public long count(Predicate predicate) {
        return filter(predicate).count();
    }

    @Override
    public long countDistinct() {
        return collect(Agg.countDistinct());
    }

    @Override
    public long countDistinct(Predicate predicate) {
        return filter(predicate).countDistinct();
    }

    @Override
    public  long countDistinctBy(Function function) {
        return collect(Agg.countDistinctBy(function));
    }

    @Override
    public  long countDistinctBy(Function function, Predicate predicate) {
        return map(function).filter(predicate).countDistinct();
    }

    @Override
    public Optional sum() {
        return collect(Agg.sum());
    }

    @Override
    public  Optional sum(Function function) {
        return collect(Agg.sum(function));
    }

    @Override
    public int sumInt(ToIntFunction function) {
        return collect(Collectors.summingInt(function));
    }

    @Override
    public long sumLong(ToLongFunction function) {
        return collect(Collectors.summingLong(function));
    }

    @Override
    public double sumDouble(ToDoubleFunction function) {
        return collect(Collectors.summingDouble(function));
    }

    @Override
    public Optional avg() {
        return collect(Agg.avg());
    }

    @Override
    public  Optional avg(Function function) {
        return collect(Agg.avg(function));
    }

    @Override
    public double avgInt(ToIntFunction function) {
        return collect(Collectors.averagingInt(function));
    }

    @Override
    public double avgLong(ToLongFunction function) {
        return collect(Collectors.averagingLong(function));
    }

    @Override
    public double avgDouble(ToDoubleFunction function) {
        return collect(Collectors.averagingDouble(function));
    }

    @Override
    @SuppressWarnings("unchecked")
    public Optional min() {
        return min((Comparator) naturalOrder());
    }

    @Override
    public Optional min(Comparator comparator) {
        return stream().min(comparator);
    }

    @Override
    public > Optional min(Function function) {
        return collect(Agg.min(function));
    }

    @Override
    public  Optional min(Function function, Comparator comparator) {
        return collect(Agg.min(function, comparator));
    }

    @Override
    public > Optional minBy(Function function) {
        return collect(Agg.minBy(function));
    }

    @Override
    public  Optional minBy(Function function, Comparator comparator) {
        return collect(Agg.minBy(function, comparator));
    }

    @Override
    @SuppressWarnings("unchecked")
    public Seq minAll() {
        return minAll((Comparator) naturalOrder());
    }

    @Override
    public Seq minAll(Comparator comparator) {
        return collect(Agg.minAll(comparator));
    }

    @Override
    public > Seq minAll(Function function) {
        return collect(Agg.minAll(function));
    }

    @Override
    public  Seq minAll(Function function, Comparator comparator) {
        return collect(Agg.minAll(function, comparator));
    }

    @Override
    public > Seq minAllBy(Function function) {
        return collect(Agg.minAllBy(function));
    }

    @Override
    public  Seq minAllBy(Function function, Comparator comparator) {
        return collect(Agg.minAllBy(function, comparator));
    }

    @Override
    @SuppressWarnings("unchecked")
    public Optional max() {
        return max((Comparator) naturalOrder());
    }

    @Override
    public Optional max(Comparator comparator) {
        return stream().max(comparator);
    }

    @Override
    public > Optional max(Function function) {
        return collect(Agg.max(function));
    }

    @Override
    public  Optional max(Function function, Comparator comparator) {
        return collect(Agg.max(function, comparator));
    }

    @Override
    public > Optional maxBy(Function function) {
        return collect(Agg.maxBy(function));
    }

    @Override
    public  Optional maxBy(Function function, Comparator comparator) {
        return collect(Agg.maxBy(function, comparator));
    }

    @Override
    @SuppressWarnings("unchecked")
    public Seq maxAll() {
        return maxAll((Comparator) naturalOrder());
    }

    @Override
    public Seq maxAll(Comparator comparator) {
        return collect(Agg.maxAll(comparator));
    }

    @Override
    public > Seq maxAll(Function function) {
        return collect(Agg.maxAll(function));
    }

    @Override
    public  Seq maxAll(Function function, Comparator comparator) {
        return collect(Agg.maxAll(function, comparator));
    }

    @Override
    public > Seq maxAllBy(Function function) {
        return collect(Agg.maxAllBy(function));
    }

    @Override
    public  Seq maxAllBy(Function function, Comparator comparator) {
        return collect(Agg.maxAllBy(function, comparator));
    }

    @Override
    @SuppressWarnings("unchecked")
    public Optional median() {
        return median((Comparator) naturalOrder());
    }

    @Override
    public Optional median(Comparator comparator) {
        return collect(Agg.median(comparator));
    }

    @Override
    public > Optional medianBy(Function function) {
        return collect(Agg.medianBy(function));
    }

    @Override
    public  Optional medianBy(Function function, Comparator comparator) {
        return collect(Agg.medianBy(function, comparator));
    }

    @Override
    @SuppressWarnings("unchecked")
    public Optional percentile(double percentile) {
        return percentile(percentile, (Comparator) naturalOrder());
    }

    @Override
    public Optional percentile(double percentile, Comparator comparator) {
        return collect(Agg.percentile(percentile, comparator));
    }

    @Override
    public > Optional percentileBy(double percentile, Function function) {
        return collect(Agg.percentileBy(percentile, function));
    }

    @Override
    public  Optional percentileBy(double percentile, Function function, Comparator comparator) {
        return collect(Agg.percentileBy(percentile, function, comparator));
    }

    @Override
    public Optional mode() {
        return collect(Agg.mode());
    }

    @Override
    public  Optional modeBy(Function function) {
        return collect(Agg.modeBy(function));
    }

    @Override
    public Seq modeAll() {
        return collect(Agg.modeAll());
    }

    @Override
    public  Seq modeAllBy(Function function) {
        return collect(Agg.modeAllBy(function));
    }

    @Override
    public boolean anyMatch(Predicate predicate) {
        return stream().anyMatch(predicate);
    }

    @Override
    public boolean allMatch(Predicate predicate) {
        return stream().allMatch(predicate);
    }

    @Override
    public boolean noneMatch(Predicate predicate) {
        return stream().noneMatch(predicate);
    }

    @Override
    public Optional bitAnd() {
        return collect(Agg.bitAnd());
    }

    @Override
    public  Optional bitAnd(Function function) {
        return collect(Agg.bitAnd(function));
    }

    @Override
    public int bitAndInt(ToIntFunction function) {
        return collect(Agg.bitAndInt(function));
    }

    @Override
    public long bitAndLong(ToLongFunction function) {
        return collect(Agg.bitAndLong(function));
    }

    @Override
    public Optional bitOr() {
        return collect(Agg.bitOr());
    }

    @Override
    public  Optional bitOr(Function function) {
        return collect(Agg.bitOr(function));
    }

    @Override
    public int bitOrInt(ToIntFunction function) {
        return collect(Agg.bitOrInt(function));
    }

    @Override
    public long bitOrLong(ToLongFunction function) {
        return collect(Agg.bitOrLong(function));
    }

    @Override
    public Optional findFirst() {
        return stream().findFirst();
    }

    @Override
    public Optional findAny() {
        return stream().findAny();
    }

    @Override
    public Iterator iterator() {
        return stream().iterator();
    }

    @Override
    public Spliterator spliterator() {
        return stream().spliterator();
    }

    /**
     * Always returns false. Seq streams are always sequential and, as such,
     * doesn't support parallelization.
     *
     * @return false
     * @see jOOL Issue #130
     */
    @Override
    public boolean isParallel() {
        return false;
    }

    @Override
    public Seq onClose(Runnable closeHandler) {
        return Seq.seq(stream.onClose(closeHandler));
    }

    @Override
    public void close() {
        stream.close();
    }

    @Override
    public List toList() {
        return Seq.toList(this);
    }
    
    @Override
    public > L toList(Supplier factory) {
        return Seq.toCollection(this, factory);
    }

    @Override
    public Set toSet() {
        return Seq.toSet(this);
    }

    @Override
    public > S toSet(Supplier factory) {
        return Seq.toCollection(this, factory);
    }

    @Override
    public > C toCollection(Supplier factory) {
        return Seq.toCollection(this, factory);
    }
    
    @Override
    public  Map toMap(Function keyMapper, Function valueMapper) {
        return Seq.toMap(this, keyMapper, valueMapper);
    }

    @Override
    public  Map toMap(Function keyMapper) {
        return toMap(keyMapper, Function.identity());
    }

    @Override
    public String toString() {
        buffered = toArray();
        return Seq.toString(stream());
    }
    
    @Override
    public String toString(CharSequence delimiter) {
        return Seq.toString(this, delimiter);
    }

    @Override
    public String toString(CharSequence delimiter, CharSequence prefix, CharSequence suffix) {
        return map(Objects::toString).collect(Collectors.joining(delimiter, prefix, suffix));
    }

    @Override
    public String commonPrefix() {
        return map(Objects::toString).collect(Agg.commonPrefix());
    }

    @Override
    public String commonSuffix() {
        return map(Objects::toString).collect(Agg.commonSuffix());
    }

    @Override
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public String format() {
        final List strings = new ArrayList<>();
        Class[] types0 = null;
        
        for (T t : this) {
            Object[] array = t instanceof Tuple
                           ? ((Tuple) t).toArray()
                           : new Object[] { t };
            
            if (types0 == null) 
                types0 = new Class[array.length];
            
            for (int i = 0; i < array.length; i++)
                if (types0[i] == null && array[i] != null)
                    types0[i] = array[i].getClass();
            
            strings.add(Seq
                .of(array)
                .map(o -> 
                     o instanceof Optional
                   ? ((Optional) o).map(Objects::toString).orElse("{empty}")
                   : Objects.toString(o))
                .toArray(String[]::new));
        }
        
        if (strings.isEmpty())
            return "(empty seq)";
        
        final Class[] types = types0;
        final int length = types.length;
        final int[] maxLengths = new int[length];
        for (int s = 0; s < strings.size(); s++)
            for (int l = 0; l < length; l++)
                maxLengths[l] = Math.max(2, Math.max(maxLengths[l], strings.get(s)[l].length()));
        
        Function[] pad = IntStream
            .range(0, length)
            .mapToObj(i -> (Function) string -> {
                boolean number = Number.class.isAssignableFrom(types[i]);
                return Seq.seq(Collections.nCopies(maxLengths[i] - string.length(), " ")).toString("", number ? "" : string, number ? string : "");
            })
            .toArray(Function[]::new);
                
        StringBuilder separator = new StringBuilder("+-");
        for (int l = 0; l < length; l++) {
            if (l > 0)
                separator.append("-+-");
            
            for (int p = 0; p < maxLengths[l]; p++)
                separator.append('-');
        }
        separator.append("-+\n");
        
        StringBuilder result = new StringBuilder(separator).append("| ");
        for (int l = 0; l < length; l++) {
            String n = "v" + (l + 1);
            
            if (l > 0)
                result.append(" | ");
            
            result.append(pad[l].apply(n));
        }
        result.append(" |\n").append(separator);
        for (int s = 0; s < strings.size(); s++) {
            result.append("| ");
                    
            for (int l = 0; l < length; l++) {
                String string = strings.get(s)[l];
                
                if (l > 0)
                    result.append(" | ");
                
                result.append(pad[l].apply(string));
            }
            
            result.append(" |\n");
        }
        
        return result.append(separator).toString();
    }
}