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

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

Go to download

A general programming library in Java/Android. It's easy to learn and simple to use with concise and powerful APIs.

There is a newer version: 5.3.16
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.Random;
import java.util.Set;
import java.util.concurrent.Executor;

import com.landawn.abacus.annotation.Beta;
import com.landawn.abacus.annotation.IntermediateOp;
import com.landawn.abacus.annotation.LazyEvaluation;
import com.landawn.abacus.annotation.ParallelSupported;
import com.landawn.abacus.annotation.SequentialOnly;
import com.landawn.abacus.annotation.TerminalOp;
import com.landawn.abacus.annotation.TerminalOpTriggered;
import com.landawn.abacus.exception.DuplicatedResultException;
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.If.OrElse;
import com.landawn.abacus.util.ImmutableMap;
import com.landawn.abacus.util.Indexed;
import com.landawn.abacus.util.Joiner;
import com.landawn.abacus.util.ListMultimap;
import com.landawn.abacus.util.LongMultiset;
import com.landawn.abacus.util.MergeResult;
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.ObjIterator;
import com.landawn.abacus.util.Pair;
import com.landawn.abacus.util.Percentage;
import com.landawn.abacus.util.Throwables;
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;

/**
 * The Stream will be automatically closed after execution(A terminal method is executed/triggered).
 *
 * @see BaseStream
 * @see Stream
 * @see IntStream
 * @see LongStream
 * @see DoubleStream
 * @see EntryStream
 * @see com.landawn.abacus.util.ExceptionalStream
 * @see Collectors
 * @see com.landawn.abacus.util.Fn
 * @see com.landawn.abacus.util.Comparators
 */
@com.landawn.abacus.annotation.Immutable
@LazyEvaluation
public final class EntryStream extends
        StreamBase, Object[], Predicate>, Consumer>, List>, Optional>, Indexed>, ObjIterator>, EntryStream> {

    private static final Function, Stream>> mapper_func = t -> Stream.of(t);

    final Map m;
    final Stream> s;

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

    @SuppressWarnings("rawtypes")
    EntryStream(final Map m, final Stream> s) {
        super(s.sorted, (Comparator>) s.cmp, s.closeHandlers);
        this.m = (Map) m;
        this.s = (Stream>) s;
    }

    @SequentialOnly
    @IntermediateOp
    public Stream keys() {
        // It won't be parallel stream if m != null.
        if (m != null) {
            return Stream.of(m.keySet());
        }

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

        if (isParallel()) {
            return s.psp(ss -> ss.map(func));
        } else {
            return s.map(func);
        }
    }

    @SequentialOnly
    @IntermediateOp
    public Stream values() {
        // It won't be parallel stream if m != null.
        if (m != null) {
            return Stream.of(m.values());
        }

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

        if (isParallel()) {
            return s.psp(ss -> ss.map(func));
        } else {
            return s.map(func);
        }
    }

    @SequentialOnly
    @IntermediateOp
    public Stream> entries() {
        return s;
    }

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

        if (isParallel()) {
            return of(s.>> psp(ss -> ss.map(mapper)));
        } else {
            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 */ @SuppressWarnings({ "unchecked" }) @SequentialOnly @IntermediateOp public EntryStream selectByKey(Class clazz) { if (isParallel()) { return (EntryStream) sequential().filterByKey(Fn.instanceOf(clazz)) .parallel(maxThreadNum(), splitor(), asyncExecutor(), cancelUncompletedThreads()); } 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 */ @SuppressWarnings({ "unchecked" }) @SequentialOnly @IntermediateOp public EntryStream selectByValue(Class clazz) { if (isParallel()) { return (EntryStream) sequential().filterByValue(Fn.instanceOf(clazz)) .parallel(maxThreadNum(), splitor(), asyncExecutor(), cancelUncompletedThreads()); } else { return (EntryStream) filterByValue(Fn.instanceOf(clazz)); } } @Override public EntryStream filter(final Predicate> predicate) { return of(s.filter(predicate)); } @ParallelSupported @IntermediateOp public EntryStream filter(final BiPredicate predicate) { return of(s.filter(Fn.Entries.p(predicate))); } @Override public EntryStream filter(Predicate> predicate, Consumer> actionOnDroppedItem) { return of(s.filter(predicate, actionOnDroppedItem)); } @ParallelSupported @IntermediateOp public EntryStream filterByKey(final Predicate keyPredicate) { final Predicate> predicate = Fn.testByKey(keyPredicate); return of(s.filter(predicate)); } @ParallelSupported @IntermediateOp public EntryStream filterByValue(final Predicate valuePredicate) { final Predicate> predicate = Fn.testByValue(valuePredicate); return of(s.filter(predicate)); } /** * * @param * @param predicate * @return * @deprecated */ @Deprecated @Override public EntryStream removeIf(final Predicate> predicate) { return of(s.removeIf(predicate)); } /** * * @param * @param predicate * @return * @deprecated */ @ParallelSupported @Deprecated public EntryStream removeIf(final BiPredicate predicate) { return of(s.removeIf(Fn.Entries.p(predicate))); } @Deprecated @Override public EntryStream removeIf(Predicate> predicate, Consumer> actionOnDroppedItem) { return of(s.removeIf(predicate, actionOnDroppedItem)); } @Override public EntryStream takeWhile(final Predicate> predicate) { return of(s.takeWhile(predicate)); } @ParallelSupported @IntermediateOp public EntryStream takeWhile(final BiPredicate predicate) { return of(s.takeWhile(Fn.Entries.p(predicate))); } @Override public EntryStream dropWhile(final Predicate> predicate) { return of(s.dropWhile(predicate)); } @ParallelSupported @IntermediateOp public EntryStream dropWhile(final BiPredicate predicate) { return of(s.dropWhile(Fn.Entries.p(predicate))); } @Override public EntryStream dropWhile(Predicate> predicate, Consumer> actionOnDroppedItem) { return of(s.dropWhile(predicate, actionOnDroppedItem)); } @Override public EntryStream skipUntil(final Predicate> predicate) { return of(s.skipUntil(predicate)); } @ParallelSupported @IntermediateOp public EntryStream skipUntil(final BiPredicate predicate) { return of(s.skipUntil(Fn.Entries.p(predicate))); } @ParallelSupported @IntermediateOp public EntryStream map(final Function, ? extends Map.Entry> mapper) { return s.mapToEntry(mapper); } @ParallelSupported @IntermediateOp public EntryStream map(final Function, ? extends KK> keyMapper, final Function, ? extends VV> valueMapper) { return s.mapToEntry(keyMapper, valueMapper); } @ParallelSupported @IntermediateOp public EntryStream map(final BiFunction> mapper) { return map(Fn.Entries.f(mapper)); } @ParallelSupported @IntermediateOp public EntryStream map(final BiFunction keyMapper, final BiFunction valueMapper) { final Function, Map.Entry> mapper = t -> new SimpleImmutableEntry<>(keyMapper.apply(t.getKey(), t.getValue()), valueMapper.apply(t.getKey(), t.getValue())); return map(mapper); } @ParallelSupported @IntermediateOp public EntryStream mapKey(final Function keyMapper) { final Function, Map.Entry> mapper = Fn.mapKey(keyMapper); return map(mapper); } @ParallelSupported @IntermediateOp public EntryStream mapKey(final BiFunction keyMapper) { final Function, Map.Entry> mapper = entry -> new SimpleImmutableEntry<>(keyMapper.apply(entry.getKey(), entry.getValue()), entry.getValue()); return map(mapper); } @ParallelSupported @IntermediateOp public EntryStream mapValue(final Function valueMapper) { final Function, Map.Entry> mapper = Fn.mapValue(valueMapper); return map(mapper); } @ParallelSupported @IntermediateOp public EntryStream mapValue(final BiFunction valueMapper) { final Function, Map.Entry> mapper = entry -> new SimpleImmutableEntry<>(entry.getKey(), valueMapper.apply(entry.getKey(), entry.getValue())); return map(mapper); } @ParallelSupported @IntermediateOp public EntryStream mapKeyPartial​(final Function> keyMapper) { final Map.Entry emptyEntry = new SimpleImmutableEntry<>(null, null); final Function, Map.Entry> mapper = entry -> { final Optional op = keyMapper.apply(entry.getKey()); return op.isPresent() ? new SimpleImmutableEntry<>(op.get(), entry.getValue()) : emptyEntry; }; if (this.isParallel()) { return map(mapper).psp(s -> s.filter(it -> it != emptyEntry)); } else { return map(mapper).filter(it -> it != emptyEntry); } } @ParallelSupported @IntermediateOp public EntryStream mapKeyPartial​(final BiFunction> keyMapper) { final Map.Entry emptyEntry = new SimpleImmutableEntry<>(null, null); final Function, Map.Entry> mapper = entry -> { final Optional op = keyMapper.apply(entry.getKey(), entry.getValue()); return op.isPresent() ? new SimpleImmutableEntry<>(op.get(), entry.getValue()) : emptyEntry; }; if (this.isParallel()) { return map(mapper).psp(s -> s.filter(it -> it != emptyEntry)); } else { return map(mapper).filter(it -> it != emptyEntry); } } @ParallelSupported @IntermediateOp public EntryStream mapValuePartial​(final Function> valueMapper) { final Map.Entry emptyEntry = new SimpleImmutableEntry<>(null, null); final Function, Map.Entry> mapper = entry -> { final Optional op = valueMapper.apply(entry.getValue()); return op.isPresent() ? new SimpleImmutableEntry<>(entry.getKey(), op.get()) : emptyEntry; }; if (this.isParallel()) { return map(mapper).psp(s -> s.filter(it -> it != emptyEntry)); } else { return map(mapper).filter(it -> it != emptyEntry); } } @ParallelSupported @IntermediateOp public EntryStream mapValuePartial​(final BiFunction> valueMapper) { final Map.Entry emptyEntry = new SimpleImmutableEntry<>(null, null); final Function, Map.Entry> mapper = entry -> { final Optional op = valueMapper.apply(entry.getKey(), entry.getValue()); return op.isPresent() ? new SimpleImmutableEntry<>(entry.getKey(), op.get()) : emptyEntry; }; if (this.isParallel()) { return map(mapper).psp(s -> s.filter(it -> it != emptyEntry)); } else { return map(mapper).filter(it -> it != emptyEntry); } } @ParallelSupported @IntermediateOp public EntryStream flatMap(final Function, ? extends EntryStream> mapper) { return s.flatMappToEntry(mapper); } @ParallelSupported @IntermediateOp public EntryStream flatMap(final BiFunction> mapper) { return flatMap(Fn.Entries.f(mapper)); } @ParallelSupported @IntermediateOp public EntryStream flattMap(final Function, ? extends Map> mapper) { return s.flattMapToEntry(mapper); } @ParallelSupported @IntermediateOp public EntryStream flattMap(final BiFunction> mapper) { return flattMap(Fn.Entries.f(mapper)); } @ParallelSupported @IntermediateOp public EntryStream flatMapp( final Function, ? extends Stream>> mapper) { return s.flatMapToEntry(mapper); } @ParallelSupported @IntermediateOp public EntryStream flatMapp( final BiFunction>> mapper) { return flatMapp(Fn.Entries.f(mapper)); } @ParallelSupported @IntermediateOp public EntryStream flatMapKey(final Function> keyMapper) { final Function, Stream>> mapper2 = e -> keyMapper.apply(e.getKey()) .map(kk -> new SimpleImmutableEntry<>(kk, e.getValue())); return flatMapp(mapper2); } @ParallelSupported @IntermediateOp public EntryStream flatMapKey(final BiFunction> keyMapper) { final Function, Stream>> mapper2 = e -> keyMapper.apply(e.getKey(), e.getValue()) .map(kk -> new SimpleImmutableEntry<>(kk, e.getValue())); return flatMapp(mapper2); } @ParallelSupported @IntermediateOp public EntryStream flattMapKey(final Function> keyMapper) { final Function, Stream>> mapper2 = e -> Stream.of(keyMapper.apply(e.getKey())) .map(kk -> new SimpleImmutableEntry<>(kk, e.getValue())); return flatMapp(mapper2); } @ParallelSupported @IntermediateOp public EntryStream flattMapKey(final BiFunction> keyMapper) { final Function, Stream>> mapper2 = e -> Stream.of(keyMapper.apply(e.getKey(), e.getValue())) .map(kk -> new SimpleImmutableEntry<>(kk, e.getValue())); return flatMapp(mapper2); } @ParallelSupported @IntermediateOp public EntryStream flatMapValue(final Function> valueMapper) { final Function, Stream>> mapper2 = e -> valueMapper.apply(e.getValue()) .map(vv -> new SimpleImmutableEntry<>(e.getKey(), vv)); return flatMapp(mapper2); } @ParallelSupported @IntermediateOp public EntryStream flatMapValue(final BiFunction> valueMapper) { final Function, Stream>> mapper2 = e -> valueMapper.apply(e.getKey(), e.getValue()) .map(vv -> new SimpleImmutableEntry<>(e.getKey(), vv)); return flatMapp(mapper2); } @ParallelSupported @IntermediateOp public EntryStream flattMapValue(final Function> valueMapper) { final Function, Stream>> mapper2 = e -> Stream.of(valueMapper.apply(e.getValue())) .map(vv -> new SimpleImmutableEntry<>(e.getKey(), vv)); return flatMapp(mapper2); } @ParallelSupported @IntermediateOp public EntryStream flattMapValue(final BiFunction> valueMapper) { final Function, Stream>> mapper2 = e -> Stream.of(valueMapper.apply(e.getKey(), e.getValue())) .map(vv -> new SimpleImmutableEntry<>(e.getKey(), vv)); return flatMapp(mapper2); } /** * * @param keyMapper * @return * @see Collectors#groupingBy(Function) */ @SequentialOnly @IntermediateOp @TerminalOpTriggered 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(), s.asyncExecutor(), s.cancelUncompletedThreads())); } else { return of(s.groupBy(keyMapper, valueMapper)); } } /** * * @param keyMapper * @param mapFactory * @return * @see Collectors#groupingBy(Function, Supplier) */ @SequentialOnly @IntermediateOp @TerminalOpTriggered 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(), s.asyncExecutor(), s.cancelUncompletedThreads())); } else { return of(s.groupBy(keyMapper, valueMapper, mapFactory)); } } @ParallelSupported @IntermediateOp @TerminalOpTriggered 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 @IntermediateOp @TerminalOpTriggered 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 @IntermediateOp @TerminalOpTriggered 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 @IntermediateOp @TerminalOpTriggered 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 @IntermediateOp @TerminalOpTriggered 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 @IntermediateOp @TerminalOpTriggered 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 @IntermediateOp @TerminalOpTriggered 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(), s.asyncExecutor(), s.cancelUncompletedThreads())); } else { return of(s.groupBy(keyMapper, valueMapper, mergeFunction)); } } /** * * @param mergeFunction * @param mapFactory * @return */ @SequentialOnly @IntermediateOp @TerminalOpTriggered 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(), s.asyncExecutor(), s.cancelUncompletedThreads())); } else { return of(s.groupBy(keyMapper, valueMapper, mergeFunction, mapFactory)); } } /** * * @param keyMapper * @param valueMapper * @param mergeFunction * @return * @see Collectors#groupBy(Function, Function, BinaryOperator) */ @ParallelSupported @IntermediateOp @TerminalOpTriggered 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 @IntermediateOp @TerminalOpTriggered 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 @IntermediateOp 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 runs sequentially, even in parallel stream. * * @param collapsible * @param collector * @return */ @SequentialOnly @IntermediateOp public Stream collapseByKey(final BiPredicate collapsible, final Collector collector) { final BiPredicate, ? super Map.Entry> collapsible2 = (t, u) -> collapsible.test(t.getKey(), u.getKey()); final Function, V> mapper = Fn.value(); return s.collapse(collapsible2, Collectors.mapping(mapper, collector)); } @Override public Stream> split(int chunkSize) { return s.split(chunkSize).map(EntryStream::of); } @Override public Stream>> splitToList(int chunkSize) { return s.splitToList(chunkSize); } @Override public Stream> split(Predicate> predicate) { return s.split(predicate).map(EntryStream::of); } @Override public Stream>> splitToList(Predicate> predicate) { return s.splitToList(predicate); } @Override public Stream> splitAt(int where) { return s.splitAt(where).map(EntryStream::of); } @Override public Stream> splitAt(Predicate> where) { return s.splitAt(where).map(EntryStream::of); } @Override public Stream> sliding(int windowSize, int increment) { return s.sliding(windowSize, increment).map(EntryStream::of); } @Override public Stream>> slidingToList(int windowSize, int increment) { return s.slidingToList(windowSize, increment); } @Override public EntryStream intersection(Collection c) { return of(s.intersection(c)); } @Override public EntryStream difference(Collection c) { return of(s.difference(c)); } @Override public EntryStream symmetricDifference(Collection> c) { return of(s.symmetricDifference(c)); } /** * Compares keys and then compares values if key is equals. */ @SuppressWarnings("rawtypes") @Override @Deprecated public EntryStream sorted() { final Comparator> cmp = Comparators. comparingByKey((Comparator) Fn.naturalOrder()) .thenComparing(Comparators.comparingByValue((Comparator) Fn.naturalOrder())); return of(s.sorted(cmp)); } @ParallelSupported @IntermediateOp @TerminalOpTriggered public EntryStream sorted(final Comparator> comparator) { return of(s.sorted(comparator)); } @ParallelSupported @IntermediateOp @TerminalOpTriggered public EntryStream sortedByKey(final Comparator keyComparator) { final Comparator> comparator = Comparators.comparingByKey(keyComparator); return of(s.sorted(comparator)); } @ParallelSupported @IntermediateOp @TerminalOpTriggered public EntryStream sortedByValue(final Comparator valueComparator) { final Comparator> comparator = Comparators.comparingByValue(valueComparator); return of(s.sorted(comparator)); } @SuppressWarnings("rawtypes") @ParallelSupported @IntermediateOp @TerminalOpTriggered public EntryStream sortedBy(Function, ? extends Comparable> keyMapper) { return of(s.sortedBy(keyMapper)); } /** * * @param keyMapper * @return */ @ParallelSupported @IntermediateOp @TerminalOpTriggered public EntryStream sortedByInt(final ToIntFunction> keyMapper) { final Comparator> comparator = Comparators.comparingInt(keyMapper); return sorted(comparator); } /** * * @param keyMapper * @return */ @ParallelSupported @IntermediateOp @TerminalOpTriggered public EntryStream sortedByLong(final ToLongFunction> keyMapper) { final Comparator> comparator = Comparators.comparingLong(keyMapper); return sorted(comparator); } /** * * @param keyMapper * @return */ @ParallelSupported @IntermediateOp @TerminalOpTriggered public EntryStream sortedByDouble(final ToDoubleFunction> keyMapper) { final Comparator> comparator = Comparators.comparingDouble(keyMapper); return sorted(comparator); } @ParallelSupported @IntermediateOp @TerminalOpTriggered public EntryStream reverseSorted(final Comparator> comparator) { return of(s.reverseSorted(comparator)); } @Override public Stream>> indexed() { return s.indexed(); } @Override public EntryStream distinct() { return of(s.distinct()); } @ParallelSupported @IntermediateOp @TerminalOpTriggered public EntryStream distinct(BinaryOperator> mergeFunction) { return of(s.distinct(mergeFunction)); } @SequentialOnly @IntermediateOp public EntryStream distinctByKey() { final Function, K> keyMapper = Fn.key(); if (isParallel()) { return of(s.sequential().distinctBy(keyMapper).parallel(s.maxThreadNum(), s.splitor(), s.asyncExecutor(), s.cancelUncompletedThreads())); } else { return of(s.distinctBy(keyMapper)); } } @SequentialOnly @IntermediateOp public EntryStream distinctByValue() { final Function, V> keyMapper = Fn.value(); if (isParallel()) { return of(s.sequential().distinctBy(keyMapper).parallel(s.maxThreadNum(), s.splitor(), s.asyncExecutor(), s.cancelUncompletedThreads())); } else { return of(s.distinctBy(keyMapper)); } } @ParallelSupported @IntermediateOp public EntryStream distinctBy(final Function, ?> keyMapper) { return of(s.distinctBy(keyMapper)); } @ParallelSupported @IntermediateOp @TerminalOpTriggered public EntryStream distinct(final Predicate occurrencesFilter) { return of(s.distinct(occurrencesFilter)); } /** * * @param keyMapper * @param occurrencesFilter * @return * @see #groupBy(Function, Collector) */ @ParallelSupported @IntermediateOp @TerminalOpTriggered public EntryStream distinctBy(final Function, ?> keyMapper, final Predicate occurrencesFilter) { return of(s.distinctBy(keyMapper, occurrencesFilter)); } /** * * @param keyMapper * @param mergeFunction * @return * @see #groupBy(Function, Function, BinaryOperator) */ @ParallelSupported @IntermediateOp @TerminalOpTriggered public EntryStream distinctBy(final Function, ?> keyMapper, BinaryOperator> mergeFunction) { return of(s.distinctBy(keyMapper, mergeFunction)); } @Override public EntryStream rotated(final int distance) { return of(s.rotated(distance)); } @Override public EntryStream shuffled() { return of(s.shuffled()); } @Override public EntryStream shuffled(final Random rnd) { return of(s.shuffled(rnd)); } @Override public EntryStream reversed() { return of(s.reversed()); } @Override @Deprecated public EntryStream reverseSorted() { @SuppressWarnings("rawtypes") final Comparator> cmp = Comparators. comparingByKey((Comparator) Fn.naturalOrder()) .thenComparing(Comparators.comparingByValue((Comparator) Fn.naturalOrder())) .reversed(); return of(s.sorted(cmp)); } @Override public EntryStream cycled() { return of(s.cycled()); } @Override public EntryStream cycled(final long rounds) { return of(s.cycled(rounds)); } @SequentialOnly @IntermediateOp @SuppressWarnings("rawtypes") public > EntryStream prepend(M map) { if (N.isNullOrEmpty(map)) { return of(s); } final Set> set = (Set) map.entrySet(); return of(s.prepend(set)); } @Override public EntryStream prepend(EntryStream stream) { return of(s.prepend(stream.s)); } @Override public EntryStream prepend(Optional> op) { return of(s.prepend(op)); } @SequentialOnly @IntermediateOp @SuppressWarnings("rawtypes") public > EntryStream append(M map) { if (N.isNullOrEmpty(map)) { return of(s); } final Set> set = (Set) map.entrySet(); return of(s.append(set)); } @Override public EntryStream append(EntryStream stream) { return of(s.append(stream.s)); } @Override public EntryStream append(Optional> op) { return of(s.append(op)); } @SequentialOnly @IntermediateOp @SuppressWarnings("rawtypes") public > EntryStream appendIfEmpty(M map) { if (N.isNullOrEmpty(map)) { return of(s); } final Set> set = (Set) map.entrySet(); return of(s.appendIfEmpty(set)); } @Override public EntryStream appendIfEmpty(final Supplier> supplier) { return EntryStream.of(s.appendIfEmpty(new Supplier>>() { @SuppressWarnings("resource") @Override public Stream> get() { return supplier.get().s; } })); } @Override public Optional applyIfNotEmpty(final Throwables.Function, R, E> func) throws E { final EntryStream tmp = this; final Throwables.Function>, R, E> func2 = t -> func.apply(tmp); return s.applyIfNotEmpty(func2); } @Override public OrElse acceptIfNotEmpty(Throwables.Consumer, E> action) throws E { final EntryStream tmp = this; final Throwables.Consumer>, E> action2 = t -> action.accept(tmp); return s.acceptIfNotEmpty(action2); } @SequentialOnly @IntermediateOp @Override public EntryStream skip(long n) { return of(s.skip(n)); } @Override public EntryStream skip(long n, Consumer> consumer) { return of(s.skip(n, consumer)); } @SequentialOnly @IntermediateOp @Override public EntryStream limit(final long maxSize) { return of(s.limit(maxSize)); } // /** // * // * @param from // * @param to // * @return // * @deprecated // */ // @Deprecated // @SequentialOnly // public EntryStream slice(final long from, final long to) { // return of(s.slice(from, to)); // } @Override public EntryStream step(long step) { return of(s.step(step)); } @Override public EntryStream peek(final Consumer> action) { return of(s.peek(action)); } @ParallelSupported @IntermediateOp public EntryStream peek(final BiConsumer action) { return of(s.peek(Fn.Entries.c(action))); } @Override public EntryStream onEach(final Consumer> action) { return of(s.onEach(action)); } @ParallelSupported @IntermediateOp public EntryStream onEach(final BiConsumer action) { return of(s.onEach(Fn.Entries.c(action))); } @ParallelSupported @TerminalOp public void forEach(final Throwables.Consumer, E> action) throws E { s.forEach(action); } @ParallelSupported @TerminalOp public void forEach(final Throwables.BiConsumer action) throws E { s.forEach(Fn.Entries.ec(action)); } @ParallelSupported @TerminalOp public void forEachIndexed(final Throwables.IndexedConsumer, E> action) throws E { s.forEachIndexed(action); } @ParallelSupported @TerminalOp public Optional> min(Comparator> comparator) { return s.min(comparator); } @ParallelSupported @TerminalOp public Optional> minByKey(Comparator keyComparator) { return s.min(Comparators.comparingBy(Fn. key(), keyComparator)); } @ParallelSupported @TerminalOp public Optional> minByValue(Comparator valueComparator) { return s.min(Comparators.comparingBy(Fn. value(), valueComparator)); } @ParallelSupported @TerminalOp @SuppressWarnings("rawtypes") public Optional> minBy(final Function, ? extends Comparable> keyMapper) { return s.minBy(keyMapper); } @ParallelSupported @TerminalOp public Optional> max(Comparator> comparator) { return s.max(comparator); } @ParallelSupported @TerminalOp public Optional> maxByKey(Comparator keyComparator) { return s.max(Comparators.comparingBy(Fn. key(), keyComparator)); } @ParallelSupported @TerminalOp public Optional> maxByValue(Comparator valueComparator) { return s.max(Comparators.comparingBy(Fn. value(), valueComparator)); } @ParallelSupported @TerminalOp @SuppressWarnings("rawtypes") public Optional> maxBy(final Function, ? extends Comparable> keyMapper) { return s.maxBy(keyMapper); } @ParallelSupported @TerminalOp public boolean anyMatch(final Throwables.Predicate, E> predicate) throws E { return s.anyMatch(predicate); } @ParallelSupported @TerminalOp public boolean anyMatch(final Throwables.BiPredicate predicate) throws E { return s.anyMatch(Fn.Entries.ep(predicate)); } @ParallelSupported @TerminalOp public boolean allMatch(final Throwables.Predicate, E> predicate) throws E { return s.allMatch(predicate); } @ParallelSupported @TerminalOp public boolean allMatch(final Throwables.BiPredicate predicate) throws E { return s.allMatch(Fn.Entries.ep(predicate)); } @ParallelSupported @TerminalOp public boolean noneMatch(final Throwables.Predicate, E> predicate) throws E { return s.noneMatch(predicate); } @ParallelSupported @TerminalOp public boolean noneMatch(final Throwables.BiPredicate predicate) throws E { return s.noneMatch(Fn.Entries.ep(predicate)); } @ParallelSupported @TerminalOp public Optional> findFirst(final Throwables.Predicate, E> predicate) throws E { return s.findFirst(predicate); } @ParallelSupported @TerminalOp public Optional> findFirst(final Throwables.BiPredicate predicate) throws E { return s.findFirst(Fn.Entries.ep(predicate)); } @ParallelSupported @TerminalOp public Optional> findAny(final Throwables.Predicate, E> predicate) throws E { return s.findAny(predicate); } @ParallelSupported @TerminalOp public Optional> findAny(final Throwables.BiPredicate predicate) throws E { return s.findAny(Fn.Entries.ep(predicate)); } @Override public Optional> first() { return s.first(); } @Override public Optional> last() { return s.last(); } @Override public Optional> elementAt(final long position) { return s.elementAt(position); } @Override public Optional> onlyOne() throws DuplicatedResultException { return s.onlyOne(); } @Override public Optional>> percentiles() { return s.percentiles(); } @Override public long count() { return s.count(); } /** * Remember to close this Stream after the iteration is done, if needed. * * @return */ @Override public ObjIterator> iterator() { return s.iteratorEx(); } /** * Remember to close this Stream after the iteration is done, if needed. * * @return */ @SequentialOnly public BiIterator biIterator() { final ObjIterator> iter = s.iteratorEx(); final BooleanSupplier hasNext = () -> iter.hasNext(); final Consumer> output = new Consumer<>() { private Map.Entry entry = null; @Override public void accept(Pair t) { entry = iter.next(); t.set(entry.getKey(), entry.getValue()); } }; return BiIterator.generate(hasNext, output); } @Override protected Object[] toArray(boolean closeStream) { return s.toArray(closeStream); } @Override public List> toList() { return s.toList(); } @Override public Set> toSet() { return s.toSet(); } @Override public >> CC toCollection(Supplier supplier) { return s.toCollection(supplier); } @Override public Multiset> toMultiset() { return s.toMultiset(); } @Override public Multiset> toMultiset(Supplier>> supplier) { return s.toMultiset(supplier); } @Override public LongMultiset> toLongMultiset() { return s.toLongMultiset(); } @Override public LongMultiset> toLongMultiset(Supplier>> supplier) { return s.toLongMultiset(supplier); } @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 @TerminalOp 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 @TerminalOp 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 @TerminalOp 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); } } @SequentialOnly @TerminalOp public R toMapAndThen(Throwables.Function, R, E> func) throws E { return func.apply(toMap()); } @SequentialOnly @TerminalOp public ImmutableMap toImmutableMap() { return ImmutableMap.of(toMap()); } @SequentialOnly @TerminalOp public ImmutableMap toImmutableMap(final BinaryOperator mergeFunction) { return ImmutableMap.of(toMap(mergeFunction)); } /** * * @param keyMapper * @return * @see Collectors#toMultimap(Function, Function) */ @SequentialOnly @TerminalOp 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 @TerminalOp 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 * @return * @see Collectors#groupingBy(Function) */ @SequentialOnly @TerminalOp 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 @TerminalOp 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); } } @SequentialOnly @TerminalOp public R groupToAndThen(final Throwables.Function>, R, E> func) throws E { return func.apply(groupTo()); } @SequentialOnly @TerminalOp public Map.Entry reduce(final Map.Entry identity, final BinaryOperator> accumulator) { return s.reduce(identity, accumulator); } @ParallelSupported @TerminalOp public Optional> reduce(final BinaryOperator> accumulator) { return s.reduce(accumulator); } /** * * @param * @param supplier * @param accumulator * @param combiner * @return * @see Stream#collect(Supplier, BiConsumer, BiConsumer) */ @ParallelSupported @TerminalOp public R collect(final Supplier supplier, final BiConsumer> accumulator, final BiConsumer combiner) { return s.collect(supplier, accumulator, combiner); } /** * * @param * @param supplier * @param accumulator * @return * @see Stream#collect(Supplier, BiConsumer) */ @ParallelSupported @TerminalOp public R collect(final Supplier supplier, final BiConsumer> accumulator) { return s.collect(supplier, accumulator); } @ParallelSupported @TerminalOp public R collect(final Collector, A, R> collector) { return s.collect(collector); } @ParallelSupported @TerminalOp public R collect(final java.util.stream.Collector, A, R> collector) { return s.collect(collector); } @ParallelSupported @TerminalOp public RR collectAndThen(final Collector, A, R> downstream, final Throwables.Function finisher) throws E { return s.collectAndThen(downstream, finisher); } @ParallelSupported @TerminalOp public RR collectAndThen(final java.util.stream.Collector, A, R> downstream, final Throwables.Function finisher) throws E { return s.collectAndThen(downstream, finisher); } @Override public String join(CharSequence delimiter) { return join(delimiter, "", ""); } @Override public String join(CharSequence delimiter, CharSequence prefix, CharSequence suffix) { return join(delimiter, "=", prefix, suffix); } @SequentialOnly @TerminalOp public String join(CharSequence delimiter, CharSequence keyValueDelimiter) { return join(delimiter, keyValueDelimiter, "", ""); } @SequentialOnly @TerminalOp public String join(CharSequence delimiter, CharSequence keyValueDelimiter, CharSequence prefix, CharSequence suffix) { s.assertNotClosed(); try { final Joiner joiner = Joiner.with(delimiter, keyValueDelimiter, prefix, suffix).reuseCachedBuffer(); final Iterator> iter = s.iteratorEx(); while (iter.hasNext()) { joiner.appendEntry(iter.next()); } return joiner.toString(); } finally { close(); } } @SequentialOnly @TerminalOp public EntryStream chain(Function>, ? extends Stream>> transfer) { return of(transfer.apply(s)); } // @SequentialOnly // @IntermediateOp // @Beta // public EntryStream __(Function, EntryStream> transfer) { // return transfer.apply(this); // } // /** // * // * @param // * @param // * @param terminalOp should be terminal operation. // * @param mapper // * @return // */ // @TerminalOp // @Beta // public R __(final Function, U> terminalOp, final Function mapper) { // return mapper.apply(terminalOp.apply(this)); // } // // /** // * // * @param // * @param terminalOp should be terminal operation. // * @param action // * @return // */ // @TerminalOp // @Beta // public R __(final Function, R> terminalOp, final Consumer action) { // final R result = terminalOp.apply(this); // action.accept(result); // return result; // } @Override public boolean isParallel() { return s.isParallel(); } @Override public EntryStream sequential() { return s.isParallel() ? of(s.sequential()) : this; } @Override public EntryStream parallel() { return of(s.parallel()); } @Override public EntryStream parallel(final int threadNum) { return of(s.parallel(threadNum)); } @Override public EntryStream parallel(final int maxThreadNum, final Splitor splitor) { return of(s.parallel(maxThreadNum, splitor)); } @Override public EntryStream parallel(final int maxThreadNum, final Splitor splitor, final Executor executor) { return of(s.parallel(maxThreadNum, splitor, executor)); } @Override public EntryStream parallel(final int maxThreadNum, final Executor executor) { return of(s.parallel(maxThreadNum, executor)); } @Override public EntryStream parallel(final Executor executor) { return of(s.parallel(executor)); } @Override protected EntryStream parallel(final int maxThreadNum, final Splitor splitor, final AsyncExecutor asyncExecutor, final boolean cancelUncompletedThreads) { return of(s.parallel(maxThreadNum, splitor, asyncExecutor, cancelUncompletedThreads)); } @Override protected int maxThreadNum() { return s.maxThreadNum(); } @Override protected Splitor splitor() { return s.splitor(); } @Override protected AsyncExecutor asyncExecutor() { return s.asyncExecutor(); } @Override protected boolean cancelUncompletedThreads() { return s.cancelUncompletedThreads(); } /** * @return * @see Stream#mapToDisposableEntry(Function, Function) * @deprecated */ @SequentialOnly @Deprecated @Beta public EntryStream inversedToDisposableEntry() { checkState(!s.isParallel(), "inversedER can't be applied to parallel stream"); final Function, DisposableEntry> mapper = new Function<>() { private final ReusableEntry entry = new ReusableEntry<>(); @Override public DisposableEntry apply(Map.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 */ @SequentialOnly @Deprecated @Beta public EntryStream mapToDisposableEntry(final Function, ? extends KK> keyMapper, final Function, ? extends VV> valueMapper) { checkState(!s.isParallel(), "mapER can't be applied to parallel stream"); final Function, Map.Entry> mapper = new Function<>() { private final ReusableEntry entry = new ReusableEntry<>(); @Override public Map.Entry apply(Map.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 */ @SequentialOnly @Deprecated @Beta public EntryStream mapToDisposableEntry(final BiFunction keyMapper, final BiFunction valueMapper) { checkState(!s.isParallel(), "mapER can't be applied to parallel stream"); final Function, Map.Entry> mapper = new Function<>() { private final ReusableEntry entry = new ReusableEntry<>(); @Override public Map.Entry apply(Map.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 */ @SequentialOnly @Deprecated @Beta public EntryStream flatMapKeyToDisposableEntry(final Function> keyMapper) { checkState(!s.isParallel(), "flatMapKeyER can't be applied to parallel stream"); final Function, Stream>> mapper2 = e -> 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 flatMapp(mapper2); } /** * * @param keyMapper * @return * @see #mapToDisposableEntry(Function, Function) * @deprecated */ @SequentialOnly @Deprecated @Beta public EntryStream flattMapKeyToDisposableEntry(final Function> keyMapper) { checkState(!s.isParallel(), "flatMapKeyER can't be applied to parallel stream"); final Function, Stream>> mapper2 = e -> 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 flatMapp(mapper2); } /** * * @param valueMapper * @return * @see #mapToDisposableEntry(Function, Function) * @deprecated */ @SequentialOnly @Deprecated @Beta public EntryStream flatMapValueToDisposableEntry(final Function> valueMapper) { checkState(!s.isParallel(), "flatMapValueER can't be applied to parallel stream"); final Function, Stream>> mapper2 = e -> 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 flatMapp(mapper2); } /** * * @param valueMapper * @return * @see #mapToDisposableEntry(Function, Function) * @deprecated */ @SequentialOnly @Deprecated @Beta public EntryStream flattMapValueToDisposableEntry(final Function> valueMapper) { checkState(!s.isParallel(), "flatMapValueER can't be applied to parallel stream"); final Function, Stream>> mapper2 = e -> 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 flatMapp(mapper2); } @Override public EntryStream onClose(Runnable closeHandler) { return of(s.onClose(closeHandler)); } @Override public synchronized void close() { s.close(); } @Override 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 ofNullable(final Map.Entry entry) { if (entry == null) { return EntryStream. empty(); } return of(Stream.of(entry)); } 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 Iterable> 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 Iterable 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(); } return Stream.of(maps).flattMapToEntry(Fn.> identity()); } public static EntryStream concat(final Collection> maps) { if (N.isNullOrEmpty(maps)) { return EntryStream.empty(); } return Stream.of(maps).flattMapToEntry(Fn.> identity()); } public static EntryStream merge(final Map a, final Map b, final BiFunction, ? super Map.Entry, MergeResult> 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, MergeResult> 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, MergeResult> 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.mergeIterables(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 Iterable keys, final Iterable values) { if (keys == null || values == null) { 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 Iterable keys, final Iterable values, K valueForNonKey, V valueForNonValue) { if (keys == null && values == null) { 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 (this == obj) { 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