Collectors.toMap (#515)

Implement Collectors.toMap
This commit is contained in:
Ivan Hetman 2020-10-07 12:21:55 +03:00 committed by GitHub
parent 03c70e3a06
commit 1785d6ad9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 0 deletions

View File

@ -17,12 +17,16 @@ package org.teavm.classlib.java.util.stream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import org.teavm.classlib.java.util.TObjects;
public final class TCollectors {
private TCollectors() {
@ -69,4 +73,48 @@ public final class TCollectors {
return TCollector.of(StringBuilder::new, accumulator, combiner,
sb -> sb.insert(0, prefix).append(suffix).toString());
}
public static <E, K, V> TCollector<E, ?, Map<K, V>> toMap(Function<? super E, ? extends K> keyMapper,
Function<? super E, ? extends V> valueMapper) {
return TCollector.of(HashMap::new,
(map, el) -> {
K k = keyMapper.apply(el);
V newV = TObjects.requireNonNull(valueMapper.apply(el));
V oldV = map.putIfAbsent(k, newV);
if (oldV != null) {
throw new IllegalStateException(
"Key " + k + " corresponds to values " + oldV + " and " + newV);
}
},
(m1, m2) -> {
for (Map.Entry<K, V> e : m2.entrySet()) {
V newV = TObjects.requireNonNull(e.getValue());
V oldV = m1.putIfAbsent(e.getKey(), newV);
if (oldV != null) {
throw new IllegalStateException(
"Key " + e.getKey() + " corresponds to values " + oldV + " and " + newV);
}
}
return m1;
},
TCollector.Characteristics.IDENTITY_FINISH);
}
public static <E, K, V> TCollector<E, ?, Map<K, V>> toMap(Function<? super E, ? extends K> keyMapper,
Function<? super E, ? extends V> valueMapper, BinaryOperator<V> mergeFunction) {
return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
}
public static <E, K, V, M extends Map<K, V>> TCollector<E, ?, M> toMap(Function<? super E, ? extends K> keyMapper,
Function<? super E, ? extends V> valueMapper, BinaryOperator<V> mergeFunction, Supplier<M> mapFactory) {
return TCollector.of(mapFactory,
(map, el) -> map.merge(keyMapper.apply(el), valueMapper.apply(el), mergeFunction),
(m1, m2) -> {
for (Map.Entry<K, V> e : m2.entrySet()) {
m1.merge(e.getKey(), e.getValue(), mergeFunction);
}
return m1;
},
TCollector.Characteristics.IDENTITY_FINISH);
}
}

View File

@ -18,9 +18,13 @@ package org.teavm.classlib.java.util.stream;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -55,4 +59,23 @@ public class CollectorsTest {
Stream.of(1, 2, 3).collect(Collectors.toCollection(() -> c));
assertEquals(Arrays.asList(1, 2, 3), c);
}
@Test(expected = NullPointerException.class)
public void noNullsInToMap() {
Stream.of(1, 2, null).collect(Collectors.toMap(Function.identity(), Function.identity()));
}
@Test(expected = IllegalStateException.class)
public void noDuplicatesInToMap() {
Stream.of(1, 2, 2).collect(Collectors.toMap(Function.identity(), Function.identity()));
}
@Test
public void toMap() {
Map<Integer, Integer> expected = new HashMap<>();
IntStream.range(1, 4).forEach(i -> expected.put(i, i));
assertEquals(expected,
IntStream.range(1, 4).boxed().collect(Collectors.toMap(Function.identity(), Function.identity())));
}
}