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

functionalj.stream.StreamPlusAddtionalOperators Maven / Gradle / Ivy

// ============================================================================
// Copyright (c) 2017-2019 Nawapunth Manusitthipol (NawaMan - http://nawaman.net).
// ----------------------------------------------------------------------------
// MIT License
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// ============================================================================
package functionalj.stream;

import static functionalj.tuple.Tuple.tuple2;

import java.util.Collection;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;

import functionalj.result.Result;
import functionalj.tuple.Tuple;
import functionalj.tuple.Tuple2;
import lombok.val;

public interface StreamPlusAddtionalOperators {
    
    
    public  StreamPlus deriveWith(
            Function, Stream> action);
    
    public  StreamPlus map(
            Function mapper);
    
    public  StreamPlus flatMap(
            Function> mapper);
    
    public StreamPlus filter(
            Predicate predicate);
    
    public StreamPlus peek(
            Consumer action);
    
    
    //--map with condition --
    
    public default StreamPlus mapOnly(
            Predicate      checker, 
            Function mapper) {
        return map(d -> checker.test(d) ? mapper.apply(d) : d);
    }
    
    public default  StreamPlus mapIf(
            Predicate   checker, 
            Function mapper, 
            Function elseMapper) {
        return map(d -> {
            return checker.test(d) 
                    ? mapper.apply(d) 
                    : elseMapper.apply(d);
        });
    }
    
    //-- mapWithIndex --
    
    public default StreamPlus> mapWithIndex() {
        val index = new AtomicInteger();
        return map(each -> tuple2(index.getAndIncrement(), each));
    }
    
    public default  StreamPlus mapWithIndex(
            BiFunction mapper) {
        val index = new AtomicInteger();
        return map(each -> mapper.apply(index.getAndIncrement(), each));
    }
    
    public default  StreamPlus mapWithIndex(
                Function       mapper1,
                BiFunction mapper) {
        val index = new AtomicInteger();
        return map(each -> mapper.apply(
                                index.getAndIncrement(),
                                mapper1.apply(each)));
    }
    
    //-- mapWithPrev --
    
    public default StreamPlus, ? super DATA>> mapWithPrev() {
        val prev = new AtomicReference>(Result.ofNotExist());
        return map(element -> {
            val prevValue = prev.get();
            prev.set(Result.valueOf(element));
            return Tuple.of(prevValue, element);
        });
    }
    
    public default  StreamPlus mapWithPrev(
            BiFunction, ? super DATA, ? extends TARGET> mapper) {
        val prev = new AtomicReference>(Result.ofNotExist());
        return map(element -> {
            val newValue = mapper.apply(prev.get(), element);
            prev.set(Result.valueOf(element));
            return newValue;
        });
    }
    
    //-- Filter --
    
    public default StreamPlus filterNonNull() {
        return deriveWith(stream -> stream.filter(Objects::nonNull));
    }
    
    public default StreamPlus filterIn(Collection collection) {
        return deriveWith(stream -> {
            return (collection == null)
                ? Stream.empty()
                : stream.filter(data -> collection.contains(data));
        });
    }
    
    public default StreamPlus exclude(Predicate predicate) {
        return deriveWith(stream -> {
            return (predicate == null)
                ? stream
                : stream.filter(data -> !predicate.test(data));
        });
    }
    
    public default StreamPlus excludeIn(Collection collection) {
        return deriveWith(stream -> {
            return (collection == null)
                ? stream
                : stream.filter(data -> !collection.contains(data));
        });
    }
    
    public default  StreamPlus filter(Class clzz) {
        return filter(clzz::isInstance);
    }
    
    public default  StreamPlus filter(Class clzz, Predicate theCondition) {
        return filter(value -> {
            if (!clzz.isInstance(value))
                return false;
            
            val target = clzz.cast(value);
            val isPass = theCondition.test(target);
            return isPass;
        });
    }
    
    public default  StreamPlus filter(Function mapper, Predicate theCondition) {
        return filter(value -> {
            val target = mapper.apply(value);
            val isPass = theCondition.test(target);
            return isPass;
        });
    }
    
    public default StreamPlus filterWithIndex(BiFunction predicate) {
        val index = new AtomicInteger();
        return filter(each -> {
                    return (predicate != null) 
                            && predicate.apply(index.getAndIncrement(), each);
        });
    }
    
    //-- Peek --
    
    public default  StreamPlus peek(Class clzz, Consumer theConsumer) {
        return peek(value -> {
            if (!clzz.isInstance(value))
                return;
            
            val target = clzz.cast(value);
            theConsumer.accept(target);
        });
    }
    public default StreamPlus peek(Predicate selector, Consumer theConsumer) {
        return peek(value -> {
            if (!selector.test(value))
                return;
            
            theConsumer.accept(value);
        });
    }
    public default  StreamPlus peek(Function mapper, Consumer theConsumer) {
        return peek(value -> {
            val target = mapper.apply(value);
            theConsumer.accept(target);
        });
    }
    
    public default  StreamPlus peek(Function mapper, Predicate selector, Consumer theConsumer) {
        return peek(value -> {
            val target = mapper.apply(value);
            if (selector.test(target))
                theConsumer.accept(target);
        });
    }
    
    //-- FlatMap --
    
    public default StreamPlus flatMapOnly(
            Predicate                        checker, 
            Function> mapper) {
        return flatMap(d -> checker.test(d) ? mapper.apply(d) : StreamPlus.of(d));
    }
    public default  StreamPlus flatMapIf(
            Predicate checker, 
            Function> mapper, 
            Function> elseMapper) {
        return flatMap(d -> checker.test(d) ? mapper.apply(d) : elseMapper.apply(d));
    }
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy