|
@@ -32,45 +32,65 @@ public class MapUtils {
|
|
|
* Returned view does not support modifications.
|
|
* Returned view does not support modifications.
|
|
|
*
|
|
*
|
|
|
* @param map source map
|
|
* @param map source map
|
|
|
- * @param function mapping function
|
|
|
|
|
|
|
+ * @param function function
|
|
|
* @param <K> K
|
|
* @param <K> K
|
|
|
* @param <TV> source type
|
|
* @param <TV> source type
|
|
|
* @param <RV> target type
|
|
* @param <RV> target type
|
|
|
* @return read-only view
|
|
* @return read-only view
|
|
|
*/
|
|
*/
|
|
|
public static <K, TV, RV> Map<K,RV> map(Map<K,TV> map, Function<? super TV, ? extends RV> function) {
|
|
public static <K, TV, RV> Map<K,RV> map(Map<K,TV> map, Function<? super TV, ? extends RV> function) {
|
|
|
- return new MapAdapter<>(map, function, null);
|
|
|
|
|
|
|
+ return new MapAdapterKV<>(map, function, null);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* Creates view which transforms values stored inside source map.
|
|
* Creates view which transforms values stored inside source map.
|
|
|
- * Returned view supports modifications: it uses second function to apply inverted conversion.
|
|
|
|
|
|
|
+ * Returned view supports modifications: it uses passed projection for conversion in both directions.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param map source map
|
|
|
|
|
+ * @param projection projection
|
|
|
|
|
+ * @param <K> K
|
|
|
|
|
+ * @param <TV> source type
|
|
|
|
|
+ * @param <RV> target type
|
|
|
|
|
+ * @return mutable view
|
|
|
|
|
+ */
|
|
|
|
|
+ public static <K, TV, RV> Map<K,RV> map(Map<K,TV> map, ProjectionFunction<TV, RV> projection) {
|
|
|
|
|
+ return new MapProjection<>(map, projection);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Creates view which transforms values stored inside source map.
|
|
|
|
|
+ * Returned view supports modifications: it uses "inserter" function to change map.
|
|
|
|
|
+ *
|
|
|
|
|
+ * It passes to inserter "key" and "new value".
|
|
|
*
|
|
*
|
|
|
* @param map source map
|
|
* @param map source map
|
|
|
* @param function mapping function
|
|
* @param function mapping function
|
|
|
- * @param inserter inverted mapping, used for insertion
|
|
|
|
|
|
|
+ * @param inserter insertion function
|
|
|
* @param <K> K
|
|
* @param <K> K
|
|
|
* @param <TV> source type
|
|
* @param <TV> source type
|
|
|
* @param <RV> target type
|
|
* @param <RV> target type
|
|
|
* @return mutable view
|
|
* @return mutable view
|
|
|
*/
|
|
*/
|
|
|
- public static <K, TV, RV> Map<K,RV> map(Map<K,TV> map, Function<? super TV, ? extends RV> function, BiFunction<? super K, ? super RV, ? extends RV> inserter) {
|
|
|
|
|
- return new MapAdapter<>(map, function, inserter);
|
|
|
|
|
|
|
+ public static <K, TV, RV> Map<K,RV> mapKV(Map<K,TV> map, Function<? super TV, ? extends RV> function, BiFunction<? super K, ? super RV, ? extends RV> inserter) {
|
|
|
|
|
+ return new MapAdapterKV<>(map, function, inserter);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* Creates view which transforms values stored inside source map.
|
|
* Creates view which transforms values stored inside source map.
|
|
|
- * Returned view supports modifications: it uses passed projection for conversion in both directions.
|
|
|
|
|
|
|
+ * Returned view supports modifications: it uses "replacer" function to change map.
|
|
|
|
|
+ *
|
|
|
|
|
+ * It passes to replacer "previous value" and "new value".
|
|
|
*
|
|
*
|
|
|
* @param map source map
|
|
* @param map source map
|
|
|
- * @param function mapping projection
|
|
|
|
|
|
|
+ * @param function mapping function
|
|
|
|
|
+ * @param replacer insertion function
|
|
|
* @param <K> K
|
|
* @param <K> K
|
|
|
* @param <TV> source type
|
|
* @param <TV> source type
|
|
|
* @param <RV> target type
|
|
* @param <RV> target type
|
|
|
* @return mutable view
|
|
* @return mutable view
|
|
|
*/
|
|
*/
|
|
|
- public static <K, TV, RV> Map<K,RV> map(Map<K,TV> map, ProjectionFunction<TV, RV> function) {
|
|
|
|
|
- return new MapProjection<>(map, function);
|
|
|
|
|
|
|
+ public static <K, TV, RV> Map<K,RV> mapVV(Map<K,TV> map, Function<? super TV, ? extends RV> function, BiFunction<? super TV, ? super RV, ? extends RV> replacer) {
|
|
|
|
|
+ return new MapAdapterVV<>(map, function, replacer);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -84,47 +104,59 @@ public class MapUtils {
|
|
|
* @param <RV> target type
|
|
* @param <RV> target type
|
|
|
* @return read-only view
|
|
* @return read-only view
|
|
|
*/
|
|
*/
|
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
public static <K, TV, RV> MultiMap<K,RV> map(MultiMap<K,TV> map, Function<? super TV, ? extends RV> function) {
|
|
public static <K, TV, RV> MultiMap<K,RV> map(MultiMap<K,TV> map, Function<? super TV, ? extends RV> function) {
|
|
|
- return new MMapAdapter<>(map, function, null);
|
|
|
|
|
|
|
+ return new MultiMapAdapterKV<>(map, function, null);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* Creates view which transforms values stored inside source map.
|
|
* Creates view which transforms values stored inside source map.
|
|
|
- * Returned view supports modifications: it uses second function to apply inverted conversion.
|
|
|
|
|
|
|
+ * Returned view supports modifications: it uses passed projection for conversion in both directions.
|
|
|
*
|
|
*
|
|
|
* @param map source map
|
|
* @param map source map
|
|
|
- * @param function mapping function
|
|
|
|
|
- * @param inserter inverted mapping, used for insertion
|
|
|
|
|
|
|
+ * @param projection projection
|
|
|
* @param <K> K
|
|
* @param <K> K
|
|
|
* @param <TV> source type
|
|
* @param <TV> source type
|
|
|
* @param <RV> target type
|
|
* @param <RV> target type
|
|
|
* @return mutable view
|
|
* @return mutable view
|
|
|
*/
|
|
*/
|
|
|
- public static <K, TV, RV> MultiMap<K,RV> map(MultiMap<K,TV> map, Function<? super TV, ? extends RV> function, BiFunction<? super K, ? super RV, ? extends RV> inserter) {
|
|
|
|
|
- return new MMapAdapter<>(map, function, inserter);
|
|
|
|
|
|
|
+ public static <K, TV, RV> MultiMap<K,RV> map(MultiMap<K,TV> map, ProjectionFunction<TV, RV> projection) {
|
|
|
|
|
+ return new MultiMapProjection<>(map, projection);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* Creates view which transforms values stored inside source map.
|
|
* Creates view which transforms values stored inside source map.
|
|
|
- * Returned view supports modifications: it uses passed projection for conversion in both directions.
|
|
|
|
|
|
|
+ * Returned view supports modifications: it uses "inserter" function to change map.
|
|
|
|
|
+ * It passes to inserter "key" and "new value".
|
|
|
*
|
|
*
|
|
|
* @param map source map
|
|
* @param map source map
|
|
|
- * @param function mapping projection
|
|
|
|
|
|
|
+ * @param function mapping function
|
|
|
|
|
+ * @param inserter inverted mapping, used for insertion
|
|
|
* @param <K> K
|
|
* @param <K> K
|
|
|
* @param <TV> source type
|
|
* @param <TV> source type
|
|
|
* @param <RV> target type
|
|
* @param <RV> target type
|
|
|
* @return mutable view
|
|
* @return mutable view
|
|
|
*/
|
|
*/
|
|
|
- public static <K, TV, RV> MultiMap<K,RV> map(MultiMap<K,TV> map, ProjectionFunction<TV, RV> function) {
|
|
|
|
|
- return new MMapProjection<>(map, function);
|
|
|
|
|
|
|
+ public static <K, TV, RV> MultiMap<K,RV> mapKV(MultiMap<K,TV> map, Function<? super TV, ? extends RV> function, BiFunction<? super K, ? super RV, ? extends RV> inserter) {
|
|
|
|
|
+ return new MultiMapAdapterKV<>(map, function, inserter);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public static <K, TV, RV> Map<K,RV> wrap(Map<K,TV> map, Function<? super TV, ? extends RV> getter, BiFunction<? super TV, ? super RV, ? extends RV> setter) {
|
|
|
|
|
- return new MapWrapper<>(map, getter, setter);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static <K, TV, RV> MultiMap<K,RV> wrap(MultiMap<K,TV> map, Function<? super TV, ? extends RV> getter, BiFunction<? super TV, ? super RV, ? extends RV> setter) {
|
|
|
|
|
- return new MMapWrapper<>(map, getter, setter);
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Creates view which transforms values stored inside source map.
|
|
|
|
|
+ * Returned view supports modifications: it uses "replacer" function to change map.
|
|
|
|
|
+ *
|
|
|
|
|
+ * It passes to replacer "previous value" and "new value".
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param map source map
|
|
|
|
|
+ * @param function mapping function
|
|
|
|
|
+ * @param replacer inverted mapping, used for insertion
|
|
|
|
|
+ * @param <K> K
|
|
|
|
|
+ * @param <TV> source type
|
|
|
|
|
+ * @param <RV> target type
|
|
|
|
|
+ * @return mutable view
|
|
|
|
|
+ */
|
|
|
|
|
+ public static <K, TV, RV> MultiMap<K,RV> mapVV(MultiMap<K,TV> map, Function<? super TV, ? extends RV> function, BiFunction<? super TV, ? super RV, ? extends RV> replacer) {
|
|
|
|
|
+ return new MultiMapAdapterVV<>(map, function, replacer);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -140,8 +172,8 @@ public class MapUtils {
|
|
|
* @param <V> V
|
|
* @param <V> V
|
|
|
* @return view
|
|
* @return view
|
|
|
*/
|
|
*/
|
|
|
- public static <K,V> Map<K,V> keyproxy(Supplier<Map<K, V>> content, Predicate<Object> acceptor, Function<K, K> function) {
|
|
|
|
|
- return new KeyMapAdapter<>(content, acceptor, function);
|
|
|
|
|
|
|
+ public static <K,V> Map<K,V> keymap(Map<K, V> content, Predicate<Object> acceptor, Function<K, K> function) {
|
|
|
|
|
+ return new KeyMapFilter<>(content, acceptor, function);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -155,26 +187,8 @@ public class MapUtils {
|
|
|
* @param <V> V
|
|
* @param <V> V
|
|
|
* @return view
|
|
* @return view
|
|
|
*/
|
|
*/
|
|
|
- public static <TK, RK, V> Map<RK,V> view(Map<TK, ? extends V> map, Function<TK, RK> keyMapper) {
|
|
|
|
|
- return view(map, keyMapper, Function.identity());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * It cretes read-only view of map which keys and values are created by provided functions.
|
|
|
|
|
- * Maps keys at access time, before lookup.
|
|
|
|
|
- * Maps values at access time, after lookup.
|
|
|
|
|
- *
|
|
|
|
|
- * @param map map
|
|
|
|
|
- * @param keyMapper keyMapper
|
|
|
|
|
- * @param valueMapper valueMapper
|
|
|
|
|
- * @param <TK> TK
|
|
|
|
|
- * @param <RK> RK
|
|
|
|
|
- * @param <TV> TV
|
|
|
|
|
- * @param <RV> RV
|
|
|
|
|
- * @return view
|
|
|
|
|
- */
|
|
|
|
|
- public static <TK, RK, TV, RV> Map<RK, RV> view(Map<TK,? extends TV> map, Function<TK, RK> keyMapper, Function<TV, RV> valueMapper) {
|
|
|
|
|
- return new ViewAdapter<>(map, keyMapper, valueMapper);
|
|
|
|
|
|
|
+ public static <TK, RK, V> Map<RK,V> keymap(Map<TK, ? extends V> map, Function<TK, RK> keyMapper) {
|
|
|
|
|
+ return new KeyMapAdapter<>(map, keyMapper, Function.identity());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -258,7 +272,7 @@ public class MapUtils {
|
|
|
return target;
|
|
return target;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private static class ViewAdapter<TK, RK, TV, RV> extends AMap<RK, RV> {
|
|
|
|
|
|
|
+ private static class KeyMapAdapter<TK, RK, TV, RV> extends AMap<RK, RV> {
|
|
|
|
|
|
|
|
private final Map<TK,? extends TV> content;
|
|
private final Map<TK,? extends TV> content;
|
|
|
|
|
|
|
@@ -266,7 +280,7 @@ public class MapUtils {
|
|
|
|
|
|
|
|
private final Function<TV, RV> vmap;
|
|
private final Function<TV, RV> vmap;
|
|
|
|
|
|
|
|
- public ViewAdapter(Map<TK,? extends TV> content, Function<TK, RK> kmap, Function<TV, RV> vmap) {
|
|
|
|
|
|
|
+ public KeyMapAdapter(Map<TK,? extends TV> content, Function<TK, RK> kmap, Function<TV, RV> vmap) {
|
|
|
this.content = content;
|
|
this.content = content;
|
|
|
this.kmap = kmap;
|
|
this.kmap = kmap;
|
|
|
this.vmap = vmap;
|
|
this.vmap = vmap;
|
|
@@ -323,13 +337,13 @@ public class MapUtils {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private static class MMapAdapter<K, TV, RV> extends MapAdapter<K, TV, RV> implements MultiMap<K, RV> {
|
|
|
|
|
|
|
+ private static class MultiMapAdapterKV<K, TV, RV> extends MapAdapterKV<K, TV, RV> implements MultiMap<K, RV> {
|
|
|
|
|
|
|
|
private static final long serialVersionUID = 1L;
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
|
|
|
|
private final MultiMap<K, TV> mcontent;
|
|
private final MultiMap<K, TV> mcontent;
|
|
|
|
|
|
|
|
- public MMapAdapter(MultiMap<K, TV> mcontent, Function<? super TV, ? extends RV> function, BiFunction<? super K, ? super RV, ? extends RV> setter) {
|
|
|
|
|
|
|
+ public MultiMapAdapterKV(MultiMap<K, TV> mcontent, Function<? super TV, ? extends RV> function, BiFunction<? super K, ? super RV, ? extends RV> setter) {
|
|
|
super(mcontent, function, setter);
|
|
super(mcontent, function, setter);
|
|
|
this.mcontent = mcontent;
|
|
this.mcontent = mcontent;
|
|
|
}
|
|
}
|
|
@@ -340,21 +354,57 @@ public class MapUtils {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- private static class MapAdapter<K, TV, RV> extends AMap<K, RV> implements Map<K, RV> {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ private static class MultiMapAdapterVV<K, TV, RV> extends MapAdapterVV<K,TV,RV> implements MultiMap<K, RV> {
|
|
|
|
|
+
|
|
|
|
|
+ private static final long serialVersionUID = 1L;
|
|
|
|
|
+
|
|
|
|
|
+ private final MultiMap<K, TV> mcontent;
|
|
|
|
|
+
|
|
|
|
|
+ public MultiMapAdapterVV(MultiMap<K, TV> content, Function<? super TV, ? extends RV> getter, BiFunction<? super TV, ? super RV, ? extends RV> setter) {
|
|
|
|
|
+ super(content, getter, setter);
|
|
|
|
|
+ this.mcontent = content;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Collection<RV> getAll(Object key) {
|
|
|
|
|
+ return CollectionUtils.map(mcontent.getAll(key), getter);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static class MultiMapProjection<K, TV, RV> extends MapProjection<K,TV,RV> implements MultiMap<K, RV> {
|
|
|
|
|
|
|
|
private static final long serialVersionUID = 1L;
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
|
|
|
|
|
|
+ private final MultiMap<K, TV> mcontent;
|
|
|
|
|
+
|
|
|
|
|
+ public MultiMapProjection(MultiMap<K, TV> content, ProjectionFunction<TV, RV> function) {
|
|
|
|
|
+ super(content, function);
|
|
|
|
|
+ this.mcontent = content;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Collection<RV> getAll(Object key) {
|
|
|
|
|
+ return CollectionUtils.map(mcontent.getAll(key), function);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static class MapAdapterKV<K, TV, RV> extends AMap<K, RV> implements Map<K, RV> {
|
|
|
|
|
+
|
|
|
|
|
+ private static final long serialVersionUID = 1L;
|
|
|
|
|
+
|
|
|
private static final BiFunction NSE = (Serializable & BiFunction)(a,b) -> {
|
|
private static final BiFunction NSE = (Serializable & BiFunction)(a,b) -> {
|
|
|
- throw new UnsupportedOperationException();
|
|
|
|
|
|
|
+ throw new UnsupportedOperationException();
|
|
|
};
|
|
};
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
protected final Map<K, TV> content;
|
|
protected final Map<K, TV> content;
|
|
|
protected final Function<? super TV, ? extends RV> function;
|
|
protected final Function<? super TV, ? extends RV> function;
|
|
|
protected final BiFunction<? super K, ? super RV, ? extends RV> inserter;
|
|
protected final BiFunction<? super K, ? super RV, ? extends RV> inserter;
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
@SuppressWarnings("unchecked")
|
|
|
- public MapAdapter(Map<K, TV> content, Function<? super TV, ? extends RV> function, BiFunction<? super K, ? super RV, ? extends RV> setter) {
|
|
|
|
|
|
|
+ public MapAdapterKV(Map<K, TV> content, Function<? super TV, ? extends RV> function, BiFunction<? super K, ? super RV, ? extends RV> setter) {
|
|
|
this.content = content;
|
|
this.content = content;
|
|
|
this.function = function;
|
|
this.function = function;
|
|
|
this.inserter = null != setter ? setter : NSE;
|
|
this.inserter = null != setter ? setter : NSE;
|
|
@@ -369,7 +419,7 @@ public class MapUtils {
|
|
|
public boolean containsKey(Object key) {
|
|
public boolean containsKey(Object key) {
|
|
|
return content.containsKey(key);
|
|
return content.containsKey(key);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
public boolean containsValue(Object value) {
|
|
public boolean containsValue(Object value) {
|
|
|
return content.values().stream().map(function).anyMatch(rv -> CompareUtils.equals(rv, value));
|
|
return content.values().stream().map(function).anyMatch(rv -> CompareUtils.equals(rv, value));
|
|
@@ -395,7 +445,7 @@ public class MapUtils {
|
|
|
public Collection<RV> values() {
|
|
public Collection<RV> values() {
|
|
|
return CollectionUtils.map(content.values(), function);
|
|
return CollectionUtils.map(content.values(), function);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
public Set<Entry<K, RV>> entrySet() {
|
|
public Set<Entry<K, RV>> entrySet() {
|
|
|
return SetUtils.map(content.entrySet(), e -> new EntryAdapter(e));
|
|
return SetUtils.map(content.entrySet(), e -> new EntryAdapter(e));
|
|
@@ -410,9 +460,9 @@ public class MapUtils {
|
|
|
public RV put(K key, RV value) {
|
|
public RV put(K key, RV value) {
|
|
|
return inserter.apply(key, value);
|
|
return inserter.apply(key, value);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
private final class EntryAdapter extends AEntry<K, RV> {
|
|
private final class EntryAdapter extends AEntry<K, RV> {
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
private final Entry<K,TV> delegate;
|
|
private final Entry<K,TV> delegate;
|
|
|
|
|
|
|
|
public EntryAdapter(Entry<K, TV> delegate) {
|
|
public EntryAdapter(Entry<K, TV> delegate) {
|
|
@@ -437,41 +487,19 @@ public class MapUtils {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- private static class MMapProjection<K, TV, RV> extends MapProjection<K,TV,RV> implements MultiMap<K, RV> {
|
|
|
|
|
-
|
|
|
|
|
- private static final long serialVersionUID = 1L;
|
|
|
|
|
-
|
|
|
|
|
- private final MultiMap<K, TV> mcontent;
|
|
|
|
|
-
|
|
|
|
|
- public MMapProjection(MultiMap<K, TV> content, ProjectionFunction<TV, RV> function) {
|
|
|
|
|
- super(content, function);
|
|
|
|
|
- this.mcontent = content;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public Collection<RV> getAll(Object key) {
|
|
|
|
|
- return CollectionUtils.map(mcontent.getAll(key), function);
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private static class MapProjection<K, TV, RV> extends AMap<K, RV> implements Map<K, RV> {
|
|
|
|
|
-
|
|
|
|
|
|
|
+ private static class MapAdapterVV<K, TV, RV> extends AMap<K, RV> implements Map<K, RV> {
|
|
|
|
|
+
|
|
|
private static final long serialVersionUID = 1L;
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
|
|
|
|
protected final Map<K, TV> content;
|
|
protected final Map<K, TV> content;
|
|
|
|
|
+ protected final Function<? super TV, ? extends RV> getter;
|
|
|
|
|
+ protected final BiFunction<? super TV, ? super RV, ? extends RV> setter;
|
|
|
|
|
|
|
|
- protected final ProjectionFunction<TV, RV> function;
|
|
|
|
|
-
|
|
|
|
|
- public MapProjection(Map<K, TV> content, ProjectionFunction<TV, RV> function) {
|
|
|
|
|
- this.content = content;
|
|
|
|
|
- this.function = function;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public MapProjection(MultiMap<K, TV> content, ProjectionFunction<TV, RV> function) {
|
|
|
|
|
|
|
+ public MapAdapterVV(Map<K,TV> content, Function<? super TV, ? extends RV> getter, BiFunction<? super TV, ? super RV, ? extends RV> setter) {
|
|
|
this.content = content;
|
|
this.content = content;
|
|
|
- this.function = function;
|
|
|
|
|
|
|
+ this.getter = getter;
|
|
|
|
|
+ this.setter = setter;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -483,26 +511,22 @@ public class MapUtils {
|
|
|
public boolean containsKey(Object key) {
|
|
public boolean containsKey(Object key) {
|
|
|
return content.containsKey(key);
|
|
return content.containsKey(key);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
public boolean containsValue(Object value) {
|
|
public boolean containsValue(Object value) {
|
|
|
- try {
|
|
|
|
|
- return content.containsValue(function.invert((RV)value));
|
|
|
|
|
- } catch(ClassCastException _ex) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ return values().contains(value);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public void clear() {
|
|
|
|
|
- content.clear();
|
|
|
|
|
|
|
+ public RV get(Object key) {
|
|
|
|
|
+ TV var = content.get(key);
|
|
|
|
|
+ return null!=var ? getter.apply(var) : null;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public RV remove(Object key) {
|
|
|
|
|
- TV prev = content.remove(key);
|
|
|
|
|
- return prev==null ? null : function.apply(prev);
|
|
|
|
|
|
|
+ public RV put(K key, RV value) {
|
|
|
|
|
+ TV var = content.get(key);
|
|
|
|
|
+ return null!=var ? setter.apply(var, value) : null;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -512,41 +536,19 @@ public class MapUtils {
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public Collection<RV> values() {
|
|
public Collection<RV> values() {
|
|
|
- return CollectionUtils.map(content.values(), function);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public Set<Map.Entry<K, RV>> entrySet() {
|
|
|
|
|
- return SetUtils.map(content.entrySet(), e -> new EntryProjection(e));
|
|
|
|
|
|
|
+ return CollectionUtils.map(content.values(), getter);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public RV get(Object key) {
|
|
|
|
|
- return function.apply(content.get(key));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public RV put(K key, RV value) {
|
|
|
|
|
- return function.apply(content.put(key, function.invert(value)));
|
|
|
|
|
|
|
+ public Set<Entry<K, RV>> entrySet() {
|
|
|
|
|
+ return SetUtils.map(content.entrySet(), e -> new EntryWrapper(e));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- @Override
|
|
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
|
|
- public boolean remove(Object key, Object value) {
|
|
|
|
|
- Object v;
|
|
|
|
|
- try {
|
|
|
|
|
- v = function.invert((RV)value);
|
|
|
|
|
- } catch(ClassCastException _e) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- return content.remove(key, v);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ private final class EntryWrapper extends AEntry<K, RV> {
|
|
|
|
|
|
|
|
- private final class EntryProjection extends AEntry<K, RV> {
|
|
|
|
|
-
|
|
|
|
|
private final Map.Entry<K,TV> delegate;
|
|
private final Map.Entry<K,TV> delegate;
|
|
|
|
|
|
|
|
- public EntryProjection(Map.Entry<K, TV> delegate) {
|
|
|
|
|
|
|
+ public EntryWrapper(Map.Entry<K, TV> delegate) {
|
|
|
this.delegate = delegate;
|
|
this.delegate = delegate;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -557,48 +559,34 @@ public class MapUtils {
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public RV getValue() {
|
|
public RV getValue() {
|
|
|
- return function.apply(delegate.getValue());
|
|
|
|
|
|
|
+ return getter.apply(delegate.getValue());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public RV setValue(RV value) {
|
|
public RV setValue(RV value) {
|
|
|
- return function.apply(content.put(getKey(), function.invert(value)));
|
|
|
|
|
|
|
+ return setter.apply(delegate.getValue(), value);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- private static class MMapWrapper<K, TV, RV> extends MapWrapper<K,TV,RV> implements MultiMap<K, RV> {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ private static class MapProjection<K, TV, RV> extends AMap<K, RV> implements Map<K, RV> {
|
|
|
|
|
|
|
|
private static final long serialVersionUID = 1L;
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
|
|
|
|
- private final MultiMap<K, TV> mcontent;
|
|
|
|
|
-
|
|
|
|
|
- public MMapWrapper(MultiMap<K, TV> content, Function<? super TV, ? extends RV> getter, BiFunction<? super TV, ? super RV, ? extends RV> setter) {
|
|
|
|
|
- super(content, getter, setter);
|
|
|
|
|
- this.mcontent = content;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ protected final Map<K, TV> content;
|
|
|
|
|
|
|
|
- @Override
|
|
|
|
|
- public Collection<RV> getAll(Object key) {
|
|
|
|
|
- return CollectionUtils.map(mcontent.getAll(key), getter);
|
|
|
|
|
|
|
+ protected final ProjectionFunction<TV, RV> function;
|
|
|
|
|
+
|
|
|
|
|
+ public MapProjection(Map<K, TV> content, ProjectionFunction<TV, RV> function) {
|
|
|
|
|
+ this.content = content;
|
|
|
|
|
+ this.function = function;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private static class MapWrapper<K, TV, RV> extends AMap<K, RV> implements Map<K, RV> {
|
|
|
|
|
-
|
|
|
|
|
- private static final long serialVersionUID = 1L;
|
|
|
|
|
-
|
|
|
|
|
- protected final Map<K, TV> content;
|
|
|
|
|
- protected final Function<? super TV, ? extends RV> getter;
|
|
|
|
|
- protected final BiFunction<? super TV, ? super RV, ? extends RV> setter;
|
|
|
|
|
-
|
|
|
|
|
- public MapWrapper(Map<K,TV> content, Function<? super TV, ? extends RV> getter, BiFunction<? super TV, ? super RV, ? extends RV> setter) {
|
|
|
|
|
|
|
+ public MapProjection(MultiMap<K, TV> content, ProjectionFunction<TV, RV> function) {
|
|
|
this.content = content;
|
|
this.content = content;
|
|
|
- this.getter = getter;
|
|
|
|
|
- this.setter = setter;
|
|
|
|
|
|
|
+ this.function = function;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -610,26 +598,28 @@ public class MapUtils {
|
|
|
public boolean containsKey(Object key) {
|
|
public boolean containsKey(Object key) {
|
|
|
return content.containsKey(key);
|
|
return content.containsKey(key);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
@Override
|
|
@Override
|
|
|
public boolean containsValue(Object value) {
|
|
public boolean containsValue(Object value) {
|
|
|
- return values().contains(value);
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ return content.containsValue(function.invert((RV)value));
|
|
|
|
|
+ } catch(ClassCastException _ex) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public RV get(Object key) {
|
|
|
|
|
- TV var = content.get(key);
|
|
|
|
|
- return null!=var ? getter.apply(var) : null;
|
|
|
|
|
|
|
+ public void clear() {
|
|
|
|
|
+ content.clear();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public RV put(K key, RV value) {
|
|
|
|
|
- TV var = content.get(key);
|
|
|
|
|
- return null!=var ? setter.apply(var, value) : null;
|
|
|
|
|
|
|
+ public RV remove(Object key) {
|
|
|
|
|
+ TV prev = content.remove(key);
|
|
|
|
|
+ return prev==null ? null : function.apply(prev);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
public Set<K> keySet() {
|
|
public Set<K> keySet() {
|
|
|
return content.keySet();
|
|
return content.keySet();
|
|
@@ -637,19 +627,41 @@ public class MapUtils {
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public Collection<RV> values() {
|
|
public Collection<RV> values() {
|
|
|
- return CollectionUtils.map(content.values(), getter);
|
|
|
|
|
|
|
+ return CollectionUtils.map(content.values(), function);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public Set<Entry<K, RV>> entrySet() {
|
|
|
|
|
- return SetUtils.map(content.entrySet(), e -> new EntryWrapper(e));
|
|
|
|
|
|
|
+ public Set<Map.Entry<K, RV>> entrySet() {
|
|
|
|
|
+ return SetUtils.map(content.entrySet(), e -> new EntryProjection(e));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public RV get(Object key) {
|
|
|
|
|
+ return function.apply(content.get(key));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private final class EntryWrapper extends AEntry<K, RV> {
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public RV put(K key, RV value) {
|
|
|
|
|
+ return function.apply(content.put(key, function.invert(value)));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
|
|
+ public boolean remove(Object key, Object value) {
|
|
|
|
|
+ Object v;
|
|
|
|
|
+ try {
|
|
|
|
|
+ v = function.invert((RV)value);
|
|
|
|
|
+ } catch(ClassCastException _e) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ return content.remove(key, v);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private final class EntryProjection extends AEntry<K, RV> {
|
|
|
|
|
|
|
|
private final Map.Entry<K,TV> delegate;
|
|
private final Map.Entry<K,TV> delegate;
|
|
|
|
|
|
|
|
- public EntryWrapper(Map.Entry<K, TV> delegate) {
|
|
|
|
|
|
|
+ public EntryProjection(Map.Entry<K, TV> delegate) {
|
|
|
this.delegate = delegate;
|
|
this.delegate = delegate;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -660,18 +672,18 @@ public class MapUtils {
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public RV getValue() {
|
|
public RV getValue() {
|
|
|
- return getter.apply(delegate.getValue());
|
|
|
|
|
|
|
+ return function.apply(delegate.getValue());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public RV setValue(RV value) {
|
|
public RV setValue(RV value) {
|
|
|
- return setter.apply(delegate.getValue(), value);
|
|
|
|
|
|
|
+ return function.apply(content.put(getKey(), function.invert(value)));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
static class EmptyMM<K,V> extends AMap<K,V> implements MultiMap<K, V> {
|
|
static class EmptyMM<K,V> extends AMap<K,V> implements MultiMap<K, V> {
|
|
|
|
|
|
|
|
private static final long serialVersionUID = 1L;
|
|
private static final long serialVersionUID = 1L;
|
|
@@ -708,14 +720,14 @@ public class MapUtils {
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private static class KeyMapAdapter<K, V> extends AMap<K, V> {
|
|
|
|
|
|
|
+ private static class KeyMapFilter<K, V> extends AMap<K, V> {
|
|
|
|
|
|
|
|
protected final Map<K, V> content;
|
|
protected final Map<K, V> content;
|
|
|
protected final Predicate<Object> acceptor;
|
|
protected final Predicate<Object> acceptor;
|
|
|
protected final Function<K, K> function;
|
|
protected final Function<K, K> function;
|
|
|
|
|
|
|
|
- KeyMapAdapter(Supplier<Map<K, V>> content, Predicate<Object> acceptor, Function<K, K> function) {
|
|
|
|
|
- this.content = content.get();
|
|
|
|
|
|
|
+ KeyMapFilter(Map<K, V> content, Predicate<Object> acceptor, Function<K, K> function) {
|
|
|
|
|
+ this.content = content;
|
|
|
this.acceptor = acceptor;
|
|
this.acceptor = acceptor;
|
|
|
this.function = function;
|
|
this.function = function;
|
|
|
}
|
|
}
|