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

com.landawn.abacus.util.Builder Maven / Gradle / Ivy

There is a newer version: 1.2.9
Show newest version
/*
 * Copyright (C) 2016 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;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import com.landawn.abacus.util.function.Supplier;

/**
 * 
 * @param 
 * @since 0.8
 * 
 * @author haiyangl
 */
public class Builder {
    final T val;

    Builder(T val) {
        N.requireNonNull(val);

        this.val = val;
    }

    /**
     * 
     * @param val
     * @return
     * @throws NullPointerException if the specified {@code val} is {@code null}.
     */
    public static final BooleanListBuilder of(BooleanList val) {
        return new BooleanListBuilder(val);
    }

    /**
     * 
     * @param val
     * @return
     * @throws NullPointerException if the specified {@code val} is {@code null}.
     */
    public static final CharListBuilder of(CharList val) {
        return new CharListBuilder(val);
    }

    /**
     * 
     * @param val
     * @return
     * @throws NullPointerException if the specified {@code val} is {@code null}.
     */
    public static final ByteListBuilder of(ByteList val) {
        return new ByteListBuilder(val);
    }

    /**
     * 
     * @param val
     * @return
     * @throws NullPointerException if the specified {@code val} is {@code null}.
     */
    public static final ShortListBuilder of(ShortList val) {
        return new ShortListBuilder(val);
    }

    /**
     * 
     * @param val
     * @return
     * @throws NullPointerException if the specified {@code val} is {@code null}.
     */
    public static final IntListBuilder of(IntList val) {
        return new IntListBuilder(val);
    }

    /**
     * 
     * @param val
     * @return
     * @throws NullPointerException if the specified {@code val} is {@code null}.
     */
    public static final LongListBuilder of(LongList val) {
        return new LongListBuilder(val);
    }

    /**
     * 
     * @param val
     * @return
     * @throws NullPointerException if the specified {@code val} is {@code null}.
     */
    public static final FloatListBuilder of(FloatList val) {
        return new FloatListBuilder(val);
    }

    /**
     * 
     * @param val
     * @return
     * @throws NullPointerException if the specified {@code val} is {@code null}.
     */
    public static final DoubleListBuilder of(DoubleList val) {
        return new DoubleListBuilder(val);
    }

    /**
     * 
     * @param val
     * @return
     * @throws NullPointerException if the specified {@code val} is {@code null}.
     */
    public static final > ListBuilder of(L val) {
        return new ListBuilder<>(val);
    }

    /**
     * 
     * @param val
     * @return
     * @throws NullPointerException if the specified {@code val} is {@code null}.
     */
    public static final > CollectionBuilder of(C val) {
        return new CollectionBuilder<>(val);
    }

    /**
     * 
     * @param val
     * @return
     * @throws NullPointerException if the specified {@code val} is {@code null}.
     */
    public static final > MapBuilder of(M val) {
        return new MapBuilder<>(val);
    }

    /**
     * 
     * @param val
     * @return
     * @throws NullPointerException if the specified {@code val} is {@code null}.
     */
    public static final  MultisetBuilder of(Multiset val) {
        return new MultisetBuilder<>(val);
    }

    /**
     * 
     * @param val
     * @return
     * @throws NullPointerException if the specified {@code val} is {@code null}.
     */
    public static final  LongMultisetBuilder of(LongMultiset val) {
        return new LongMultisetBuilder<>(val);
    }

    /**
     * 
     * @param val
     * @return
     * @throws NullPointerException if the specified {@code val} is {@code null}.
     */
    public static final , M extends Multimap> MultimapBuilder of(M val) {
        return new MultimapBuilder<>(val);
    }

    /**
     * 
     * @param val
     * @return
     * @throws NullPointerException if the specified {@code val} is {@code null}.
     */
    public static final  Builder of(T val) {
        return new Builder<>(val);
    }

    //    public static  Builder get(final Supplier supplier) {
    //        return new Builder<>(supplier.get());
    //    }

    public T val() {
        return val;
    }

    public  Builder accept(final Try.Consumer consumer) throws E {
        consumer.accept(val);

        return this;
    }

    public  Builder map(final Try.Function mapper) throws E {
        return of(mapper.apply(val));
    }

    /**
     * 
     * @param predicate
     * @return Optional with the value if predicate returns true, 
     * otherwise, return an empty Optional
     */
    public  Optional filter(final Try.Predicate predicate) throws E {
        return predicate.test(val) ? Optional.of(val) : Optional. empty();
    }

    //    /**
    //    * Returns an empty Nullable if {@code val()} is {@code null} while {@code targetType} is primitive or can't be assigned to {@code targetType}.
    //    * Please be aware that {@code null} can be assigned to any {@code Object} type except primitive types: {@code boolean/char/byte/short/int/long/double}.
    //    * 
    //    * @param val
    //    * @param targetType
    //    * @return
    //    */
    //    @SuppressWarnings("unchecked")
    //    public  Nullable castIfAssignable(final Class targetType) {
    //        if (N.isPrimitive(targetType)) {
    //            return val != null && N.wrapperOf(targetType).isAssignableFrom(val.getClass()) ? Nullable.of((TT) val) : Nullable. empty();
    //        }
    //
    //        return val == null || targetType.isAssignableFrom(val.getClass()) ? Nullable.of((TT) val) : Nullable. empty();
    //    }
    //
    //    /**
    //     * 
    //     * @param b
    //     * @param actionForTrue do nothing if it's {@code null} even {@code b} is true.
    //     * @param actionForFalse do nothing if it's {@code null} even {@code b} is false.
    //     * @throws E1
    //     * @throws E2
    //     */
    //    public  void ifOrElse(final boolean b, final Try.Consumer actionForTrue,
    //            final Try.Consumer actionForFalse) throws E1, E2 {
    //        if (b) {
    //            if (actionForTrue != null) {
    //                actionForTrue.accept(val);
    //            }
    //        } else {
    //            if (actionForFalse != null) {
    //                actionForFalse.accept(val);
    //            }
    //        }
    //    }
    //
    //    /**
    //     * 
    //     * @param predicate
    //     * @param actionForTrue do nothing if it's {@code null} even {@code b} is true.
    //     * @param actionForFalse do nothing if it's {@code null} even {@code b} is false.
    //     * @throws E0
    //     * @throws E1
    //     * @throws E2
    //     */
    //    public  void ifOrElse(final Try.Predicate predicate,
    //            final Try.Consumer actionForTrue, final Try.Consumer actionForFalse) throws E0, E1, E2 {
    //        if (predicate.test(val)) {
    //            if (actionForTrue != null) {
    //                actionForTrue.accept(val);
    //            }
    //        } else {
    //            if (actionForFalse != null) {
    //                actionForFalse.accept(val);
    //            }
    //        }
    //    }
    //
    //    /**
    //     * Returns an empty {@code Optional} if {@code cmd} is executed successfully, otherwise a {@code Optional} with the exception threw.
    //     * 
    //     * @param cmd
    //     * @return
    //     */
    //    public Optional run(final Try.Consumer cmd) {
    //        try {
    //            cmd.accept(val);
    //            return Optional.empty();
    //        } catch (Exception e) {
    //            return Optional.of(e);
    //        }
    //    }
    //
    //    /**
    //     * Returns a {@code Pair} with {@code left=returnedValue, right=null} if {@code cmd} is executed successfully, otherwise a {@code Pair} with {@code left=null, right=exception}.
    //     * 
    //     * @param cmd
    //     * @return
    //     */
    //    public  Pair call(final Try.Function cmd) {
    //        try {
    //            return Pair.of(cmd.apply(val), null);
    //        } catch (Exception e) {
    //            return Pair.of(null, e);
    //        }
    //    }
    //
    //    /**
    //     * Returns a {@code Nullable} with the value returned by {@code action} or an empty {@code Nullable} if exception happens.
    //     * 
    //     * @param cmd
    //     * @return
    //     */
    //    public  Nullable tryOrEmpty(final Try.Function cmd) {
    //        try {
    //            return Nullable.of(cmd.apply(val));
    //        } catch (Throwable e) {
    //            return Nullable. empty();
    //        }
    //    }

    public static final class BooleanListBuilder extends Builder {
        BooleanListBuilder(BooleanList val) {
            super(val);
        }

        public BooleanListBuilder set(int index, boolean e) {
            val.set(index, e);

            return this;
        }

        public BooleanListBuilder add(boolean e) {
            val.add(e);

            return this;
        }

        public BooleanListBuilder add(int index, boolean e) {
            val.add(index, e);

            return this;
        }

        public BooleanListBuilder addAll(BooleanList c) {
            val.addAll(c);

            return this;
        }

        public BooleanListBuilder addAll(int index, BooleanList c) {
            val.addAll(index, c);

            return this;
        }

        public BooleanListBuilder remove(boolean e) {
            val.remove(e);

            return this;
        }

        //        public BooleanListBuilder removeAllOccurrences(double e) {
        //            value.removeAllOccurrences(e);
        //
        //            return this;
        //        }

        public BooleanListBuilder removeAll(BooleanList c) {
            val.removeAll(c);

            return this;
        }
    }

    public static final class CharListBuilder extends Builder {
        CharListBuilder(CharList val) {
            super(val);
        }

        public CharListBuilder set(int index, char e) {
            val.set(index, e);

            return this;
        }

        public CharListBuilder add(char e) {
            val.add(e);

            return this;
        }

        public CharListBuilder add(int index, char e) {
            val.add(index, e);

            return this;
        }

        public CharListBuilder addAll(CharList c) {
            val.addAll(c);

            return this;
        }

        public CharListBuilder addAll(int index, CharList c) {
            val.addAll(index, c);

            return this;
        }

        public CharListBuilder remove(char e) {
            val.remove(e);

            return this;
        }

        //        public CharListBuilder removeAllOccurrences(double e) {
        //            value.removeAllOccurrences(e);
        //
        //            return this;
        //        }

        public CharListBuilder removeAll(CharList c) {
            val.removeAll(c);

            return this;
        }
    }

    public static final class ByteListBuilder extends Builder {
        ByteListBuilder(ByteList val) {
            super(val);
        }

        public ByteListBuilder set(int index, byte e) {
            val.set(index, e);

            return this;
        }

        public ByteListBuilder add(byte e) {
            val.add(e);

            return this;
        }

        public ByteListBuilder add(int index, byte e) {
            val.add(index, e);

            return this;
        }

        public ByteListBuilder addAll(ByteList c) {
            val.addAll(c);

            return this;
        }

        public ByteListBuilder addAll(int index, ByteList c) {
            val.addAll(index, c);

            return this;
        }

        public ByteListBuilder remove(byte e) {
            val.remove(e);

            return this;
        }

        //        public ByteListBuilder removeAllOccurrences(double e) {
        //            value.removeAllOccurrences(e);
        //
        //            return this;
        //        }

        public ByteListBuilder removeAll(ByteList c) {
            val.removeAll(c);

            return this;
        }
    }

    public static final class ShortListBuilder extends Builder {
        ShortListBuilder(ShortList val) {
            super(val);
        }

        public ShortListBuilder set(int index, short e) {
            val.set(index, e);

            return this;
        }

        public ShortListBuilder add(short e) {
            val.add(e);

            return this;
        }

        public ShortListBuilder add(int index, short e) {
            val.add(index, e);

            return this;
        }

        public ShortListBuilder addAll(ShortList c) {
            val.addAll(c);

            return this;
        }

        public ShortListBuilder addAll(int index, ShortList c) {
            val.addAll(index, c);

            return this;
        }

        public ShortListBuilder remove(short e) {
            val.remove(e);

            return this;
        }

        //        public ShortListBuilder removeAllOccurrences(double e) {
        //            value.removeAllOccurrences(e);
        //
        //            return this;
        //        }

        public ShortListBuilder removeAll(ShortList c) {
            val.removeAll(c);

            return this;
        }
    }

    public static final class IntListBuilder extends Builder {
        IntListBuilder(IntList val) {
            super(val);
        }

        public IntListBuilder set(int index, int e) {
            val.set(index, e);

            return this;
        }

        public IntListBuilder add(int e) {
            val.add(e);

            return this;
        }

        public IntListBuilder add(int index, int e) {
            val.add(index, e);

            return this;
        }

        public IntListBuilder addAll(IntList c) {
            val.addAll(c);

            return this;
        }

        public IntListBuilder addAll(int index, IntList c) {
            val.addAll(index, c);

            return this;
        }

        public IntListBuilder remove(int e) {
            val.remove(e);

            return this;
        }

        //        public IntListBuilder removeAllOccurrences(double e) {
        //            value.removeAllOccurrences(e);
        //
        //            return this;
        //        }

        public IntListBuilder removeAll(IntList c) {
            val.removeAll(c);

            return this;
        }
    }

    public static final class LongListBuilder extends Builder {
        LongListBuilder(LongList val) {
            super(val);
        }

        public LongListBuilder set(int index, long e) {
            val.set(index, e);

            return this;
        }

        public LongListBuilder add(long e) {
            val.add(e);

            return this;
        }

        public LongListBuilder add(int index, long e) {
            val.add(index, e);

            return this;
        }

        public LongListBuilder addAll(LongList c) {
            val.addAll(c);

            return this;
        }

        public LongListBuilder addAll(int index, LongList c) {
            val.addAll(index, c);

            return this;
        }

        public LongListBuilder remove(long e) {
            val.remove(e);

            return this;
        }

        //        public LongListBuilder removeAllOccurrences(double e) {
        //            value.removeAllOccurrences(e);
        //
        //            return this;
        //        }

        public LongListBuilder removeAll(LongList c) {
            val.removeAll(c);

            return this;
        }
    }

    public static final class FloatListBuilder extends Builder {
        FloatListBuilder(FloatList val) {
            super(val);
        }

        public FloatListBuilder set(int index, float e) {
            val.set(index, e);

            return this;
        }

        public FloatListBuilder add(float e) {
            val.add(e);

            return this;
        }

        public FloatListBuilder add(int index, float e) {
            val.add(index, e);

            return this;
        }

        public FloatListBuilder addAll(FloatList c) {
            val.addAll(c);

            return this;
        }

        public FloatListBuilder addAll(int index, FloatList c) {
            val.addAll(index, c);

            return this;
        }

        public FloatListBuilder remove(float e) {
            val.remove(e);

            return this;
        }

        //        public FloatListBuilder removeAllOccurrences(double e) {
        //            value.removeAllOccurrences(e);
        //
        //            return this;
        //        }

        public FloatListBuilder removeAll(FloatList c) {
            val.removeAll(c);

            return this;
        }
    }

    public static final class DoubleListBuilder extends Builder {
        DoubleListBuilder(DoubleList val) {
            super(val);
        }

        public DoubleListBuilder set(int index, double e) {
            val.set(index, e);

            return this;
        }

        public DoubleListBuilder add(double e) {
            val.add(e);

            return this;
        }

        public DoubleListBuilder add(int index, double e) {
            val.add(index, e);

            return this;
        }

        public DoubleListBuilder addAll(DoubleList c) {
            val.addAll(c);

            return this;
        }

        public DoubleListBuilder addAll(int index, DoubleList c) {
            val.addAll(index, c);

            return this;
        }

        public DoubleListBuilder remove(double e) {
            val.remove(e);

            return this;
        }

        //        public DoubleListBuilder removeAllOccurrences(double e) {
        //            value.removeAllOccurrences(e);
        //
        //            return this;
        //        }

        public DoubleListBuilder removeAll(DoubleList c) {
            val.removeAll(c);

            return this;
        }
    }

    public static final class ListBuilder> extends CollectionBuilder {
        ListBuilder(L c) {
            super(c);
        }

        public ListBuilder add(int index, T e) {
            val.add(index, e);

            return this;
        }

        public ListBuilder addAll(int index, Collection c) {
            N.checkIndex(index, val.size());

            if (N.notNullOrEmpty(c)) {
                val.addAll(index, c);
            }

            return this;
        }

        public ListBuilder remove(int index) {
            val.remove(index);

            return this;
        }
    }

    public static class CollectionBuilder> extends Builder {
        CollectionBuilder(C c) {
            super(c);
        }

        public CollectionBuilder add(T e) {
            val.add(e);

            return this;
        }

        public CollectionBuilder addAll(final Collection c) {
            if (N.notNullOrEmpty(c)) {
                val.addAll(c);
            }

            return this;
        }

        public CollectionBuilder remove(Object e) {
            val.remove(e);

            return this;
        }

        public CollectionBuilder removeAll(Collection c) {
            if (N.notNullOrEmpty(c)) {
                val.removeAll(c);
            }

            return this;
        }
    }

    public static final class MultisetBuilder extends Builder> {
        MultisetBuilder(Multiset c) {
            super(c);
        }

        public MultisetBuilder add(T e) {
            val.add(e);

            return this;
        }

        public MultisetBuilder addAll(final Collection c) {
            val.addAll(c);

            return this;
        }

        public MultisetBuilder addAll(final Map m) {
            val.addAll(m);

            return this;
        }

        public MultisetBuilder addAll(final Multiset multiset) {
            val.addAll(multiset);

            return this;
        }

        public MultisetBuilder remove(Object e) {
            val.remove(e);

            return this;
        }

        public MultisetBuilder removeAll(Collection c) {
            val.removeAll(c);

            return this;
        }

        public MultisetBuilder removeAll(final Map m) {
            val.removeAll(m);

            return this;
        }

        public MultisetBuilder removeAll(Multiset multiset) {
            val.removeAll(multiset);

            return this;
        }
    }

    public static final class LongMultisetBuilder extends Builder> {
        LongMultisetBuilder(LongMultiset c) {
            super(c);
        }

        public LongMultisetBuilder add(T e) {
            val.add(e);

            return this;
        }

        public LongMultisetBuilder addAll(final Collection c) {
            val.addAll(c);

            return this;
        }

        public LongMultisetBuilder addAll(final Map m) {
            val.addAll(m);

            return this;
        }

        public LongMultisetBuilder addAll(final LongMultiset multiset) {
            val.addAll(multiset);

            return this;
        }

        public LongMultisetBuilder remove(Object e) {
            val.remove(e);

            return this;
        }

        public LongMultisetBuilder removeAll(Collection c) {
            val.removeAll(c);

            return this;
        }

        public LongMultisetBuilder removeAll(final Map m) {
            val.removeAll(m);

            return this;
        }

        public LongMultisetBuilder removeAll(LongMultiset multiset) {
            val.removeAll(multiset);

            return this;
        }
    }

    public static final class MapBuilder> extends Builder {
        MapBuilder(M m) {
            super(m);
        }

        public MapBuilder put(K k, V v) {
            val.put(k, v);

            return this;
        }

        public MapBuilder putAll(Map m) {
            if (N.notNullOrEmpty(m)) {
                val.putAll(m);
            }

            return this;
        }

        public MapBuilder putIfAbsent(K key, V value) {
            V v = val.get(key);

            if (v == null) {
                v = val.put(key, value);
            }

            return this;
        }

        public MapBuilder putIfAbsent(K key, Supplier supplier) {
            V v = val.get(key);

            if (v == null) {
                v = val.put(key, supplier.get());
            }

            return this;
        }

        public MapBuilder remove(Object k) {
            val.remove(k);

            return this;
        }

        public MapBuilder removeAll(Collection keysToRemove) {
            if (N.notNullOrEmpty(keysToRemove)) {
                for (Object k : keysToRemove) {
                    val.remove(k);
                }
            }

            return this;
        }
    }

    public static final class MultimapBuilder, M extends Multimap> extends Builder {
        MultimapBuilder(M m) {
            super(m);
        }

        public MultimapBuilder put(K key, E e) {
            val.put(key, e);

            return this;
        }

        public MultimapBuilder putAll(final K k, final Collection c) {
            val.putAll(k, c);

            return this;
        }

        public MultimapBuilder putAll(Map m) {
            val.putAll(m);

            return this;
        }

        public MultimapBuilder putAll(Multimap m) {
            val.putAll(m);

            return this;
        }

        public MultimapBuilder remove(Object k, Object e) {
            val.remove(k, e);

            return this;
        }

        public MultimapBuilder removeAll(Object k) {
            val.removeAll(k);

            return this;
        }

        public MultimapBuilder removeAll(Object k, Collection valuesToRemove) {
            val.removeAll(k, valuesToRemove);

            return this;
        }

        public MultimapBuilder removeAll(Map m) {
            val.removeAll(m);

            return this;
        }

        public MultimapBuilder removeAll(Multimap m) {
            val.removeAll(m);

            return this;
        }
    }

    public static final class X extends Builder {
        private X(T val) {
            super(val);
        }

        /**
         * 
         * @param output
         * @param e
         * @return return the specified {@code output}
         */
        public static > C add(final C output, final E e) {
            output.add(e);
            return output;
        }

        /**
         * 
         * @param output
         * @param e
         * @return return the specified {@code output}
         */
        public static > C addAll(final C output, final Collection c) {
            if (c == null || c.size() == 0) {
                return output;
            }

            output.addAll(c);
            return output;
        }

        /**
         * 
         * @param output
         * @param e
         * @return return the specified {@code output}
         */
        public static > C remove(final C output, final Object e) {
            if (output == null || output.size() == 0) {
                return output;
            }

            output.remove(e);
            return output;
        }

        /**
         * 
         * @param output
         * @param e
         * @return return the specified {@code output}
         */
        public static > C removeAll(final C output, final Collection c) {
            if (output == null || output.size() == 0 || c == null || c.size() == 0) {
                return output;
            }

            output.removeAll(c);
            return output;
        }

        /**
         * 
         * @param output
         * @param key
         * @param value
         * @return
         * @return return the specified {@code output}
         */
        public static > M put(final M output, K key, final V value) {
            output.put(key, value);
            return output;
        }

        /**
         * 
         * @param output
         * @param entryToAdd
         * @return
         * @return return the specified {@code output}
         */
        public static > M put(final M output, final Map.Entry entryToAdd) {
            output.put(entryToAdd.getKey(), entryToAdd.getValue());
            return output;
        }

        /**
         * 
         * @param output
         * @param entriesToAdd
         * @return
         * @return return the specified {@code output}
         */
        public static > M putAll(final M output, final Map entriesToAdd) {
            if (entriesToAdd == null || entriesToAdd.size() == 0) {
                return output;
            }

            output.putAll(entriesToAdd);
            return output;
        }

        /**
         * 
         * @param output
         * @param key
         * @param value
         * @return
         * @return return the specified {@code output}
         */
        public static > M putIfAbsent(final M output, K key, final V value) {
            if (!output.containsKey(key)) {
                output.put(key, value);
            }

            return output;
        }

        /**
         * 
         * @param output
         * @param entryToAdd
         * @return
         * @return return the specified {@code output}
         */
        public static > M putIfAbsent(final M output, final Map.Entry entryToAdd) {
            if (!output.containsKey(entryToAdd.getKey())) {
                output.put(entryToAdd.getKey(), entryToAdd.getValue());
            }
            return output;
        }

        /**
         * 
         * @param output
         * @param key
         * @param oldValue
         * @param newValue
         * @return return the specified {@code output}
         */
        public static > M replace(final M output, final K key, final V newValue) {
            if (output == null || output.size() == 0) {
                return output;
            }

            final V curValue = output.get(key);

            if ((curValue != null || output.containsKey(key))) {
                output.put(key, newValue);
            }

            return output;
        }

        /**
         * 
         * @param output
         * @param key
         * @param oldValue
         * @param newValue
         * @return return the specified {@code output}
         */
        public static > M replace(final M output, final K key, final V oldValue, final V newValue) {
            if (output == null || output.size() == 0) {
                return output;
            }

            final V curValue = output.get(key);

            if ((curValue != null || output.containsKey(key)) && N.equals(curValue, oldValue)) {
                output.put(key, newValue);
            }

            return output;
        }

        /**
         * 
         * @param output
         * @param key
         * @return
         * @return return the specified {@code output}
         */
        public static > M remove(final M output, final Object key) {
            if (output == null || output.size() == 0) {
                return output;
            }

            output.remove(key);
            return output;
        }

        /**
         * 
         * @param output
         * @param key
         * @return
         * @return return the specified {@code output}
         */
        public static > M remove(final M output, final Map.Entry entryToRemove) {
            if (output == null || output.size() == 0) {
                return output;
            }

            if (N.equals(output.get(entryToRemove.getKey()), entryToRemove.getValue())) {
                output.remove(entryToRemove.getKey());
            }

            return output;
        }

        /**
         * 
         * @param output
         * @param key
         * @param value
         * @return
         * @return return the specified {@code output}
         */
        public static > M remove(final M output, final Object key, final Object value) {
            if (output == null || output.size() == 0) {
                return output;
            }

            if (N.equals(output.get(key), value)) {
                output.remove(key);
            }

            return output;
        }

        /**
         * 
         * @param output
         * @param keys
         * @return
         * @return return the specified {@code output}
         */
        public static > M removeAll(final M output, final Collection keys) {
            if (output == null || output.size() == 0 || keys == null || keys.size() == 0) {
                return output;
            }

            for (Object key : keys) {
                output.remove(key);
            }

            return output;
        }

        /**
         * 
         * @param output
         * @param entriesToRemove
         * @return
         * @return return the specified {@code output}
         */
        public static > M removeAll(final M output, final Map entriesToRemove) {
            if (output == null || output.size() == 0 || entriesToRemove == null || entriesToRemove.size() == 0) {
                return output;
            }

            for (Map.Entry entry : entriesToRemove.entrySet()) {
                if (N.equals(output.get(entry.getKey()), entry.getValue())) {
                    output.remove(entry.getKey());
                }
            }

            return output;
        }
    }
}