/*
* Copyright 2015, 2016 Tagir Valeev
*
* 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 one.util.streamex;
import static one.util.streamex.TestHelpers.*;
import static java.util.Arrays.asList;
import static org.junit.Assert.*;
import java.util.AbstractMap;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import one.util.streamex.EntryStream;
import one.util.streamex.IntStreamEx;
import one.util.streamex.MoreCollectors;
import one.util.streamex.StreamEx;
import one.util.streamex.StreamExTest.Point;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
/**
* @author Tagir Valeev
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class EntryStreamTest {
private void checkAsString(String expected, EntryStream<?, ?> stream) {
assertEquals(expected, stream.join("->").joining(";"));
}
private Map<String, Integer> createMap() {
Map<String, Integer> data = new LinkedHashMap<>();
data.put("a", 1);
data.put("bb", 22);
data.put("ccc", 33);
return data;
}
@Test
public void testCreate() {
assertEquals(0, EntryStream.empty().count());
assertEquals(0, EntryStream.empty().count());
Map<String, Integer> data = createMap();
assertEquals(data, EntryStream.of(data).toMap());
assertEquals(data, EntryStream.of(data.entrySet().stream()).toMap());
Map<String, Integer> expected = new HashMap<>();
expected.put("aaa", 3);
expected.put("bbb", 3);
expected.put("c", 1);
assertEquals(expected, StreamEx.of("aaa", "bbb", "c").mapToEntry(String::length).toMap());
assertEquals(expected, StreamEx.of("aaa", "bbb", "c").mapToEntry(s -> s, String::length).toMap());
assertEquals(Collections.singletonMap("foo", 1), EntryStream.of("foo", 1).toMap());
assertEquals(createMap(), EntryStream.of("a", 1, "bb", 22, "ccc", 33).toMap());
assertEquals(expected, StreamEx.of(Collections.singletonMap("aaa", 3), Collections.singletonMap("bbb", 3),
Collections.singletonMap("c", 1), Collections.emptyMap()).flatMapToEntry(m -> m).toMap());
EntryStream<String, Integer> stream = EntryStream.of(data);
assertSame(stream.stream(), EntryStream.of(stream).stream());
assertSame(stream.stream(), EntryStream.of(StreamEx.of(EntryStream.of(stream))).stream());
assertEquals(Collections.singletonMap("aaa", 3), EntryStream.of(
Collections.singletonMap("aaa", 3).entrySet().spliterator()).toMap());
assertEquals(Collections.singletonMap("aaa", 3), EntryStream.of(
Collections.singletonMap("aaa", 3).entrySet().iterator()).toMap());
}
@Test
public void testCreateKeyValuePairs() {
checkAsString("a->1", EntryStream.of("a", 1));
checkAsString("a->1;b->2", EntryStream.of("a", 1, "b", 2));
checkAsString("a->1;b->2;c->3", EntryStream.of("a", 1, "b", 2, "c", 3));
checkAsString("a->1;b->2;c->3;d->4", EntryStream.of("a", 1, "b", 2, "c", 3, "d", 4));
checkAsString("a->1;b->2;c->3;d->4;e->5", EntryStream.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5));
checkAsString("a->1;b->2;c->3;d->4;e->5;f->6", EntryStream.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6));
checkAsString("a->1;b->2;c->3;d->4;e->5;f->6;g->7", EntryStream.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f",
6, "g", 7));
checkAsString("a->1;b->2;c->3;d->4;e->5;f->6;g->7;h->8", EntryStream.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5,
"f", 6, "g", 7, "h", 8));
checkAsString("a->1;b->2;c->3;d->4;e->5;f->6;g->7;h->8;i->9", EntryStream.of("a", 1, "b", 2, "c", 3, "d", 4,
"e", 5, "f", 6, "g", 7, "h", 8, "i", 9));
checkAsString("a->1;b->2;c->3;d->4;e->5;f->6;g->7;h->8;i->9;j->10", EntryStream.of("a", 1, "b", 2, "c", 3, "d",
4, "e", 5, "f", 6, "g", 7, "h", 8, "i", 9, "j", 10));
}
@Test
public void testSequential() {
EntryStream<String, Integer> stream = EntryStream.of(createMap());
assertFalse(stream.isParallel());
stream = stream.parallel();
assertTrue(stream.isParallel());
stream = stream.sequential();
assertFalse(stream.isParallel());
}
@Test
public void testZip() {
Map<String, Integer> expected = new HashMap<>();
expected.put("aaa", 3);
expected.put("bbb", 3);
expected.put("c", 1);
assertEquals(expected, EntryStream.zip(asList("aaa", "bbb", "c"), asList(3, 3, 1)).toMap());
assertEquals(expected, EntryStream.zip(new String[] { "aaa", "bbb", "c" }, new Integer[] { 3, 3, 1 }).toMap());
}
@Test
public void testWithIndex() {
Map<Integer, String> map = EntryStream.of(asList("a", "bbb", "cc")).toMap();
assertEquals(3, map.size());
assertEquals("a", map.get(0));
assertEquals("bbb", map.get(1));
assertEquals("cc", map.get(2));
Map<Integer, String> map2 = EntryStream.of(new String[] { "a", "bbb", "cc" }).toMap();
assertEquals(map, map2);
Map<Integer, List<String>> grouping = EntryStream.of(new String[] { "a", "bbb", "cc", null, null }).append(
EntryStream.of(new String[] { "bb", "bbb", "c", null, "e" })).distinct().grouping();
assertEquals(asList("a", "bb"), grouping.get(0));
assertEquals(asList("bbb"), grouping.get(1));
assertEquals(asList("cc", "c"), grouping.get(2));
assertEquals(Collections.singletonList(null), grouping.get(3));
assertEquals(asList(null, "e"), grouping.get(4));
assertEquals("0=a,1=bbb,2=cc", EntryStream.of(new String[] { "a", "bbb", "cc" }).map(Object::toString).joining(
","));
Entry<Integer, String> entry = EntryStream.of(asList("a")).findFirst().get();
// Test equals contract
assertNotEquals(new Object(), entry);
assertNotEquals(entry, new Object());
assertEquals(entry, new AbstractMap.SimpleImmutableEntry<>(0, "a"));
}
@Test(expected = UnsupportedOperationException.class)
public void testWithIndexModify() {
EntryStream.of(Collections.singletonList("1")).forEach(entry -> entry.setValue("2"));
}
@Test
public void testMap() {
assertEquals(asList("1a", "22bb", "33ccc"), EntryStream.of(createMap()).map(
entry -> entry.getValue() + entry.getKey()).toList());
}
@Test
public void testMapKeyValue() {
assertEquals(asList("1a", "22bb", "33ccc"), EntryStream.of(createMap()).mapKeyValue((k, v) -> v + k).toList());
}
@Test
public void testFilter() {
assertEquals(Collections.singletonMap("a", 1), EntryStream.of(createMap()).filterKeys(s -> s.length() < 2)
.toMap());
assertEquals(Collections.singletonMap("bb", 22), EntryStream.of(createMap()).filterValues(v -> v % 2 == 0)
.toMap());
assertEquals(Collections.singletonMap("ccc", 33), EntryStream.of(createMap()).filterKeyValue(
(str, num) -> !str.equals("a") && num != 22).toMap());
}
@Test
public void testPeek() {
List<String> keys = new ArrayList<>();
assertEquals(createMap(), EntryStream.of(createMap()).peekKeys(keys::add).toMap());
assertEquals(asList("a", "bb", "ccc"), keys);
List<Integer> values = new ArrayList<>();
assertEquals(createMap(), EntryStream.of(createMap()).peekValues(values::add).toMap());
assertEquals(asList(1, 22, 33), values);
Map<String, Integer> map = new LinkedHashMap<>();
assertEquals(createMap(), EntryStream.of(createMap()).peekKeyValue(map::put).toMap());
assertEquals(createMap(), map);
}
@Test
public void testRemove() {
Map<String, List<Integer>> data = new HashMap<>();
data.put("aaa", Collections.emptyList());
data.put("bbb", Collections.singletonList(1));
assertEquals(asList("bbb"), EntryStream.of(data).removeValues(List::isEmpty).keys().toList());
assertEquals(asList("aaa"), EntryStream.of(data).removeKeys(Pattern.compile("bbb").asPredicate()).keys()
.toList());
assertEquals(EntryStream.of("a", 1, "bb", 22).toMap(), EntryStream.of(createMap()).removeKeyValue(
(str, num) -> !str.equals("a") && num != 22).toMap());
}
@Test
public void testLimit() {
assertEquals(Collections.singletonMap("a", 1), EntryStream.of(createMap()).limit(1).toMap());
}
@Test
public void testKeys() {
assertEquals(new HashSet<>(asList("a", "bb", "ccc")), EntryStream.of(createMap()).keys().toSet());
}
@Test
public void testValues() {
assertEquals(new HashSet<>(asList(1, 22, 33)), EntryStream.of(createMap()).values().toSet());
}
@Test
public void testMapKeys() {
Map<Integer, Integer> expected = new HashMap<>();
expected.put(1, 1);
expected.put(2, 22);
expected.put(3, 33);
Map<Integer, Integer> result = EntryStream.of(createMap()).mapKeys(String::length).toMap();
assertEquals(expected, result);
}
@Test
public void testMapValues() {
Map<String, String> expected = new HashMap<>();
expected.put("a", "1");
expected.put("bb", "22");
expected.put("ccc", "33");
Map<String, String> result = EntryStream.of(createMap()).mapValues(String::valueOf).toMap();
assertEquals(expected, result);
}
@Test
public void testMapToValue() {
Map<String, Integer> expected = new HashMap<>();
expected.put("a", 2);
expected.put("bb", 24);
expected.put("ccc", 36);
Map<String, Integer> result = EntryStream.of(createMap()).mapToValue((str, num) -> str.length() + num).toMap();
assertEquals(expected, result);
}
@Test
public void testMapToKey() {
Map<String, Integer> expected = new HashMap<>();
expected.put("a:1", 1);
expected.put("bb:22", 22);
expected.put("ccc:33", 33);
Map<String, Integer> result = EntryStream.of(createMap()).mapToKey((str, num) -> str + ":" + num).toMap();
assertEquals(expected, result);
}
@Test
public void testAppend() {
assertEquals(asList(22, 33, 5, 22, 33), EntryStream.of(createMap()).append("dddd", 5).append(createMap())
.filterKeys(k -> k.length() > 1).values().toList());
assertEquals(EntryStream.of(createMap()).toList(), EntryStream.empty().append("a", 1, "bb", 22, "ccc", 33)
.toList());
checkAsString("bb->22;a->1;ccc->33", EntryStream.of("bb", 22).append("a", 1, "ccc", 33));
EntryStream<String, Integer> stream = EntryStream.of("a", 1, "b", 2);
assertSame(stream, stream.append(Collections.emptyMap()));
assertNotSame(stream, stream.append(new ConcurrentHashMap<>()));
}
@Test
public void testPrepend() {
assertEquals(asList(5, 22, 33, 22, 33), EntryStream.of(createMap()).prepend(createMap()).prepend("dddd", 5)
.filterKeys(k -> k.length() > 1).values().toList());
checkAsString("a->1;ccc->33;bb->22", EntryStream.of("bb", 22).prepend("a", 1, "ccc", 33));
checkAsString("a->1;ccc->33;dddd->40;bb->22", EntryStream.of("bb", 22).prepend("a", 1, "ccc", 33, "dddd", 40));
EntryStream<String, Integer> stream = EntryStream.of("a", 1, "b", 2);
assertSame(stream, stream.prepend(Collections.emptyMap()));
assertNotSame(stream, stream.prepend(new ConcurrentHashMap<>()));
}
@Test
public void testToMap() {
Map<String, Integer> base = IntStreamEx.range(100).mapToEntry(String::valueOf, Integer::valueOf).toMap();
entryStream(() -> EntryStream.of(base), supplier -> {
TreeMap<String, Integer> result = supplier.get().toCustomMap(TreeMap::new);
assertEquals(base, result);
});
Map<Integer, String> expected = new HashMap<>();
expected.put(3, "aaa");
expected.put(2, "bbdd");
Function<StreamExSupplier<String>, EntryStream<Integer, String>> fn = supplier -> supplier.get().mapToEntry(
String::length, Function.identity());
streamEx(() -> StreamEx.of("aaa", "bb", "dd"), supplier -> {
HashMap<Integer, String> customMap = fn.apply(supplier).toCustomMap(String::concat, HashMap::new);
assertEquals(expected, customMap);
Map<Integer, String> map = fn.apply(supplier).toMap(String::concat);
assertEquals(expected, map);
SortedMap<Integer, String> sortedMap = fn.apply(supplier).toSortedMap(String::concat);
assertEquals(expected, sortedMap);
NavigableMap<Integer, String> navigableMap = fn.apply(supplier).toNavigableMap(String::concat);
assertEquals(expected, navigableMap);
checkIllegalStateException(() -> fn.apply(supplier).toMap(), "2", "dd", "bb");
checkIllegalStateException(() -> fn.apply(supplier).toSortedMap(), "2", "dd", "bb");
checkIllegalStateException(() -> fn.apply(supplier).toNavigableMap(), "2", "dd", "bb");
checkIllegalStateException(() -> fn.apply(supplier).toCustomMap(HashMap::new), "2", "dd", "bb");
});
assertEquals(createMap(), EntryStream.of(createMap()).parallel().toMap());
assertTrue(EntryStream.of(createMap()).parallel().toMap() instanceof ConcurrentMap);
SortedMap<String, Integer> sortedMap2 = EntryStream.of(createMap()).toSortedMap();
assertEquals(createMap(), sortedMap2);
assertFalse(sortedMap2 instanceof ConcurrentMap);
sortedMap2 = EntryStream.of(createMap()).parallel().toSortedMap();
assertEquals(createMap(), sortedMap2);
assertTrue(sortedMap2 instanceof ConcurrentMap);
}
@Test
public void testToMapAndThen() {
Map<String, Integer> map = EntryStream.of(createMap()).append("d", 4).toMapAndThen(EntryStream::of).append("e",
5).toMap();
Map<String, Integer> expected = EntryStream.of("a", 1, "bb", 22, "ccc", 33, "d", 4, "e", 5).toMap();
assertEquals(expected, map);
}
@Test
public void testFlatMap() {
assertEquals(asList((int) 'a', (int) 'b', (int) 'b', (int) 'c', (int) 'c', (int) 'c'), EntryStream.of(
createMap()).flatMap(entry -> entry.getKey().chars().boxed()).toList());
assertEquals(asList("a", "b", "b", "c", "c", "c"), EntryStream.of(createMap()).flatCollection(
entry -> asList(entry.getKey().split(""))).toList());
assertEquals(asList("a", 1, "bb", 22, "ccc", 33), EntryStream.of(createMap()).flatMapKeyValue(
(str, num) -> Stream.of(str, num)).toList());
}
@Test
public void testFlatMapKeys() {
Map<String, List<Integer>> data = new HashMap<>();
data.put("aaa", asList(1, 2, 3));
data.put("bb", asList(2, 3, 4));
Map<Integer, List<String>> result = EntryStream.of(data).invert().flatMapKeys(List::stream).grouping();
Map<Integer, List<String>> expected = new HashMap<>();
expected.put(1, asList("aaa"));
expected.put(2, asList("aaa", "bb"));
expected.put(3, asList("aaa", "bb"));
expected.put(4, asList("bb"));
assertEquals(expected, result);
assertEquals(0, EntryStream.<Stream<String>, String> of(null, "a").flatMapKeys(Function.identity()).count());
}
@Test
public void testFlatMapToValue() {
checkAsString("a->a;a->aa;a->aaa;b->b;b->bb", EntryStream.of("a", 3, "b", 2, "c", 0).flatMapToValue(
(str, cnt) -> cnt == 0 ? null : IntStream.rangeClosed(1, cnt).mapToObj(
idx -> StreamEx.constant(str, idx).joining())));
}
@Test
public void testFlatMapToKey() {
checkAsString("a->3;aa->3;aaa->3;b->2;bb->2", EntryStream.of("a", 3, "c", 0, "b", 2).flatMapToKey(
(str, cnt) -> cnt == 0 ? null : IntStream.rangeClosed(1, cnt).mapToObj(
idx -> StreamEx.constant(str, idx).joining())));
}
@Test
public void testFlatMapValues() {
Map<String, List<Integer>> data1 = new HashMap<>();
data1.put("aaa", asList(1, 2, 3));
data1.put("bb", asList(4, 5, 6));
Map<String, List<Integer>> data2 = new HashMap<>();
data2.put("aaa", asList(10));
data2.put("bb", asList(20));
data2.put("cc", null);
Map<String, List<Integer>> result = StreamEx.of(data1, data2, null).flatMapToEntry(m -> m).flatMapValues(
l -> l == null ? null : l.stream()).grouping();
Map<String, List<Integer>> expected = new HashMap<>();
expected.put("aaa", asList(1, 2, 3, 10));
expected.put("bb", asList(4, 5, 6, 20));
assertEquals(expected, result);
// Find the key which contains the biggest value in the list
assertEquals("bb", EntryStream.of(data1).flatMapValues(List::stream).maxByInt(Entry::getValue).map(
Entry::getKey).orElse(null));
}
@Test
public void testGrouping() {
Map<String, Integer> data = new LinkedHashMap<>();
data.put("ab", 1);
data.put("ac", 2);
data.put("ba", 3);
data.put("bc", 4);
Map<String, List<Integer>> expected = new LinkedHashMap<>();
expected.put("a", asList(1, 2));
expected.put("b", asList(3, 4));
Supplier<EntryStream<String, Integer>> s = () -> EntryStream.of(data).mapKeys(k -> k.substring(0, 1));
Map<String, List<Integer>> result = s.get().grouping();
assertEquals(expected, result);
TreeMap<String, List<Integer>> resultTree = s.get().grouping(TreeMap::new);
assertEquals(expected, resultTree);
result = s.get().parallel().grouping();
assertEquals(expected, result);
resultTree = s.get().parallel().grouping(TreeMap::new);
assertEquals(expected, resultTree);
streamEx(() -> IntStreamEx.range(1000).boxed(), supplier -> {
assertEquals(EntryStream.of(0, 500, 1, 500).toMap(), supplier.get().mapToEntry(i -> i / 500, i -> i)
.grouping(MoreCollectors.countingInt()));
ConcurrentSkipListMap<Integer, Integer> map = supplier.get().mapToEntry(i -> i / 500, i -> i).grouping(
ConcurrentSkipListMap::new, MoreCollectors.countingInt());
assertEquals(EntryStream.of(0, 500, 1, 500).toMap(), map);
});
}
@Test
public void testGroupingTo() {
Map<String, Integer> data = new LinkedHashMap<>();
data.put("ab", 1);
data.put("ac", 2);
data.put("ba", 3);
data.put("bc", 4);
Map<String, List<Integer>> expected = new LinkedHashMap<>();
expected.put("a", asList(1, 2));
expected.put("b", asList(3, 4));
Supplier<EntryStream<String, Integer>> s = () -> EntryStream.of(data).mapKeys(k -> k.substring(0, 1));
Map<String, List<Integer>> result = s.get().groupingTo(LinkedList::new);
assertEquals(expected, result);
assertTrue(result.get("a") instanceof LinkedList);
result = s.get().parallel().groupingTo(LinkedList::new);
assertEquals(expected, result);
assertTrue(result.get("a") instanceof LinkedList);
SortedMap<String, List<Integer>> resultTree = s.get().groupingTo(TreeMap::new, LinkedList::new);
assertTrue(result.get("a") instanceof LinkedList);
assertEquals(expected, resultTree);
resultTree = s.get().parallel().groupingTo(TreeMap::new, LinkedList::new);
assertTrue(result.get("a") instanceof LinkedList);
assertEquals(expected, resultTree);
resultTree = s.get().parallel().groupingTo(ConcurrentSkipListMap::new, LinkedList::new);
assertTrue(result.get("a") instanceof LinkedList);
assertEquals(expected, resultTree);
}
@Test
public void testSorting() {
Map<String, Integer> data = createMap();
LinkedHashMap<String, Integer> result = EntryStream.of(data).reverseSorted(Entry.comparingByValue())
.toCustomMap(LinkedHashMap::new);
assertEquals("{ccc=33, bb=22, a=1}", result.toString());
}
@Test
public void testDistinct() {
Map<String, List<Integer>> expected = new LinkedHashMap<>();
expected.put("aaa", asList(3));
expected.put("bbb", asList(3, 3));
expected.put("cc", asList(2));
assertEquals(expected, StreamEx.of("aaa", "bbb", "bbb", "cc").mapToEntry(String::length).grouping());
Map<String, List<Integer>> expectedDistinct = new LinkedHashMap<>();
expectedDistinct.put("aaa", asList(3));
expectedDistinct.put("bbb", asList(3));
expectedDistinct.put("cc", asList(2));
assertEquals(expectedDistinct, StreamEx.of("aaa", "bbb", "bbb", "cc").mapToEntry(String::length).distinct()
.grouping());
}
@Test
public void testNonNull() {
Map<String, String> input = new LinkedHashMap<>();
input.put("a", "b");
input.put("b", null);
input.put(null, "c");
assertEquals(asList("b", null), EntryStream.of(input).nonNullKeys().values().toList());
assertEquals(asList("a", null), EntryStream.of(input).nonNullValues().keys().toList());
assertEquals(Collections.singletonMap("a", "b"), EntryStream.of(input).nonNullValues().nonNullKeys().toMap());
}
@Test
public void testSelect() {
Map<Object, Object> map = new LinkedHashMap<>();
map.put("a", 1);
map.put("b", "2");
map.put(3, "c");
assertEquals(Collections.singletonMap("a", 1), EntryStream.of(map).selectValues(Integer.class).toMap());
assertEquals(Collections.singletonMap(3, "c"), EntryStream.of(map).selectKeys(Integer.class).toMap());
// Weird way to create a map from the array. Don't do this in production
// code!
Object[] interleavingArray = { "a", 1, "bb", 22, "ccc", 33 };
Map<String, Integer> result = EntryStream.of(
StreamEx.of(interleavingArray).pairMap(SimpleEntry<Object, Object>::new)).selectKeys(String.class)
.selectValues(Integer.class).toMap();
assertEquals(createMap(), result);
}
@Test
public void testInvert() {
Map<Integer, String> result = EntryStream.of(createMap()).invert().toMap();
Map<Integer, String> expected = new LinkedHashMap<>();
expected.put(1, "a");
expected.put(22, "bb");
expected.put(33, "ccc");
assertEquals(expected, result);
}
@Test(expected = IllegalStateException.class)
public void testCollision() {
StreamEx.of("aa", "aa").mapToEntry(String::length).toCustomMap(LinkedHashMap::new);
}
@Test
public void testForKeyValue() {
Map<String, Integer> output = new HashMap<>();
EntryStream.of(createMap()).forKeyValue(output::put);
assertEquals(output, createMap());
}
@Test
public void testJoin() {
assertEquals("a = 1; bb = 22; ccc = 33", EntryStream.of(createMap()).join(" = ").joining("; "));
assertEquals("{[a = 1]; [bb = 22]; [ccc = 33]}", EntryStream.of(createMap()).join(" = ", "[", "]").joining(
"; ", "{", "}"));
}
@Test
public void testOfPairs() {
withRandom(r -> {
Point[] pts = StreamEx.generate(() -> new Point(r.nextDouble(), r.nextDouble())).limit(100).toArray(
Point[]::new);
double expected = StreamEx.of(pts).cross(pts).mapKeyValue(Point::distance).mapToDouble(Double::doubleValue)
.max().getAsDouble();
entryStream(() -> EntryStream.ofPairs(pts), supplier -> assertEquals(expected, supplier.get().mapKeyValue(
Point::distance).mapToDouble(Double::doubleValue).max().getAsDouble(), 0.0));
});
}
@Test
public void testDistinctKeysValues() {
entryStream(() -> EntryStream.of(1, "a", 1, "b", 2, "b", 2, "c", 1, "c", 3, "c"), s -> {
checkAsString("1->a;2->b;3->c", s.get().distinctKeys());
checkAsString("1->a;1->b;2->c", s.get().distinctValues());
});
}
@Test
public void testOfTree() {
entryStream(() -> EntryStream.ofTree("a", (Integer depth, String str) -> null), supplier -> checkAsString(
"0->a", supplier.get()));
List<Object> input = Arrays.asList("aa", null, asList(asList("bbbb", "cc", null, asList()), "ddd", Arrays
.asList("e"), asList("fff")), "ggg");
@SuppressWarnings("unchecked")
Supplier<Stream<Entry<Integer, Object>>> base = () -> EntryStream.ofTree(input, List.class, (depth, l) -> l
.stream());
entryStream(base, supplier -> assertEquals("{1=[aa, ggg], 2=[ddd], 3=[bbbb, cc, e, fff]}", supplier.get()
.selectValues(String.class).grouping(TreeMap::new).toString()));
Set<Integer> set = new HashSet<>();
try(EntryStream<Integer, String> stream = EntryStream.ofTree("", (Integer depth, String str) -> depth >= 3 ? null : Stream.of("a", "b")
.map(str::concat).onClose(() -> set.add(depth)))) {
assertEquals(15, stream.count());
}
assertEquals(StreamEx.of(0, 1, 2).toSet(), set);
boolean catched = false;
try(EntryStream<Integer, String> stream = EntryStream.ofTree("", (Integer depth, String str) -> depth >= 3 ? null : Stream.of("a", "b")
.map(str::concat).onClose(() -> {throw new IllegalArgumentException(String.valueOf(depth));}))) {
stream.count();
}
catch(IllegalArgumentException iae) {
catched = true;
assertEquals("2", iae.getMessage());
assertEquals(2, iae.getSuppressed().length);
assertEquals("1", iae.getSuppressed()[0].getMessage());
assertEquals("0", iae.getSuppressed()[1].getMessage());
}
assertTrue(catched);
entryStream(() -> EntryStream.ofTree("", (Integer depth, String str) -> depth >= 3 ? null : Stream.of("a", "b")
.map(str::concat)), supplier -> {
assertEquals(asList("", "a", "aa", "aaa", "aab", "ab", "aba", "abb", "b", "ba", "baa", "bab", "bb", "bba",
"bbb"), supplier.get().values().toList());
assertTrue(supplier.get().values().has("bbb"));
assertFalse(supplier.get().values().has("ccc"));
assertEquals(asList("a", "b", "aa", "ab", "ba", "bb", "aaa", "aab", "aba", "abb", "baa", "bab", "bba",
"bbb"), supplier.get().sorted(Entry.comparingByKey()).values().without("").toList());
});
}
@Test
public void testCollapseKeys() {
entryStream(() -> EntryStream.of(1, "a", 1, "b", 2, "c", 3, "d", 1, "e", 1, "f", 1, "g"), s -> checkAsString(
"1->[a, b];2->[c];3->[d];1->[e, f, g]", s.get().collapseKeys()));
entryStream(() -> EntryStream.of(1, "a", 1, "b", 2, "c", 3, "d", 1, "e", 1, "f", 1, "g"), s -> checkAsString(
"1->ab;2->c;3->d;1->efg", s.get().collapseKeys(String::concat)));
entryStream(() -> EntryStream.of(1, "a", 1, "b", 2, "c", 3, "d", 1, "e", 1, "f", 1, "g"), s -> checkAsString(
"1->a+b;2->c;3->d;1->e+f+g", s.get().collapseKeys(Collectors.joining("+"))));
// batches by 3
Stream<String> s = Stream.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j");
assertEquals(asList(asList("a", "b", "c"), asList("d", "e", "f"), asList("g", "h", "i"), asList("j")),
IntStreamEx.ints().flatMapToObj(i -> StreamEx.constant(i, 3)).zipWith(s).collapseKeys().values().toList());
}
@Test
public void testChain() {
assertEquals(EntryStream.of(1, "a", 2, "b", 3, "c").toList(), EntryStream.of(1, "a", 2, "b", 2, "b", 3, "c")
.chain(StreamEx::of).collapse(Objects::equals).toList());
}
@Test
public void testImmutableMap() {
repeat(4, n -> {
Map<Integer, Integer> expected = new HashMap<>();
for (int i = n; i < 4; i++)
expected.put(i, i);
streamEx(() -> IntStreamEx.range(4).atLeast(n).boxed(), s -> {
Map<Integer, Integer> map = s.get().mapToEntry(Function.identity()).toImmutableMap();
assertEquals(expected, map);
try {
map.put(-1, -1);
fail("added");
} catch (UnsupportedOperationException e) {
// expected
}
});
});
}
@Test
public void testInto() {
for(AbstractMap<String, Integer> m : Arrays.<AbstractMap<String, Integer>>asList(new HashMap<>(), new TreeMap<>(), new ConcurrentHashMap<>())) {
AbstractMap<String, Integer> res = EntryStream.of("a", 1, "b", 2, "c", 3).into(m);
assertSame(m, res);
assertEquals(EntryStream.of("a", 1, "b", 2, "c", 3).toMap(), m);
Map<String, Integer> res2 = EntryStream.of("d", 4, "e", 5).parallel().into(m);
assertSame(m, res2);
assertEquals(EntryStream.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5).toMap(), m);
checkIllegalStateException(() -> EntryStream.of("x", 10, "c", 4).into(m), "c", "3", "4");
checkIllegalStateException(() -> EntryStream.of("y", 20, "d", 5).parallel().into(m), "d", "4", "5");
}
}
@Test
public void testPrefixKeys() {
Map<String, Integer> map = EntryStream.of("a", 1, "b", 2, "c", 3, "d", 4).prefixValues(Integer::sum).toMap();
assertEquals(EntryStream.of("a", 1, "b", 3, "c", 6, "d", 10).toMap(), map);
}
@Test
public void testPrefixValues() {
Map<String, Integer> map = EntryStream.of("a", 1, "b", 2, "c", 3, "d", 4).prefixKeys(String::concat).toMap();
assertEquals(EntryStream.of("a", 1, "ab", 2, "abc", 3, "abcd", 4).toMap(), map);
}
}