classlib: additional stream collectors (#822)

This commit is contained in:
Ivan Hetman 2023-10-16 15:09:56 +03:00 committed by GitHub
parent 65681e74d8
commit 658ef711ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 0 deletions

View File

@ -63,6 +63,10 @@ public final class TCollectors {
return toCollection(HashSet::new); return toCollection(HashSet::new);
} }
public static <T> TCollector<T, ?, Set<T>> toUnmodifiableSet() {
return collectingAndThen(toSet(), Collections::unmodifiableSet);
}
public static TCollector<CharSequence, ?, String> joining() { public static TCollector<CharSequence, ?, String> joining() {
return TCollector.of(StringBuilder::new, StringBuilder::append, StringBuilder::append, return TCollector.of(StringBuilder::new, StringBuilder::append, StringBuilder::append,
StringBuilder::toString); StringBuilder::toString);
@ -90,6 +94,41 @@ public final class TCollectors {
sb -> sb.insert(0, prefix).append(suffix).toString()); sb -> sb.insert(0, prefix).append(suffix).toString());
} }
public static <T, A, R, K> TCollector<T, ?, K> mapping(Function<? super T, ? extends A> mapper,
TCollector<? super A, R, K> downstream) {
BiConsumer<R, ? super A> downstreamAccumulator = downstream.accumulator();
return TCollector.of(downstream.supplier(), (R r, T t) -> downstreamAccumulator.accept(r, mapper.apply(t)),
downstream.combiner(), downstream.finisher(),
downstream.characteristics().toArray(TCollector.Characteristics[]::new));
}
public static <T, A, R, K> TCollector<T, ?, K> flatMapping(
Function<? super T, ? extends TStream<? extends A>> mapper, TCollector<? super A, R, K> downstream) {
BiConsumer<R, ? super A> downstreamAccumulator = downstream.accumulator();
return TCollector.of(downstream.supplier(),
(R r, T t) -> {
TStream<? extends A> result = mapper.apply(t);
if (result != null) {
result.forEach(a -> downstreamAccumulator.accept(r, a));
}
},
downstream.combiner(), downstream.finisher(),
downstream.characteristics().toArray(TCollector.Characteristics[]::new));
}
public static <T, A, R> TCollector<T, ?, R> filtering(Predicate<? super T> predicate,
TCollector<? super T, A, R> downstream) {
BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
return TCollector.of(downstream.supplier(),
(r, t) -> {
if (predicate.test(t)) {
downstreamAccumulator.accept(r, t);
}
},
downstream.combiner(), downstream.finisher(),
downstream.characteristics().toArray(TCollector.Characteristics[]::new));
}
public static <E, K, V> TCollector<E, ?, Map<K, V>> toMap(Function<? super E, ? extends K> keyMapper, public static <E, K, V> TCollector<E, ?, Map<K, V>> toMap(Function<? super E, ? extends K> keyMapper,
Function<? super E, ? extends V> valueMapper) { Function<? super E, ? extends V> valueMapper) {
return TCollector.of(HashMap::new, return TCollector.of(HashMap::new,
@ -116,11 +155,21 @@ public final class TCollectors {
TCollector.Characteristics.IDENTITY_FINISH); TCollector.Characteristics.IDENTITY_FINISH);
} }
public static <E, K, V> TCollector<E, ?, Map<K, V>> toUnmodifiableMap(Function<? super E, ? extends K> keyMapper,
Function<? super E, ? extends V> valueMapper) {
return collectingAndThen(toMap(keyMapper, valueMapper), Collections::unmodifiableMap);
}
public static <E, K, V> TCollector<E, ?, Map<K, V>> toMap(Function<? super E, ? extends K> keyMapper, 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) { Function<? super E, ? extends V> valueMapper, BinaryOperator<V> mergeFunction) {
return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new); return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
} }
public static <E, K, V> TCollector<E, ?, Map<K, V>> toUnmodifiableMap(Function<? super E, ? extends K> keyMapper,
Function<? super E, ? extends V> valueMapper, BinaryOperator<V> mergeFunction) {
return collectingAndThen(toMap(keyMapper, valueMapper, mergeFunction), Collections::unmodifiableMap);
}
public static <E, K, V, M extends Map<K, V>> TCollector<E, ?, M> toMap(Function<? super E, ? extends K> keyMapper, 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) { Function<? super E, ? extends V> valueMapper, BinaryOperator<V> mergeFunction, Supplier<M> mapFactory) {
return TCollector.of(mapFactory, return TCollector.of(mapFactory,

View File

@ -185,4 +185,15 @@ public class CollectorsTest {
assertEquals(Set.of(1, 3, 5, 7, 9), grouped.get(false)); assertEquals(Set.of(1, 3, 5, 7, 9), grouped.get(false));
assertEquals(Set.of(0, 2, 4, 6, 8), grouped.get(true)); assertEquals(Set.of(0, 2, 4, 6, 8), grouped.get(true));
} }
@Test
public void simpleCollectors() {
List<String> l = List.of("a", "b", "c", "d");
assertEquals("aAbBcCdD", l.stream().collect(
Collectors.mapping(s -> s + s.toUpperCase(), Collectors.joining())));
assertEquals("acd", l.stream().collect(
Collectors.filtering(s -> s.indexOf('b') < 0, Collectors.joining())));
assertEquals("aaabbbcccddd", l.stream().collect(
Collectors.flatMapping(s -> Stream.of(s, s, s), Collectors.joining())));
}
} }