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

com.landawn.abacus.util.stream.EntryStream Maven / Gradle / Ivy

There is a newer version: 1.10.1
Show newest version
/*
 * Copyright (C) 2016, 2017, 2018, 2019 HaiYang Li
 *
 * 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 com.landawn.abacus.util.stream;

import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.Executor;

import com.landawn.abacus.annotation.Beta;
import com.landawn.abacus.annotation.ParallelSupported;
import com.landawn.abacus.annotation.SequentialOnly;
import com.landawn.abacus.util.AsyncExecutor;
import com.landawn.abacus.util.BiIterator;
import com.landawn.abacus.util.Comparators;
import com.landawn.abacus.util.Fn;
import com.landawn.abacus.util.ImmutableEntry;
import com.landawn.abacus.util.ImmutableMap;
import com.landawn.abacus.util.Joiner;
import com.landawn.abacus.util.ListMultimap;
import com.landawn.abacus.util.LongMultiset;
import com.landawn.abacus.util.Multimap;
import com.landawn.abacus.util.Multiset;
import com.landawn.abacus.util.N;
import com.landawn.abacus.util.NoCachingNoUpdating;
import com.landawn.abacus.util.NoCachingNoUpdating.DisposableEntry;
import com.landawn.abacus.util.Nth;
import com.landawn.abacus.util.ObjIterator;
import com.landawn.abacus.util.Pair;
import com.landawn.abacus.util.Try;
import com.landawn.abacus.util.u.Optional;
import com.landawn.abacus.util.function.BiConsumer;
import com.landawn.abacus.util.function.BiFunction;
import com.landawn.abacus.util.function.BiPredicate;
import com.landawn.abacus.util.function.BinaryOperator;
import com.landawn.abacus.util.function.BooleanSupplier;
import com.landawn.abacus.util.function.Consumer;
import com.landawn.abacus.util.function.Function;
import com.landawn.abacus.util.function.Predicate;
import com.landawn.abacus.util.function.Supplier;
import com.landawn.abacus.util.function.ToDoubleFunction;
import com.landawn.abacus.util.function.ToIntFunction;
import com.landawn.abacus.util.function.ToLongFunction;
import com.landawn.abacus.util.stream.BaseStream.Splitor;

/** 
 * The Stream will be automatically closed after execution(A terminal method is executed/triggered).
 * 
 */
public final class EntryStream implements AutoCloseable {

    private static final Function, Stream>> mapper_func = new Function, Stream>>() {
        @Override
        public Stream> apply(Map t) {
            return Stream.of(t);
        }
    };

    final Map m;
    final Stream> s;

    EntryStream(final Stream> s) {
        this(null, s);
    }

    EntryStream(final Map m, final Stream> s) {
        this.m = m;
        this.s = (Stream>) s;
    }

    public Stream keys() {
        if (m != null) {
            return Stream.of(m.keySet());
        }

        final Function, K> func = Fn.key();

        return s.map(func);
    }

    public Stream values() {
        if (m != null) {
            return Stream.of(m.values());
        }

        final Function, V> func = Fn.value();

        return s.map(func);
    }

    public Stream> entries() {
        return s;
    }

    @ParallelSupported
    public EntryStream inversed() {
        final Function, Map.Entry> mapper = Fn.inverse();

        return map(mapper);
    }

    /**
     * Returns a stream consisting of the elements of this stream which keys are
     * instances of given class.
     *
     * 

* This is an intermediate * operation. * * @param a type of keys to select. * @param clazz a class to filter the keys. * @return the new stream */ @SuppressWarnings({ "unchecked" }) @SequentialOnly public EntryStream selectByKey(Class clazz) { if (isParallel()) { return (EntryStream) sequential().filterByKey(Fn.instanceOf(clazz)).parallel(maxThreadNum(), splitor()); } else { return (EntryStream) filterByKey(Fn.instanceOf(clazz)); } } /** * Returns a stream consisting of the elements of this stream which values * are instances of given class. * *

* This is an intermediate * operation. * * @param a type of values to select. * @param clazz a class to filter the values. * @return the new stream */ @SuppressWarnings({ "unchecked" }) @SequentialOnly public EntryStream selectByValue(Class clazz) { if (isParallel()) { return (EntryStream) sequential().filterByValue(Fn.instanceOf(clazz)).parallel(maxThreadNum(), splitor()); } else { return (EntryStream) filterByValue(Fn.instanceOf(clazz)); } } @ParallelSupported public EntryStream filter(final Predicate> predicate) { return of(s.filter(predicate)); } @ParallelSupported public EntryStream filter(final BiPredicate predicate) { return of(s.filter(Fn.Entries.p(predicate))); } @ParallelSupported public EntryStream filterByKey(final Predicate keyPredicate) { final Predicate> predicate = Fn.testByKey(keyPredicate); return of(s.filter(predicate)); } @ParallelSupported public EntryStream filterByValue(final Predicate valuePredicate) { final Predicate> predicate = Fn.testByValue(valuePredicate); return of(s.filter(predicate)); } @ParallelSupported public EntryStream removeIf(final Predicate> predicate) { return of(s.removeIf(predicate)); } @ParallelSupported public EntryStream removeIf(final BiPredicate predicate) { return of(s.removeIf(Fn.Entries.p(predicate))); } @ParallelSupported public EntryStream takeWhile(final Predicate> predicate) { return of(s.takeWhile(predicate)); } @ParallelSupported public EntryStream takeWhile(final BiPredicate predicate) { return of(s.takeWhile(Fn.Entries.p(predicate))); } @ParallelSupported public EntryStream dropWhile(final Predicate> predicate) { return of(s.dropWhile(predicate)); } @ParallelSupported public EntryStream dropWhile(final BiPredicate predicate) { return of(s.dropWhile(Fn.Entries.p(predicate))); } @ParallelSupported public EntryStream map(final Function, ? extends Map.Entry> mapper) { return s.mapToEntry(mapper); } @ParallelSupported public EntryStream map(final Function, ? extends KK> keyMapper, final Function, ? extends VV> valueMapper) { return s.mapToEntry(keyMapper, valueMapper); } @ParallelSupported public EntryStream map(final BiFunction> mapper) { return map(Fn.Entries.f(mapper)); } @ParallelSupported public EntryStream map(final BiFunction keyMapper, final BiFunction valueMapper) { final Function, Map.Entry> mapper = new Function, Map.Entry>() { @Override public Entry apply(Entry t) { return new SimpleImmutableEntry(keyMapper.apply(t.getKey(), t.getValue()), valueMapper.apply(t.getKey(), t.getValue())); } }; return map(mapper); } @ParallelSupported public EntryStream mapKey(final Function keyMapper) { final Function, Map.Entry> mapper = Fn.mapKey(keyMapper); return map(mapper); } @ParallelSupported public EntryStream mapKey(final BiFunction keyMapper) { final Function, Map.Entry> mapper = new Function, Map.Entry>() { @Override public Entry apply(Entry entry) { return new SimpleImmutableEntry(keyMapper.apply(entry.getKey(), entry.getValue()), entry.getValue()); } }; return map(mapper); } @ParallelSupported public EntryStream mapValue(final Function valueMapper) { final Function, Map.Entry> mapper = Fn.mapValue(valueMapper); return map(mapper); } @ParallelSupported public EntryStream mapValue(final BiFunction keyMapper) { final Function, Map.Entry> mapper = new Function, Map.Entry>() { @Override public Entry apply(Entry entry) { return new SimpleImmutableEntry(entry.getKey(), keyMapper.apply(entry.getKey(), entry.getValue())); } }; return map(mapper); } @ParallelSupported public EntryStream flatMap(final Function, ? extends EntryStream> mapper) { return s.flatMappToEntry(mapper); } @ParallelSupported public EntryStream flatMap(final BiFunction> mapper) { return flatMap(Fn.Entries.f(mapper)); } @ParallelSupported public EntryStream flattMap( final Function, ? extends Stream>> mapper) { return s.flatMapToEntry(mapper); } @ParallelSupported public EntryStream flattMap( final BiFunction>> mapper) { return flattMap(Fn.Entries.f(mapper)); } @ParallelSupported public EntryStream flatMapp(final Function, ? extends Map> mapper) { return s.flattMapToEntry(mapper); } @ParallelSupported public EntryStream flatMapp(final BiFunction> mapper) { return flatMapp(Fn.Entries.f(mapper)); } @ParallelSupported public EntryStream flatMapKey(final Function> keyMapper) { final Function, Stream>> mapper2 = new Function, Stream>>() { @Override public Stream> apply(final Map.Entry e) { return keyMapper.apply(e.getKey()).map(new Function>() { @Override public Map.Entry apply(KK kk) { return new SimpleImmutableEntry<>(kk, e.getValue()); } }); } }; return flattMap(mapper2); } @ParallelSupported public EntryStream flatMapKey(final BiFunction> keyMapper) { final Function, Stream>> mapper2 = new Function, Stream>>() { @Override public Stream> apply(final Map.Entry e) { return keyMapper.apply(e.getKey(), e.getValue()).map(new Function>() { @Override public Map.Entry apply(KK kk) { return new SimpleImmutableEntry<>(kk, e.getValue()); } }); } }; return flattMap(mapper2); } @ParallelSupported public EntryStream flattMapKey(final Function> keyMapper) { final Function, Stream>> mapper2 = new Function, Stream>>() { @Override public Stream> apply(final Map.Entry e) { return Stream.of(keyMapper.apply(e.getKey())).map(new Function>() { @Override public Map.Entry apply(KK kk) { return new SimpleImmutableEntry<>(kk, e.getValue()); } }); } }; return flattMap(mapper2); } @ParallelSupported public EntryStream flattMapKey(final BiFunction> keyMapper) { final Function, Stream>> mapper2 = new Function, Stream>>() { @Override public Stream> apply(final Map.Entry e) { return Stream.of(keyMapper.apply(e.getKey(), e.getValue())).map(new Function>() { @Override public Map.Entry apply(KK kk) { return new SimpleImmutableEntry<>(kk, e.getValue()); } }); } }; return flattMap(mapper2); } @ParallelSupported public EntryStream flatMapValue(final Function> valueMapper) { final Function, Stream>> mapper2 = new Function, Stream>>() { @Override public Stream> apply(final Entry e) { return valueMapper.apply(e.getValue()).map(new Function>() { @Override public Map.Entry apply(VV vv) { return new SimpleImmutableEntry<>(e.getKey(), vv); } }); } }; return flattMap(mapper2); } @ParallelSupported public EntryStream flatMapValue(final BiFunction> valueMapper) { final Function, Stream>> mapper2 = new Function, Stream>>() { @Override public Stream> apply(final Entry e) { return valueMapper.apply(e.getKey(), e.getValue()).map(new Function>() { @Override public Map.Entry apply(VV vv) { return new SimpleImmutableEntry<>(e.getKey(), vv); } }); } }; return flattMap(mapper2); } @ParallelSupported public EntryStream flattMapValue(final Function> valueMapper) { final Function, Stream>> mapper2 = new Function, Stream>>() { @Override public Stream> apply(final Entry e) { return Stream.of(valueMapper.apply(e.getValue())).map(new Function>() { @Override public Map.Entry apply(VV vv) { return new SimpleImmutableEntry<>(e.getKey(), vv); } }); } }; return flattMap(mapper2); } @ParallelSupported public EntryStream flattMapValue(final BiFunction> valueMapper) { final Function, Stream>> mapper2 = new Function, Stream>>() { @Override public Stream> apply(final Entry e) { return Stream.of(valueMapper.apply(e.getKey(), e.getValue())).map(new Function>() { @Override public Map.Entry apply(VV vv) { return new SimpleImmutableEntry<>(e.getKey(), vv); } }); } }; return flattMap(mapper2); } /** * * @param keyMapper * @return * @see Collectors#groupingBy(Function) */ @SequentialOnly public EntryStream> groupBy() { final Function, K> keyMapper = Fn.key(); final Function, V> valueMapper = Fn.value(); if (isParallel()) { return of(s.sequential().groupBy(keyMapper, valueMapper).parallel(s.maxThreadNum(), s.splitor())); } else { return of(s.groupBy(keyMapper, valueMapper)); } } /** * * @param keyMapper * @param mapFactory * @return * @see Collectors#groupingBy(Function, Supplier) */ @SequentialOnly public EntryStream> groupBy(final Supplier>> mapFactory) { final Function, K> keyMapper = Fn.key(); final Function, V> valueMapper = Fn.value(); if (isParallel()) { return of(s.sequential().groupBy(keyMapper, valueMapper, mapFactory).parallel(s.maxThreadNum(), s.splitor())); } else { return of(s.groupBy(keyMapper, valueMapper, mapFactory)); } } @ParallelSupported public EntryStream> groupBy(final Function, ? extends KK> keyMapper, final Function, ? extends VV> valueMapper) { return of(s.groupBy(keyMapper, valueMapper)); } /** * * @param keyMapper * @param valueMapper * @param mapFactory * @return * @see Collectors#toMultimap(Function, Function, Supplier) */ @ParallelSupported public EntryStream> groupBy(final Function, ? extends KK> keyMapper, final Function, ? extends VV> valueMapper, final Supplier>> mapFactory) { return of(s.groupBy(keyMapper, valueMapper, mapFactory)); } /** * * @param downstream * @return * @see Collectors#groupingBy(Function, Collector) */ @ParallelSupported public EntryStream groupBy(final Collector, A, D> downstream) { final Function, K> keyMapper = Fn.key(); return of(s.groupBy(keyMapper, downstream)); } /** * * @param downstream * @param mapFactory * @return * @see Collectors#groupingBy(Function, Collector) */ @ParallelSupported public EntryStream groupBy(final Collector, A, D> downstream, final Supplier> mapFactory) { final Function, K> keyMapper = Fn.key(); return of(s.groupBy(keyMapper, downstream, mapFactory)); } /** * * @param keyMapper * @param downstream * @param mapFactory * @return * @see Collectors#groupingBy(Function, Collector, Supplier) */ @ParallelSupported public EntryStream groupBy(final Function, ? extends KK> keyMapper, final Collector, A, D> downstream) { return of(s.groupBy(keyMapper, downstream)); } /** * * @param keyMapper * @param downstream * @return * @see Collectors#groupingBy(Function, Collector) */ @ParallelSupported public EntryStream groupBy(final Function, ? extends KK> keyMapper, final Collector, A, D> downstream, final Supplier> mapFactory) { return of(s.groupBy(keyMapper, downstream, mapFactory)); } /** * * @param mergeFunction * @return */ @SequentialOnly public EntryStream groupBy(final BinaryOperator mergeFunction) { final Function, K> keyMapper = Fn.key(); final Function, V> valueMapper = Fn.value(); if (isParallel()) { return of(s.sequential().groupBy(keyMapper, valueMapper, mergeFunction).parallel(s.maxThreadNum(), s.splitor())); } else { return of(s.groupBy(keyMapper, valueMapper, mergeFunction)); } } /** * * @param mergeFunction * @param mapFactory * @return */ @SequentialOnly public EntryStream groupBy(final BinaryOperator mergeFunction, final Supplier> mapFactory) { final Function, K> keyMapper = Fn.key(); final Function, V> valueMapper = Fn.value(); if (isParallel()) { return of(s.sequential().groupBy(keyMapper, valueMapper, mergeFunction, mapFactory).parallel(s.maxThreadNum(), s.splitor())); } else { return of(s.groupBy(keyMapper, valueMapper, mergeFunction, mapFactory)); } } /** * * @param keyMapper * @param valueMapper * @param mergeFunction * @return * @see Collectors#groupBy(Function, Function, BinaryOperator) */ @ParallelSupported public EntryStream groupBy(final Function, ? extends KK> keyMapper, final Function, ? extends VV> valueMapper, final BinaryOperator mergeFunction) { return of(s.groupBy(keyMapper, valueMapper, mergeFunction)); } /** * * @param keyMapper * @param valueMapper * @param mergeFunction * @param mapFactory * @return * @see Collectors#groupBy(Function, Function, BinaryOperator, Supplier) */ @ParallelSupported public EntryStream groupBy(final Function, ? extends KK> keyMapper, final Function, ? extends VV> valueMapper, final BinaryOperator mergeFunction, final Supplier> mapFactory) { return of(s.groupBy(keyMapper, valueMapper, mergeFunction, mapFactory)); } /** * * @param collapsible * @return * @see Stream#collapse(BiPredicate, Collector) */ @SequentialOnly public Stream> collapseByKey(final BiPredicate collapsible) { return collapseByKey(collapsible, Collectors. toList()); } /** * Merge series of adjacent elements which satisfy the given predicate using * the merger function and return a new stream. * *
* This method only run sequentially, even in parallel stream. * * @param collapsible * @param collector * @return */ @SequentialOnly public Stream collapseByKey(final BiPredicate collapsible, final Collector collector) { final BiPredicate, ? super Entry> collapsible2 = new BiPredicate, Entry>() { @Override public boolean test(Entry t, Entry u) { return collapsible.test(t.getKey(), u.getKey()); } }; final Function, V> mapper = Fn.value(); return s.collapse(collapsible2, Collectors.mapping(mapper, collector)); } @ParallelSupported public EntryStream sorted(final Comparator> comparator) { return of(s.sorted(comparator)); } @ParallelSupported public EntryStream sortedByKey(final Comparator keyComparator) { final Comparator> comparator = Comparators.comparingByKey(keyComparator); return of(s.sorted(comparator)); } @ParallelSupported public EntryStream sortedByValue(final Comparator valueComparator) { final Comparator> comparator = Comparators.comparingByValue(valueComparator); return of(s.sorted(comparator)); } @SuppressWarnings("rawtypes") @ParallelSupported public EntryStream sortedBy(Function, ? extends Comparable> keyMapper) { return of(s.sortedBy(keyMapper)); } /** * * @param keyMapper * @return */ @ParallelSupported public EntryStream sortedByInt(final ToIntFunction> keyMapper) { final Comparator> comparator = Comparators.comparingInt(keyMapper); return sorted(comparator); } /** * * @param keyMapper * @return */ @ParallelSupported public EntryStream sortedByLong(final ToLongFunction> keyMapper) { final Comparator> comparator = Comparators.comparingLong(keyMapper); return sorted(comparator); } /** * * @param keyMapper * @return */ @ParallelSupported public EntryStream sortedByDouble(final ToDoubleFunction> keyMapper) { final Comparator> comparator = Comparators.comparingDouble(keyMapper); return sorted(comparator); } @SequentialOnly public EntryStream distinct() { return of(s.distinct()); } @SequentialOnly public EntryStream distinctByKey() { final Function, K> keyMapper = Fn.key(); if (isParallel()) { return of(s.sequential().distinctBy(keyMapper).parallel(s.maxThreadNum(), s.splitor())); } else { return of(s.distinctBy(keyMapper)); } } @SequentialOnly public EntryStream distinctByValue() { final Function, V> keyMapper = Fn.value(); if (isParallel()) { return of(s.sequential().distinctBy(keyMapper).parallel(s.maxThreadNum(), s.splitor())); } else { return of(s.distinctBy(keyMapper)); } } @ParallelSupported public EntryStream distinctBy(final Function, ?> keyMapper) { return of(s.distinctBy(keyMapper)); } @ParallelSupported public EntryStream distinct(final Predicate occurrencesFilter) { return of(s.distinct(occurrencesFilter)); } @ParallelSupported public EntryStream distinctBy(final Function, ?> keyMapper, final Predicate occurrencesFilter) { return of(s.distinctBy(keyMapper, occurrencesFilter)); } @SequentialOnly public EntryStream reversed() { return of(s.reversed()); } @SequentialOnly public EntryStream shuffled() { return of(s.shuffled()); } @SequentialOnly public EntryStream shuffled(final Random rnd) { return of(s.shuffled(rnd)); } @SequentialOnly public EntryStream rotated(final int distance) { return of(s.rotated(distance)); } @SuppressWarnings("rawtypes") @SequentialOnly public > EntryStream prepend(M map) { if (N.isNullOrEmpty(map)) { return of(s); } final Set> set = (Set) map.entrySet(); return of(s.prepend(set)); } @SuppressWarnings("rawtypes") @SequentialOnly public > EntryStream append(M map) { if (N.isNullOrEmpty(map)) { return of(s); } final Set> set = (Set) map.entrySet(); return of(s.append(set)); } public EntryStream appendIfEmpty(final Supplier> supplier) { return EntryStream.of(s.appendIfEmpty(new Supplier>>() { @Override public Stream> get() { return supplier.get().s; } })); } @SequentialOnly public EntryStream skip(long n) { return of(s.skip(n)); } @SequentialOnly public EntryStream limit(final long maxSize) { return of(s.limit(maxSize)); } @SequentialOnly public EntryStream slice(final long from, final long to) { return of(s.slice(from, to)); } @ParallelSupported public EntryStream peek(final Consumer> action) { return of(s.peek(action)); } @ParallelSupported public EntryStream peek(final BiConsumer action) { return of(s.peek(Fn.Entries.c(action))); } @ParallelSupported public void forEach(final Try.Consumer, E> action) throws E { s.forEach(action); } @ParallelSupported public void forEach(final Try.BiConsumer action) throws E { s.forEach(Fn.Entries.ec(action)); } @ParallelSupported public Optional> min(Comparator> comparator) { return s.min(comparator); } @ParallelSupported public Optional> minByKey(Comparator keyComparator) { return s.min(Comparators.comparingBy(Fn. key(), keyComparator)); } @ParallelSupported public Optional> minByValue(Comparator valueComparator) { return s.min(Comparators.comparingBy(Fn. value(), valueComparator)); } @ParallelSupported @SuppressWarnings("rawtypes") public Optional> minBy(final Function, ? extends Comparable> keyMapper) { return s.minBy(keyMapper); } @ParallelSupported public Optional> max(Comparator> comparator) { return s.max(comparator); } @ParallelSupported public Optional> maxByKey(Comparator keyComparator) { return s.max(Comparators.comparingBy(Fn. key(), keyComparator)); } @ParallelSupported public Optional> maxByValue(Comparator valueComparator) { return s.max(Comparators.comparingBy(Fn. value(), valueComparator)); } @ParallelSupported @SuppressWarnings("rawtypes") public Optional> maxBy(final Function, ? extends Comparable> keyMapper) { return s.maxBy(keyMapper); } @ParallelSupported public boolean anyMatch(final Try.Predicate, E> predicate) throws E { return s.anyMatch(predicate); } @ParallelSupported public boolean anyMatch(final Try.BiPredicate predicate) throws E { return s.anyMatch(Fn.Entries.ep(predicate)); } @ParallelSupported public boolean allMatch(final Try.Predicate, E> predicate) throws E { return s.allMatch(predicate); } @ParallelSupported public boolean allMatch(final Try.BiPredicate predicate) throws E { return s.allMatch(Fn.Entries.ep(predicate)); } @ParallelSupported public boolean noneMatch(final Try.Predicate, E> predicate) throws E { return s.noneMatch(predicate); } @ParallelSupported public boolean noneMatch(final Try.BiPredicate predicate) throws E { return s.noneMatch(Fn.Entries.ep(predicate)); } @ParallelSupported public Optional> findFirst(final Try.Predicate, E> predicate) throws E { return s.findFirst(predicate); } @ParallelSupported public Optional> findFirst(final Try.BiPredicate predicate) throws E { return s.findFirst(Fn.Entries.ep(predicate)); } @ParallelSupported public Optional> findAny(final Try.Predicate, E> predicate) throws E { return s.findAny(predicate); } @ParallelSupported public Optional> findAny(final Try.BiPredicate predicate) throws E { return s.findAny(Fn.Entries.ep(predicate)); } @SequentialOnly public Optional> first() { return s.first(); } @SequentialOnly public Optional> last() { return s.last(); } @SequentialOnly public long count() { return s.count(); } /** * Remember to close this Stream after the iteration is done, if required. * * @return */ @SequentialOnly public BiIterator iterator() { final ObjIterator> iter = s.iterator(); final BooleanSupplier hasNext = new BooleanSupplier() { @Override public boolean getAsBoolean() { return iter.hasNext(); } }; final Consumer> output = new Consumer>() { private Entry entry = null; @Override public void accept(Pair t) { entry = iter.next(); t.set(entry.getKey(), entry.getValue()); } }; return BiIterator.generate(hasNext, output); } public List toList(final Function, ? extends T> mapper) { return s. map(mapper).toList(); } public List toList(final BiFunction mapper) { return s. map(Fn.Entries.f(mapper)).toList(); } public Set toSet(final Function, ? extends T> mapper) { return s. map(mapper).toSet(); } public Set toSet(final BiFunction mapper) { return s. map(Fn.Entries.f(mapper)).toSet(); } public > CC toCollection(final Function, ? extends T> mapper, final Supplier supplier) { return s. map(mapper).toCollection(supplier); } public > CC toCollection(final BiFunction mapper, final Supplier supplier) { return s. map(Fn.Entries.f(mapper)).toCollection(supplier); } /** * * @return */ @ParallelSupported public ImmutableMap toImmutableMap() { return ImmutableMap.of(toMap()); } /** * * @return */ @ParallelSupported public ImmutableMap toImmutableMap(final BinaryOperator mergeFunction) { return ImmutableMap.of(toMap(mergeFunction)); } /** * * @return */ @SequentialOnly public Map toMap() { if (isParallel()) { return s.sequential().toMap(Fn. key(), Fn. value()); } else { return s.toMap(Fn. key(), Fn. value()); } } /** * * @param mergeFunction * @return */ @SequentialOnly public Map toMap(final BinaryOperator mergeFunction) { if (isParallel()) { return s.sequential().toMap(Fn. key(), Fn. value(), mergeFunction); } else { return s.toMap(Fn. key(), Fn. value(), mergeFunction); } } /** * * @param mapFactory * @return */ @SequentialOnly public > M toMap(final Supplier mapFactory) { if (isParallel()) { return s.sequential().toMap(Fn. key(), Fn. value(), mapFactory); } else { return s.toMap(Fn. key(), Fn. value(), mapFactory); } } /** * * @param mergeFunction * @param mapFactory * @return */ @SequentialOnly public > M toMap(final BinaryOperator mergeFunction, final Supplier mapFactory) { if (isParallel()) { return s.sequential().toMap(Fn. key(), Fn. value(), mergeFunction, mapFactory); } else { return s.toMap(Fn. key(), Fn. value(), mergeFunction, mapFactory); } } /** * * @param keyMapper * @param valueMapper * @return * @see Collectors#toMap(Function, Function) */ @ParallelSupported public Map toMap(final Function, ? extends KK> keyMapper, final Function, ? extends VV> valueMapper) { return s.toMap(keyMapper, valueMapper); } /** * * @param keyMapper * @param valueMapper * @param mapFactory * @return * @see Collectors#toMap(Function, Function, Supplier) */ @ParallelSupported public > M toMap(final Function, ? extends KK> keyMapper, final Function, ? extends VV> valueMapper, final Supplier mapFactory) { return s.toMap(keyMapper, valueMapper, mapFactory); } /** * * @param keyMapper * @param valueMapper * @param mergeFunction * @return * @see Collectors#toMap(Function, Function, BinaryOperator) */ @ParallelSupported public Map toMap(final Function, ? extends KK> keyMapper, final Function, ? extends VV> valueMapper, final BinaryOperator mergeFunction) { return s.toMap(keyMapper, valueMapper, mergeFunction); } /** * * @param keyMapper * @param valueMapper * @param mergeFunction * @param mapFactory * @return * @see Collectors#toMap(Function, Function, BinaryOperator, Supplier) */ @ParallelSupported public > M toMap(final Function, ? extends KK> keyMapper, final Function, ? extends VV> valueMapper, final BinaryOperator mergeFunction, final Supplier mapFactory) { return s.toMap(keyMapper, valueMapper, mergeFunction, mapFactory); } /** * * @param downstream * @return * @see Collectors#groupingBy(Function, Collector) */ @ParallelSupported public Map toMap(final Collector, A, D> downstream) { final Function, K> keyMapper = Fn.key(); return s.toMap(keyMapper, downstream); } /** * * @param downstream * @param mapFactory * @return * @see Collectors#groupingBy(Function, Collector) */ @ParallelSupported public > M toMap(final Collector, A, D> downstream, final Supplier mapFactory) { return s.toMap(Fn. key(), downstream, mapFactory); } /** * * @param keyMapper * @param downstream * @param mapFactory * @return * @see Collectors#groupingBy(Function, Collector, Supplier) */ @ParallelSupported public Map toMap(final Function, ? extends KK> keyMapper, final Collector, A, D> downstream) { return s.toMap(keyMapper, downstream); } /** * * @param keyMapper * @param downstream * @return * @see Collectors#groupingBy(Function, Collector) */ @ParallelSupported public > M toMap(final Function, ? extends KK> keyMapper, final Collector, A, D> downstream, final Supplier mapFactory) { return s.toMap(keyMapper, downstream, mapFactory); } @SequentialOnly public R toMapAndThen(Function, R> func) { return func.apply(toMap()); } /** * * @param keyMapper * @return * @see Collectors#groupingBy(Function) */ @SequentialOnly public Map> groupTo() { if (isParallel()) { return s.sequential().groupTo(Fn. key(), Fn. value()); } else { return s.groupTo(Fn. key(), Fn. value()); } } /** * * @param keyMapper * @param mapFactory * @return * @see Collectors#groupingBy(Function, Supplier) */ @SequentialOnly public >> M groupTo(final Supplier mapFactory) { if (isParallel()) { return s.sequential().groupTo(Fn. key(), Fn. value(), mapFactory); } else { return s.groupTo(Fn. key(), Fn. value(), mapFactory); } } @ParallelSupported public Map> groupTo(final Function, ? extends KK> keyMapper, final Function, ? extends VV> valueMapper) { return s.groupTo(keyMapper, valueMapper); } /** * * @param keyMapper * @param valueMapper * @param mapFactory * @return * @see Collectors#toMultimap(Function, Function, Supplier) */ @ParallelSupported public >> M groupTo(final Function, ? extends KK> keyMapper, final Function, ? extends VV> valueMapper, final Supplier mapFactory) { return s.groupTo(keyMapper, valueMapper, mapFactory); } @SequentialOnly public R groupToAndThen(Function>, R> func) { return func.apply(groupTo()); } /** * * @param keyMapper * @return * @see Collectors#toMultimap(Function, Function) */ @SequentialOnly public ListMultimap toMultimap() { if (isParallel()) { return s.sequential().toMultimap(Fn. key(), Fn. value()); } else { return s.toMultimap(Fn. key(), Fn. value()); } } /** * * @param keyMapper * @param mapFactory * @return * @see Collectors#toMultimap(Function, Function, Supplier) */ @SequentialOnly public , M extends Multimap> M toMultimap(final Supplier mapFactory) { if (isParallel()) { return s.sequential().toMultimap(Fn. key(), Fn. value(), mapFactory); } else { return s.toMultimap(Fn. key(), Fn. value(), mapFactory); } } /** * * @param keyMapper * @param valueMapper * @return * @see Collectors#toMultimap(Function, Function) */ @ParallelSupported public ListMultimap toMultimap(final Function, ? extends KK> keyMapper, final Function, ? extends VV> valueMapper) { return s.toMultimap(keyMapper, valueMapper); } /** * * @param keyMapper * @param valueMapper * @param mapFactory * @return * @see Collectors#toMultimap(Function, Function, Supplier) */ @ParallelSupported public , M extends Multimap> M toMultimap(final Function, ? extends KK> keyMapper, final Function, ? extends VV> valueMapper, final Supplier mapFactory) { return s.toMultimap(keyMapper, valueMapper, mapFactory); } @ParallelSupported public Map.Entry reduce(final ImmutableEntry identity, final BinaryOperator> accumulator) { return s.reduce(identity, accumulator); } @ParallelSupported public Optional> reduce(final BinaryOperator> accumulator) { return s.reduce(accumulator); } @ParallelSupported public R collect(final Supplier supplier, final BiConsumer> accumulator, final BiConsumer combiner) { return s.collect(supplier, accumulator, combiner); } @ParallelSupported public R collect(final Supplier supplier, final BiConsumer> accumulator) { return s.collect(supplier, accumulator); } @ParallelSupported public R collect(final Collector, A, R> collector) { return s.collect(collector); } @ParallelSupported public R collect(final java.util.stream.Collector, A, R> collector) { return s.collect(collector); } @ParallelSupported public RR collectAndThen(final Collector, A, R> downstream, final Function finisher) { return s.collectAndThen(downstream, finisher); } @ParallelSupported public RR collectAndThen(final java.util.stream.Collector, A, R> downstream, final java.util.function.Function finisher) { return s.collectAndThen(downstream, finisher); } @SequentialOnly public String join(CharSequence delimiter) { return join(delimiter, "", ""); } @SequentialOnly public String join(CharSequence delimiter, CharSequence prefix, CharSequence suffix) { return join(delimiter, "=", prefix, suffix); } @SequentialOnly public String join(CharSequence delimiter, CharSequence keyValueDelimiter) { return join(delimiter, keyValueDelimiter, "", ""); } @SequentialOnly public String join(CharSequence delimiter, CharSequence keyValueDelimiter, CharSequence prefix, CharSequence suffix) { s.assertNotClosed(); try { final Joiner joiner = Joiner.with(delimiter, keyValueDelimiter, prefix, suffix).reuseCachedBuffer(true); final Iterator> iter = s.iterator(); while (iter.hasNext()) { joiner.appendEntry(iter.next()); } return joiner.toString(); } finally { close(); } } @SequentialOnly public EntryStream chain(Function>, ? extends Stream>> transfer) { return of(transfer.apply(s)); } @SequentialOnly public R __(Function, R> transfer) { return transfer.apply(this); } public EntryStream sequential() { return s.isParallel() ? of(s.sequential()) : this; } public EntryStream parallel() { return of(s.parallel()); } public EntryStream parallel(final int threadNum) { return of(s.parallel(threadNum)); } public EntryStream parallel(final int maxThreadNum, final Splitor splitor) { return of(s.parallel(maxThreadNum, splitor)); } public EntryStream parallel(final int maxThreadNum, final Executor executor) { return of(s.parallel(maxThreadNum, executor)); } public EntryStream parallel(final Executor executor) { return of(s.parallel(executor)); } protected int maxThreadNum() { return s.maxThreadNum(); } protected Splitor splitor() { return s.splitor(); } protected AsyncExecutor asyncExecutor() { return s.asyncExecutor(); } public boolean isParallel() { return s.isParallel(); } /** * @return * @see Stream#mapToDisposableEntry(Function, Function) * @deprecated */ @Deprecated @Beta @SequentialOnly public EntryStream inversedToDisposableEntry() { checkState(s.isParallel() == false, "inversedER can't be applied to parallel stream"); final Function, DisposableEntry> mapper = new Function, DisposableEntry>() { private final ReusableEntry entry = new ReusableEntry<>(); @Override public DisposableEntry apply(Entry e) { entry.set(e.getValue(), e.getKey()); return entry; } }; return map(mapper); } /** * To reduce the memory footprint, Only one instance of DisposableEntry is created, * and the same entry instance is returned and set with different keys/values during iteration of the returned stream. * The elements only can be retrieved one by one, can't be modified or saved. * The returned Stream doesn't support the operations which require two or more elements at the same time: (e.g. sort/distinct/pairMap/slidingMap/sliding/split/toList/toSet/...). * , and can't be parallel stream. * Operations: filter/map/toMap/groupBy/groupTo/... are supported. * * @param keyMapper * @param valueMapper * @return * * @see DisposableEntry * @see NoCachingNoUpdating * * @deprecated */ @Deprecated @Beta @SequentialOnly public EntryStream mapToDisposableEntry(final Function, ? extends KK> keyMapper, final Function, ? extends VV> valueMapper) { checkState(s.isParallel() == false, "mapER can't be applied to parallel stream"); final Function, Map.Entry> mapper = new Function, Map.Entry>() { private final ReusableEntry entry = new ReusableEntry<>(); @Override public Entry apply(Entry t) { entry.set(keyMapper.apply(t), valueMapper.apply(t)); return entry; } }; return map(mapper); } /** * * @param keyMapper * @param valueMapper * @return * @see #mapToDisposableEntry(Function, Function) * @deprecated */ @Deprecated @Beta @SequentialOnly public EntryStream mapToDisposableEntry(final BiFunction keyMapper, final BiFunction valueMapper) { checkState(s.isParallel() == false, "mapER can't be applied to parallel stream"); final Function, Map.Entry> mapper = new Function, Map.Entry>() { private final ReusableEntry entry = new ReusableEntry<>(); @Override public Entry apply(Entry t) { entry.set(keyMapper.apply(t.getKey(), t.getValue()), valueMapper.apply(t.getKey(), t.getValue())); return entry; } }; return map(mapper); } /** * * @param keyMapper * @return * @see #mapToDisposableEntry(Function, Function) * @deprecated */ @Deprecated @Beta @SequentialOnly public EntryStream flatMapKeyToDisposableEntry(final Function> keyMapper) { checkState(s.isParallel() == false, "flatMapKeyER can't be applied to parallel stream"); final Function, Stream>> mapper2 = new Function, Stream>>() { @Override public Stream> apply(final Map.Entry e) { return keyMapper.apply(e.getKey()).map(new Function>() { private final ReusableEntry entry = new ReusableEntry<>(); @Override public Map.Entry apply(KK kk) { entry.set(kk, e.getValue()); return entry; } }); } }; return flattMap(mapper2); } /** * * @param keyMapper * @return * @see #mapToDisposableEntry(Function, Function) * @deprecated */ @Deprecated @Beta @SequentialOnly public EntryStream flattMapKeyToDisposableEntry(final Function> keyMapper) { checkState(s.isParallel() == false, "flatMapKeyER can't be applied to parallel stream"); final Function, Stream>> mapper2 = new Function, Stream>>() { @Override public Stream> apply(final Map.Entry e) { return Stream.of(keyMapper.apply(e.getKey())).map(new Function>() { private final ReusableEntry entry = new ReusableEntry<>(); @Override public Map.Entry apply(KK kk) { entry.set(kk, e.getValue()); return entry; } }); } }; return flattMap(mapper2); } /** * * @param valueMapper * @return * @see #mapToDisposableEntry(Function, Function) * @deprecated */ @Deprecated @Beta @SequentialOnly public EntryStream flatMapValueToDisposableEntry(final Function> valueMapper) { checkState(s.isParallel() == false, "flatMapValueER can't be applied to parallel stream"); final Function, Stream>> mapper2 = new Function, Stream>>() { @Override public Stream> apply(final Entry e) { return valueMapper.apply(e.getValue()).map(new Function>() { private final ReusableEntry entry = new ReusableEntry<>(); @Override public Map.Entry apply(VV vv) { entry.set(e.getKey(), vv); return entry; } }); } }; return flattMap(mapper2); } /** * * @param valueMapper * @return * @see #mapToDisposableEntry(Function, Function) * @deprecated */ @Deprecated @Beta @SequentialOnly public EntryStream flattMapValueToDisposableEntry(final Function> valueMapper) { checkState(s.isParallel() == false, "flatMapValueER can't be applied to parallel stream"); final Function, Stream>> mapper2 = new Function, Stream>>() { @Override public Stream> apply(final Entry e) { return Stream.of(valueMapper.apply(e.getValue())).map(new Function>() { private final ReusableEntry entry = new ReusableEntry<>(); @Override public Map.Entry apply(VV vv) { entry.set(e.getKey(), vv); return entry; } }); } }; return flattMap(mapper2); } @SequentialOnly public EntryStream onClose(Runnable closeHandler) { return of(s.onClose(closeHandler)); } @Override @SequentialOnly public void close() { s.close(); } void checkState(boolean b, String errorMessage) { if (!b) { try { N.checkState(b, errorMessage); } finally { close(); } } } @SuppressWarnings({ "rawtypes", "unchecked" }) static Function, Stream>> mapFunc() { return (Function) mapper_func; } public static EntryStream empty() { return new EntryStream<>(Stream.> empty()); } public static EntryStream of(K k1, V v1) { return of(Stream.of(new SimpleImmutableEntry<>(k1, v1))); } public static EntryStream of(K k1, V v1, K k2, V v2) { return of(Stream.of(new SimpleImmutableEntry<>(k1, v1), new SimpleImmutableEntry<>(k2, v2))); } public static EntryStream of(K k1, V v1, K k2, V v2, K k3, V v3) { return of(Stream.of(new SimpleImmutableEntry<>(k1, v1), new SimpleImmutableEntry<>(k2, v2), new SimpleImmutableEntry<>(k3, v3))); } public static EntryStream of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { return of(Stream.of(new SimpleImmutableEntry<>(k1, v1), new SimpleImmutableEntry<>(k2, v2), new SimpleImmutableEntry<>(k3, v3), new SimpleImmutableEntry<>(k4, v4))); } public static EntryStream of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { return of(Stream.of(new SimpleImmutableEntry<>(k1, v1), new SimpleImmutableEntry<>(k2, v2), new SimpleImmutableEntry<>(k3, v3), new SimpleImmutableEntry<>(k4, v4), new SimpleImmutableEntry<>(k5, v5))); } public static EntryStream of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6) { return of(Stream.of(new SimpleImmutableEntry<>(k1, v1), new SimpleImmutableEntry<>(k2, v2), new SimpleImmutableEntry<>(k3, v3), new SimpleImmutableEntry<>(k4, v4), new SimpleImmutableEntry<>(k5, v5), new SimpleImmutableEntry<>(k6, v6))); } public static EntryStream of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7) { return of(Stream.of(new SimpleImmutableEntry<>(k1, v1), new SimpleImmutableEntry<>(k2, v2), new SimpleImmutableEntry<>(k3, v3), new SimpleImmutableEntry<>(k4, v4), new SimpleImmutableEntry<>(k5, v5), new SimpleImmutableEntry<>(k6, v6), new SimpleImmutableEntry<>(k7, v7))); } static EntryStream of(final Stream> s) { return new EntryStream(s); } public static EntryStream of(final Map map) { return new EntryStream(map, Stream.of(map)); } public static EntryStream of(final Iterator> iterator) { return new EntryStream(Stream.of(iterator)); } public static EntryStream of(final Collection> entries) { return new EntryStream(Stream.of(entries)); } // @SafeVarargs // public static EntryStream of(final Map.Entry... entries) { // return new EntryStream(Stream.of(entries)); // } public static EntryStream of(final Multiset multiset) { return multiset == null ? EntryStream. empty() : multiset.entryStream(); } public static EntryStream of(final LongMultiset multiset) { return multiset == null ? EntryStream. empty() : multiset.entryStream(); } public static > EntryStream of(final Multimap mulitmap) { return mulitmap == null ? EntryStream. empty() : mulitmap.entryStream(); } public static EntryStream of(final T[] a, final Function keyMapper) { final Function valueMapper = Fn.identity(); return Stream.of(a).mapToEntry(keyMapper, valueMapper); } public static EntryStream of(final Collection c, final Function keyMapper) { final Function valueMapper = Fn.identity(); return Stream.of(c).mapToEntry(keyMapper, valueMapper); } public static EntryStream of(final Iterator iter, final Function keyMapper) { final Function valueMapper = Fn.identity(); return Stream.of(iter).mapToEntry(keyMapper, valueMapper); } @SafeVarargs public static EntryStream concat(final Map... maps) { if (N.isNullOrEmpty(maps)) { return EntryStream.empty(); } final Function, Stream>> mapper = mapFunc(); return Stream.of(maps).flatMapToEntry(mapper); } public static EntryStream concat(final Collection> maps) { if (N.isNullOrEmpty(maps)) { return EntryStream.empty(); } final Function, Stream>> mapper = mapFunc(); return Stream.of(maps).flatMapToEntry(mapper); } public static EntryStream merge(final Map a, final Map b, final BiFunction, ? super Map.Entry, Nth> nextSelector) { N.checkArgNotNull(nextSelector); if (N.isNullOrEmpty(a)) { return of(b); } else if (N.isNullOrEmpty(b)) { return of(a); } else { return Stream.merge(a.entrySet(), b.entrySet(), nextSelector).mapToEntry(Fn.> identity()); } } public static EntryStream merge(final Map a, final Map b, final Map c, final BiFunction, ? super Map.Entry, Nth> nextSelector) { N.checkArgNotNull(nextSelector); if (N.isNullOrEmpty(a)) { return merge(b, c, nextSelector); } else if (N.isNullOrEmpty(b)) { return merge(a, c, nextSelector); } else if (N.isNullOrEmpty(c)) { return merge(a, b, nextSelector); } else { return Stream.merge(a.entrySet(), b.entrySet(), c.entrySet(), nextSelector).mapToEntry(Fn.> identity()); } } public static EntryStream merge(final Collection> maps, final BiFunction, ? super Map.Entry, Nth> nextSelector) { N.checkArgNotNull(nextSelector); if (N.isNullOrEmpty(maps)) { return EntryStream.empty(); } final List>> entryIteratorList = new ArrayList<>(maps.size()); for (Map map : maps) { if (N.notNullOrEmpty(map)) { entryIteratorList.add(map.entrySet()); } } return Stream.merge(entryIteratorList, nextSelector).mapToEntry(Fn.> identity()); } public static EntryStream zip(final K[] keys, final V[] values) { if (N.isNullOrEmpty(keys) || N.isNullOrEmpty(values)) { return EntryStream.empty(); } final BiFunction> zipFunction = Fn.entry(); final Function, Map.Entry> mapper = Fn.identity(); return Stream.zip(keys, values, zipFunction).mapToEntry(mapper); } public static EntryStream zip(final K[] keys, final V[] values, K valueForNonKey, V valueForNonValue) { if (N.isNullOrEmpty(keys) && N.isNullOrEmpty(values)) { return EntryStream.empty(); } final BiFunction> zipFunction = Fn.entry(); final Function, Map.Entry> mapper = Fn.identity(); return Stream.zip(keys, values, valueForNonKey, valueForNonValue, zipFunction).mapToEntry(mapper); } public static EntryStream zip(final Collection keys, final Collection values) { if (N.isNullOrEmpty(keys) || N.isNullOrEmpty(values)) { return EntryStream.empty(); } final BiFunction> zipFunction = Fn.entry(); final Function, Map.Entry> mapper = Fn.identity(); return Stream.zip(keys, values, zipFunction).mapToEntry(mapper); } public static EntryStream zip(final Collection keys, final Collection values, K valueForNonKey, V valueForNonValue) { if (N.isNullOrEmpty(keys) && N.isNullOrEmpty(values)) { return EntryStream.empty(); } final BiFunction> zipFunction = Fn.entry(); final Function, Map.Entry> mapper = Fn.identity(); return Stream.zip(keys, values, valueForNonKey, valueForNonValue, zipFunction).mapToEntry(mapper); } static class ReusableEntry extends DisposableEntry { private K key = null; private V value = null; private boolean flag = false; //check if it's used/read. @Override public K getKey() { flag = false; return key; } @Override public V getValue() { flag = false; return value; } @Override public V setValue(V value) { throw new UnsupportedOperationException(); } public void set(K key, V value) { if (flag) { throw new IllegalStateException(); } this.key = key; this.value = value; this.flag = true; } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj instanceof ReusableEntry) { final ReusableEntry other = (ReusableEntry) obj; return N.equals(key, other.key) && N.equals(value, other.value); } return false; } @Override public int hashCode() { return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode()); } @Override public String toString() { flag = false; return key + "=" + value; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy