Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
functionalj.map.FuncMap 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.map;
import static functionalj.function.Func.it;
import static functionalj.stream.ZipWithOption.RequireBoth;
import static java.util.Arrays.stream;
import java.util.Comparator;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import functionalj.function.Func0;
import functionalj.function.Func1;
import functionalj.function.Func2;
import functionalj.function.FuncUnit1;
import functionalj.list.FuncList;
import functionalj.ref.Ref;
import functionalj.stream.ZipWithOption;
import functionalj.tuple.Tuple2;
import lombok.val;
@SuppressWarnings("javadoc")
public abstract class FuncMap
implements
ReadOnlyMap {
@SuppressWarnings({"unchecked", "rawtypes"})
public static enum UnderlineMap {
HashMap (java.util.HashMap::new),
LinkedHashMap(java.util.LinkedHashMap::new),
TreeMap (java.util.TreeMap::new);
private final Func0 newMap;
private UnderlineMap(Func0 newMap) {
this.newMap = newMap;
}
Map newMap() {
return (Map)newMap.apply();
}
}
public static Ref underlineMap = Ref.ofValue(UnderlineMap.HashMap);
public static class Entry implements Map.Entry, Tuple2 {
private final KEY key;
private final VALUE value;
public static Entry of(K key, V value) {
return new Entry(key, value);
}
public static Entry of(Map.Entry entry) {
if (entry == null)
return null;
if (entry instanceof Entry)
return (Entry)entry;
K key = entry.getKey();
V value = entry.getValue();
return new Entry(key, value);
}
public Entry(KEY key, VALUE value) {
this.key = key;
this.value = value;
}
@Override
public final KEY _1() {
return key;
}
@Override
public final VALUE _2() {
return value;
}
@Override
public final KEY getKey() {
return key;
}
@Override
public final VALUE getValue() {
return value;
}
@Override
public final VALUE setValue(VALUE value) {
throw new UnsupportedOperationException();
}
@Override
public final String toString() {
return key + "=" + value;
}
@Override
public final int hashCode() {
return Entry.class.hashCode() + Objects.hash(key, value);
}
@SuppressWarnings("unchecked")
@Override
public final boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof Entry))
return false;
val entry = (Entry)obj;
return Objects.equals(entry.getKey(), key)
&& Objects.equals(entry.getValue(), value);
}
}
public static ImmutableMap empty() {
return ImmutableMap.empty();
}
public static ImmutableMap emptyMap() {
return ImmutableMap.empty();
}
public static ImmutableMap empty(Class keyClass, Class valueClass) {
return ImmutableMap.empty();
}
public static ImmutableMap emptyMap(Class keyClass, Class valueClass) {
return ImmutableMap.empty();
}
public static ImmutableMap from(Map extends K, ? extends V> map) {
return new ImmutableMap(map);
}
public static ImmutableMap from(Stream extends Map.Entry extends K, ? extends V>> stream) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
stream
.forEach(entry -> map.put(entry.getKey(), entry.getValue()));
return new ImmutableMap(map);
}
@SafeVarargs
public static ImmutableMap ofEntries(Map.Entry ... entries) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
stream(entries)
.forEach(entry -> map.put(entry.getKey(), entry.getValue()));
return new ImmutableMap(map);
}
@SafeVarargs
public static ImmutableMap ofTuples(Tuple2 ... entries) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
stream(entries)
.forEach(entry -> map.put(entry._1(), entry._2()));
return new ImmutableMap(map);
}
public static ImmutableMap of(
K key0, V value0) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
return new ImmutableMap(map);
}
public static ImmutableMap of(
K key0, V value0,
K key1, V value1) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
return new ImmutableMap(map);
}
public static ImmutableMap of(
K key0, V value0,
K key1, V value1,
K key2, V value2) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
map.put(key2, value2);
return new ImmutableMap(map);
}
public static ImmutableMap of(
K key0, V value0,
K key1, V value1,
K key2, V value2,
K key3, V value3) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
map.put(key2, value2);
map.put(key3, value3);
return new ImmutableMap(map);
}
public static ImmutableMap of(
K key0, V value0,
K key1, V value1,
K key2, V value2,
K key3, V value3,
K key4, V value4) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
map.put(key2, value2);
map.put(key3, value3);
map.put(key4, value4);
return new ImmutableMap(map);
}
public static ImmutableMap of(
K key0, V value0,
K key1, V value1,
K key2, V value2,
K key3, V value3,
K key4, V value4,
K key5, V value5) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
map.put(key2, value2);
map.put(key3, value3);
map.put(key4, value4);
map.put(key5, value5);
return new ImmutableMap(map);
}
public static ImmutableMap of(
K key0, V value0,
K key1, V value1,
K key2, V value2,
K key3, V value3,
K key4, V value4,
K key5, V value5,
K key6, V value6) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
map.put(key2, value2);
map.put(key3, value3);
map.put(key4, value4);
map.put(key5, value5);
map.put(key6, value6);
return new ImmutableMap(map);
}
public static ImmutableMap of(
K key0, V value0,
K key1, V value1,
K key2, V value2,
K key3, V value3,
K key4, V value4,
K key5, V value5,
K key6, V value6,
K key7, V value7) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
map.put(key2, value2);
map.put(key3, value3);
map.put(key4, value4);
map.put(key5, value5);
map.put(key6, value6);
map.put(key7, value7);
return new ImmutableMap(map);
}
public static ImmutableMap of(
K key0, V value0,
K key1, V value1,
K key2, V value2,
K key3, V value3,
K key4, V value4,
K key5, V value5,
K key6, V value6,
K key7, V value7,
K key8, V value8) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
map.put(key2, value2);
map.put(key3, value3);
map.put(key4, value4);
map.put(key5, value5);
map.put(key6, value6);
map.put(key7, value7);
map.put(key8, value8);
return new ImmutableMap(map);
}
public static ImmutableMap of(
K key0, V value0,
K key1, V value1,
K key2, V value2,
K key3, V value3,
K key4, V value4,
K key5, V value5,
K key6, V value6,
K key7, V value7,
K key8, V value8,
K key9, V value9) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
map.put(key2, value2);
map.put(key3, value3);
map.put(key4, value4);
map.put(key5, value5);
map.put(key6, value6);
map.put(key7, value7);
map.put(key8, value8);
map.put(key9, value9);
return new ImmutableMap(map);
}
public static ImmutableMap of(
K key0, V value0,
K key1, V value1,
K key2, V value2,
K key3, V value3,
K key4, V value4,
K key5, V value5,
K key6, V value6,
K key7, V value7,
K key8, V value8,
K key9, V value9,
K key10, V value10) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
map.put(key2, value2);
map.put(key3, value3);
map.put(key4, value4);
map.put(key5, value5);
map.put(key6, value6);
map.put(key7, value7);
map.put(key8, value8);
map.put(key9, value9);
map.put(key10, value10);
return new ImmutableMap(map);
}
public FuncMap map(Function super VALUE, ? extends TARGET> mapper) {
return mapValue(v->mapper.apply(v));
}
public FuncMap map(BiFunction super KEY, ? super VALUE, ? extends TARGET> mapper) {
return mapEntry((k, v)->mapper.apply(k, v));
}
public FuncMap mapValue(Function super VALUE, ? extends TARGET> mapper) {
return map((k, v)->mapper.apply(v));
}
public abstract FuncMap mapEntry(BiFunction super KEY, ? super VALUE, ? extends TARGET> mapper);
public static ImmutableMap mapOf(
K key0, V value0) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
return new ImmutableMap(map);
}
public static ImmutableMap mapOf(
K key0, V value0,
K key1, V value1) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
return new ImmutableMap(map);
}
public static ImmutableMap mapOf(
K key0, V value0,
K key1, V value1,
K key2, V value2) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
map.put(key2, value2);
return new ImmutableMap(map);
}
public static ImmutableMap mapOf(
K key0, V value0,
K key1, V value1,
K key2, V value2,
K key3, V value3) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
map.put(key2, value2);
map.put(key3, value3);
return new ImmutableMap(map);
}
public static ImmutableMap mapOf(
K key0, V value0,
K key1, V value1,
K key2, V value2,
K key3, V value3,
K key4, V value4) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
map.put(key2, value2);
map.put(key3, value3);
map.put(key4, value4);
return new ImmutableMap(map);
}
public static ImmutableMap mapOf(
K key0, V value0,
K key1, V value1,
K key2, V value2,
K key3, V value3,
K key4, V value4,
K key5, V value5) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
map.put(key2, value2);
map.put(key3, value3);
map.put(key4, value4);
map.put(key5, value5);
return new ImmutableMap(map);
}
public static ImmutableMap mapOf(
K key0, V value0,
K key1, V value1,
K key2, V value2,
K key3, V value3,
K key4, V value4,
K key5, V value5,
K key6, V value6) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
map.put(key2, value2);
map.put(key3, value3);
map.put(key4, value4);
map.put(key5, value5);
map.put(key6, value6);
return new ImmutableMap(map);
}
public static ImmutableMap mapOf(
K key0, V value0,
K key1, V value1,
K key2, V value2,
K key3, V value3,
K key4, V value4,
K key5, V value5,
K key6, V value6,
K key7, V value7) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
map.put(key2, value2);
map.put(key3, value3);
map.put(key4, value4);
map.put(key5, value5);
map.put(key6, value6);
map.put(key7, value7);
return new ImmutableMap(map);
}
public static ImmutableMap mapOf(
K key0, V value0,
K key1, V value1,
K key2, V value2,
K key3, V value3,
K key4, V value4,
K key5, V value5,
K key6, V value6,
K key7, V value7,
K key8, V value8) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
map.put(key2, value2);
map.put(key3, value3);
map.put(key4, value4);
map.put(key5, value5);
map.put(key6, value6);
map.put(key7, value7);
map.put(key8, value8);
return new ImmutableMap(map);
}
public static ImmutableMap mapOf(
K key0, V value0,
K key1, V value1,
K key2, V value2,
K key3, V value3,
K key4, V value4,
K key5, V value5,
K key6, V value6,
K key7, V value7,
K key8, V value8,
K key9, V value9) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
map.put(key2, value2);
map.put(key3, value3);
map.put(key4, value4);
map.put(key5, value5);
map.put(key6, value6);
map.put(key7, value7);
map.put(key8, value8);
map.put(key9, value9);
return new ImmutableMap(map);
}
public static ImmutableMap mapOf(
K key0, V value0,
K key1, V value1,
K key2, V value2,
K key3, V value3,
K key4, V value4,
K key5, V value5,
K key6, V value6,
K key7, V value7,
K key8, V value8,
K key9, V value9,
K key10, V value10) {
val map = underlineMap.orElse(UnderlineMap.HashMap).newMap();
map.put(key0, value0);
map.put(key1, value1);
map.put(key2, value2);
map.put(key3, value3);
map.put(key4, value4);
map.put(key5, value5);
map.put(key6, value6);
map.put(key7, value7);
map.put(key8, value8);
map.put(key9, value9);
map.put(key10, value10);
return new ImmutableMap(map);
}
public static FuncMapBuilder newFuncMap() {
return new FuncMapBuilder();
}
public static FuncMapBuilder newMap() {
return new FuncMapBuilder();
}
public static FuncMapBuilder newBuilder() {
return new FuncMapBuilder();
}
public static FuncMapBuilder newFuncMap(Class keyClass, Class valueClass) {
return new FuncMapBuilder();
}
public static FuncMapBuilder newMap(Class keyClass, Class valueClass) {
return new FuncMapBuilder();
}
public static FuncMapBuilder newBuilder(Class keyClass, Class valueClass) {
return new FuncMapBuilder();
}
// TODO Map builder.
public boolean isLazy() {
return true;
}
public boolean isEager() {
return false;
}
public abstract FuncMap lazy();
public abstract FuncMap eager();
@Override
public abstract int size();
@Override
public abstract boolean isEmpty();
public abstract boolean hasKey(KEY key);
public abstract boolean hasValue(VALUE value);
public abstract boolean hasKey(Predicate super KEY> keyCheck);
public abstract boolean hasValue(Predicate super VALUE> valueCheck);
public abstract Optional findBy(KEY key);
public abstract FuncList select(Predicate super KEY> keyPredicate);
public abstract FuncList> selectEntry(Predicate super KEY> keyPredicate);
public abstract FuncMap with(KEY key, VALUE value);
public abstract FuncMap withAll(Map extends KEY, ? extends VALUE> entries);
public abstract FuncMap exclude(KEY key);
public abstract FuncMap filter(Predicate super KEY> keyCheck);
public abstract FuncMap filter(BiPredicate super KEY, ? super VALUE> entryCheck);
public abstract FuncMap filterByEntry(Predicate super Map.Entry super KEY, ? super VALUE>> entryCheck);
public abstract FuncList keys();
public abstract FuncList values();
public abstract Set> entrySet();
public abstract FuncList> entries();
public abstract Map toMap();
public abstract ImmutableMap toImmutableMap();
public Func1 toFunction() {
return this::get;
}
public Func1 toFunction(VALUE elseValue) {
return key -> {
try {
val value = this.get(key);
return (value == null) ? elseValue : value;
} catch (Exception e) {
return elseValue;
}
};
}
public Func1 toFunction(Func0 elseSupplier) {
return key -> {
try {
val value = this.get(key);
return (value == null) ? elseSupplier.get() : value;
} catch (Exception e) {
return elseSupplier.get();
}
};
}
public Func1 toFunction(Func1 elseProvider) {
return key -> {
try {
val value = this.get(key);
return (value == null) ? elseProvider.apply(key) : value;
} catch (Exception e) {
return elseProvider.apply(key);
}
};
}
public Func1 toFunction(FuncUnit1 action, VALUE elseValue) {
return key -> {
try {
val value = this.get(key);
if (value == null)
action.accept(key);
return value;
} catch (Exception e) {
return elseValue;
}
};
}
public Func1 toFunction(FuncUnit1 action, Func0 elseSupplier) {
return key -> {
try {
val value = this.get(key);
if (value == null)
action.accept(key);
return (value == null) ? elseSupplier.get() : value;
} catch (Exception e) {
return elseSupplier.get();
}
};
}
public Func1 toFunction(FuncUnit1 action, Func1 elseProvider) {
return key -> {
try {
val value = this.get(key);
if (value == null)
action.accept(key);
if (value == null)
action.accept(key);
return (value == null) ? elseProvider.apply(key) : value;
} catch (Exception e) {
return elseProvider.apply(key);
}
};
}
public ImmutableMap freeze() {
return toImmutableMap();
}
public abstract FuncMap sorted();
public abstract FuncMap sorted(Comparator super Map.Entry> comparator);
public abstract FuncMap sortedByKey(Comparator super KEY> comparator);
public abstract FuncMap sortedByValue(Comparator super VALUE> comparator);
public abstract void forEach(BiConsumer super KEY, ? super VALUE> action);
public abstract void forEach(Consumer super Map.Entry super KEY, ? super VALUE>> action);
public FuncMap zipWith(Map anotherMap, Func2 merger) {
return zipWith(anotherMap, RequireBoth, merger);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public FuncMap zipWith(Map anotherMap, ZipWithOption option, Func2 merger) {
val keys1 = this.keys();
val keys2 = FuncList.from(anotherMap.keySet());
val map = keys1.appendAll(keys2.excludeIn(keys1))
.filter(key -> !(option == RequireBoth) || (this.containsKey(key) && anotherMap.containsKey(key)))
.toMap(it(), key -> {
val v1 = this.get(key);
val v2 = anotherMap.get(key);
return merger.apply(v1, v2);
});
return (FuncMap)map;
}
public String toString() {
return "{" +
entries()
.map(String::valueOf)
.collect(Collectors.joining(", ")) +
"}";
}
@Override
public int hashCode() {
return FuncMap.class.hashCode() + entries().hashCode();
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public boolean equals(Object o) {
if (!(o instanceof Map))
return false;
val thatMap = (Map)o;
if (thatMap.size() != size())
return false;
val keyExist = ((Predicate)((Map)o)::containsKey).negate();
val hasMissingKey = keys().anyMatch(keyExist);
if (hasMissingKey)
return false;
val matchEntry = (Predicate super Map.Entry>)(t -> {
val key = t.getKey();
val thatValue = this.get(key);
val thisValue = t.getValue();
return Objects.equals(thatValue, thisValue);
});
val allMatchValue
= thatMap
.entrySet().stream()
.allMatch(matchEntry);
return allMatchValue;
}
}