Skip to content

Commit

Permalink
0.9.79
Browse files Browse the repository at this point in the history
  • Loading branch information
landawn committed Aug 19, 2017
1 parent e36298a commit 565da18
Show file tree
Hide file tree
Showing 12 changed files with 93 additions and 51 deletions.
Binary file modified lib/abacus-android-0.9.79.jar
Binary file not shown.
Binary file modified lib/abacus-android-jdk7-0.9.79.jar
Binary file not shown.
Binary file modified lib/abacus-android-se-0.9.79.jar
Binary file not shown.
Binary file modified lib/abacus-android-se-jdk7-0.9.79.jar
Binary file not shown.
Binary file modified lib/abacus-util-0.9.79.jar
Binary file not shown.
Binary file modified lib/abacus-util-all-0.9.79.jar
Binary file not shown.
Binary file modified lib/abacus-util-all-jdk7-0.9.79.jar
Binary file not shown.
Binary file modified lib/abacus-util-jdk7-0.9.79.jar
Binary file not shown.
26 changes: 18 additions & 8 deletions src/com/landawn/abacus/util/ListMultimap.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@
* @since 0.9
*
* @author Haiyang Li
* @see N#newListMultimap()
*/
public class ListMultimap<K, E> extends Multimap<K, E, List<E>> {
public final class ListMultimap<K, E> extends Multimap<K, E, List<E>> {
ListMultimap() {
this(HashMap.class, ArrayList.class);
}
Expand All @@ -37,19 +38,14 @@ public class ListMultimap<K, E> extends Multimap<K, E, List<E>> {
this(new HashMap<K, List<E>>(initialCapacity), ArrayList.class);
}

@SuppressWarnings("rawtypes")
ListMultimap(final Class<? extends List> valueType) {
this(HashMap.class, valueType);
}

@SuppressWarnings("rawtypes")
ListMultimap(final Class<? extends Map> mapType, final Class<? extends List> valueType) {
super(mapType, valueType);
}

@SuppressWarnings("rawtypes")
ListMultimap(final Map<K, List<E>> valueMap, final Class<? extends List> collectionType) {
super(valueMap, collectionType);
ListMultimap(final Map<K, List<E>> valueMap, final Class<? extends List> valueType) {
super(valueMap, valueType);
}

public static <K, E> ListMultimap<K, E> from(final Map<? extends K, ? extends E> map) {
Expand Down Expand Up @@ -85,4 +81,18 @@ public static <K, E> ListMultimap<K, E> from(final Collection<? extends E> c, fi

return multimap;
}

@SuppressWarnings("rawtypes")
public static <K, E, V extends List<E>> ListMultimap<K, E> wrap(final Map<K, V> map) {
Class<? extends List> valueType = ArrayList.class;

for (V v : map.values()) {
if (v != null) {
valueType = v.getClass();
break;
}
}

return new ListMultimap<K, E>((Map<K, List<E>>) map, valueType);
}
}
73 changes: 38 additions & 35 deletions src/com/landawn/abacus/util/Multimap.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import java.lang.reflect.Modifier;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
Expand Down Expand Up @@ -76,11 +75,6 @@ public class Multimap<K, E, V extends Collection<E>> {
this(new HashMap<K, V>(initialCapacity), ArrayList.class);
}

@SuppressWarnings("rawtypes")
Multimap(final Class<? extends Collection> valueType) {
this(HashMap.class, valueType);
}

@SuppressWarnings("rawtypes")
Multimap(final Class<? extends Map> mapType, final Class<? extends Collection> valueType) {
this(N.newInstance(mapType), valueType);
Expand All @@ -89,35 +83,29 @@ public class Multimap<K, E, V extends Collection<E>> {
/**
*
* @param valueMap The valueMap and this Multimap share same data; any changes to one will appear in the other.
* @param collectionType
* @param valueType
*/
@SuppressWarnings("rawtypes")
@Internal
Multimap(final Map<K, V> valueMap, final Class<? extends Collection> collectionType) {
Multimap(final Map<K, V> valueMap, final Class<? extends Collection> valueType) {
this.valueMap = valueMap;
this.valueType = (Class) collectionType;
this.valueType = (Class) valueType;

if (Modifier.isAbstract(collectionType.getModifiers())) {
if (List.class.isAssignableFrom(collectionType)) {
if (Modifier.isAbstract(valueType.getModifiers())) {
if (List.class.isAssignableFrom(valueType)) {
concreteValueType = (Class) ArrayList.class;
} else if (Set.class.isAssignableFrom(collectionType)) {
} else if (Set.class.isAssignableFrom(valueType)) {
concreteValueType = (Class) HashSet.class;
} else if (Queue.class.isAssignableFrom(collectionType)) {
} else if (Queue.class.isAssignableFrom(valueType)) {
concreteValueType = (Class) ArrayDeque.class;
} else {
throw new IllegalArgumentException("Unsupported collection type: " + collectionType.getCanonicalName());
throw new IllegalArgumentException("Unsupported collection type: " + valueType.getCanonicalName());
}
} else {
concreteValueType = (Class) collectionType;
concreteValueType = (Class) valueType;
}
}

Multimap(final Map<? extends K, ? extends E> m) {
this();

putAll(m);
}

public V get(final Object key) {
return valueMap.get(key);
}
Expand Down Expand Up @@ -663,7 +651,7 @@ public boolean removeAllIf(BiPredicate<? super K, ? super V> predicate) {
* @param newValue
* @return <code>true</code> if this Multimap is modified by this operation, otherwise <code>false</code>.
*/
public boolean replace(final K key, final E oldValue, final E newValue) {
public boolean replace(final K key, final Object oldValue, final E newValue) {
V val = valueMap.get(key);

if (val.remove(oldValue)) {
Expand All @@ -679,14 +667,14 @@ public boolean replace(final K key, final E oldValue, final E newValue) {
* <code>False</code> is returned if no <code>oldValue</code> is found.
*
* @param key
* @param oldValue
* @param oldValues
* @param newValue
* @return <code>true</code> if this Multimap is modified by this operation, otherwise <code>false</code>.
*/
public boolean replaceAll(final K key, final E oldValue, final E newValue) {
public boolean replaceAll(final K key, final Collection<?> oldValues, final E newValue) {
V val = valueMap.get(key);

if (val.removeAll(Arrays.asList(oldValue))) {
if (val.removeAll(oldValues)) {
val.add(newValue);
return true;
}
Expand All @@ -697,11 +685,12 @@ public boolean replaceAll(final K key, final E oldValue, final E newValue) {
/**
* Replace the specified value (one occurrence) from the value set associated with keys which satisfy the specified <code>predicate</code>.
*
* @param value
* @param oldValue
* @param newValue
* @param predicate
* @return <code>true</code> if this Multimap is modified by this operation, otherwise <code>false</code>.
*/
public boolean replaceIf(E oldValue, E newValue, Predicate<? super K> predicate) {
public boolean replaceIf(Object oldValue, E newValue, Predicate<? super K> predicate) {
boolean modified = false;

for (Map.Entry<K, V> entry : this.valueMap.entrySet()) {
Expand All @@ -719,11 +708,12 @@ public boolean replaceIf(E oldValue, E newValue, Predicate<? super K> predicate)
/**
* Replace the specified value (one occurrence) from the value set associated with keys which satisfy the specified <code>predicate</code>.
*
* @param value
* @param oldValue
* @param newValue
* @param predicate
* @return <code>true</code> if this Multimap is modified by this operation, otherwise <code>false</code>.
*/
public boolean replaceIf(E oldValue, E newValue, BiPredicate<? super K, ? super V> predicate) {
public boolean replaceIf(Object oldValue, E newValue, BiPredicate<? super K, ? super V> predicate) {
boolean modified = false;

for (Map.Entry<K, V> entry : this.valueMap.entrySet()) {
Expand All @@ -741,16 +731,17 @@ public boolean replaceIf(E oldValue, E newValue, BiPredicate<? super K, ? super
/**
* Replace the specified value (one occurrence) from the value set associated with keys which satisfy the specified <code>predicate</code>.
*
* @param value
* @param oldValues
* @param newValue
* @param predicate
* @return <code>true</code> if this Multimap is modified by this operation, otherwise <code>false</code>.
*/
public boolean replaceAllIf(E oldValue, E newValue, Predicate<? super K> predicate) {
public boolean replaceAllIf(Collection<?> oldValues, E newValue, Predicate<? super K> predicate) {
boolean modified = false;

for (Map.Entry<K, V> entry : this.valueMap.entrySet()) {
if (predicate.test(entry.getKey())) {
if (entry.getValue().removeAll(Arrays.asList(oldValue))) {
if (entry.getValue().removeAll(oldValues)) {
entry.getValue().add(newValue);
modified = true;
}
Expand All @@ -763,16 +754,17 @@ public boolean replaceAllIf(E oldValue, E newValue, Predicate<? super K> predica
/**
* Replace the specified value (one occurrence) from the value set associated with keys which satisfy the specified <code>predicate</code>.
*
* @param value
* @param oldValues
* @param newValue
* @param predicate
* @return <code>true</code> if this Multimap is modified by this operation, otherwise <code>false</code>.
*/
public boolean replaceAllIf(E oldValue, E newValue, BiPredicate<? super K, ? super V> predicate) {
public boolean replaceAllIf(Collection<?> oldValues, E newValue, BiPredicate<? super K, ? super V> predicate) {
boolean modified = false;

for (Map.Entry<K, V> entry : this.valueMap.entrySet()) {
if (predicate.test(entry.getKey(), entry.getValue())) {
if (entry.getValue().removeAll(Arrays.asList(oldValue))) {
if (entry.getValue().removeAll(oldValues)) {
entry.getValue().add(newValue);
modified = true;
}
Expand Down Expand Up @@ -1159,6 +1151,17 @@ public <M extends Map<K, V>> M toMap(final IntFunction<M> supplier) {
return map;
}

/**
* Returns a view of this multimap as a {@code Map} from each distinct key
* to the nonempty collection of that key's associated values.
*
* <p>Changes to the returned map or the collections that serve as its values
* will update the underlying multimap, and vice versa.
*/
public Map<K, V> unwrap() {
return valueMap;
}

public Stream<Map.Entry<K, V>> stream() {
return Stream.of(valueMap.entrySet());
}
Expand Down
20 changes: 20 additions & 0 deletions src/com/landawn/abacus/util/N.java
Original file line number Diff line number Diff line change
Expand Up @@ -1337,6 +1337,16 @@ public static <K, E> ListMultimap<K, E> newListSortedMultimap(final Map<? extend
return multiMap;
}

@SuppressWarnings("rawtypes")
public static <K, E> ListMultimap<K, E> newListMultimap(final Class<? extends Map> mapType) {
return new ListMultimap<>(mapType, ArrayList.class);
}

@SuppressWarnings("rawtypes")
public static <K, E> ListMultimap<K, E> newListMultimap(final Class<? extends Map> mapType, final Class<? extends List> valueType) {
return new ListMultimap<>(mapType, valueType);
}

public static <K, E> SetMultimap<K, E> newSetMultimap() {
return new SetMultimap<>();
}
Expand Down Expand Up @@ -1381,6 +1391,16 @@ public static <K, E> SetMultimap<K, E> newSetSortedMultimap(final Map<? extends
return multiMap;
}

@SuppressWarnings("rawtypes")
public static <K, E> SetMultimap<K, E> newSetMultimap(final Class<? extends Map> mapType) {
return new SetMultimap<>(mapType, HashSet.class);
}

@SuppressWarnings("rawtypes")
public static <K, E> SetMultimap<K, E> newSetMultimap(final Class<? extends Map> mapType, final Class<? extends Set> valueType) {
return new SetMultimap<>(mapType, valueType);
}

static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
static final int MAX_HASH_LENGTH = (int) (MAX_ARRAY_SIZE / 1.25) - 1;

Expand Down
25 changes: 17 additions & 8 deletions src/com/landawn/abacus/util/SetMultimap.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@
* @since 0.9
*
* @author Haiyang Li
* @see N#newSetMultimap()
*/
public class SetMultimap<K, E> extends Multimap<K, E, Set<E>> {
public final class SetMultimap<K, E> extends Multimap<K, E, Set<E>> {
SetMultimap() {
this(HashMap.class, HashSet.class);
}
Expand All @@ -36,19 +37,14 @@ public class SetMultimap<K, E> extends Multimap<K, E, Set<E>> {
this(new HashMap<K, Set<E>>(initialCapacity), HashSet.class);
}

@SuppressWarnings("rawtypes")
SetMultimap(final Class<? extends Set> valueType) {
this(HashMap.class, valueType);
}

@SuppressWarnings("rawtypes")
SetMultimap(final Class<? extends Map> mapType, final Class<? extends Set> valueType) {
super(mapType, valueType);
}

@SuppressWarnings("rawtypes")
SetMultimap(final Map<K, Set<E>> valueMap, final Class<? extends Set> collectionType) {
super(valueMap, collectionType);
SetMultimap(final Map<K, Set<E>> valueMap, final Class<? extends Set> valueType) {
super(valueMap, valueType);
}

public static <K, E> SetMultimap<K, E> from(final Map<? extends K, ? extends E> map) {
Expand Down Expand Up @@ -83,6 +79,19 @@ public static <K, E> SetMultimap<K, E> from(final Collection<? extends E> c, fin
}

return multimap;
}

@SuppressWarnings("rawtypes")
public static <K, E, V extends Set<E>> SetMultimap<K, E> wrap(final Map<K, V> map) {
Class<? extends Set> valueType = HashSet.class;

for (V v : map.values()) {
if (v != null) {
valueType = v.getClass();
break;
}
}

return new SetMultimap<K, E>((Map<K, Set<E>>) map, valueType);
}
}

0 comments on commit 565da18

Please sign in to comment.