Skip to content

Instantly share code, notes, and snippets.

@diversit
Created November 27, 2014 10:34
Show Gist options
  • Save diversit/78103c390e9ceff04c93 to your computer and use it in GitHub Desktop.
Save diversit/78103c390e9ceff04c93 to your computer and use it in GitHub Desktop.
Collector to flatten collections in Java8
/* Flatten list to list */
public static final <T, R> Collector<T, List<R>, List<R>> flattenCollector(Function<T,List<R>> mapper) {
return Collector.of(
() -> new ArrayList<>(),
(l, a) -> l.addAll(mapper.apply(a)),
(l, r) -> { l.addAll(r); return l; },
Collector.Characteristics.UNORDERED
);
}
/* Flatten any collection type to List */
public static final <T, R, C extends Collection<? extends R>> Collector<T, List<R>, List<R>> flattenCollector2(Function<T, C> mapper) {
return Collector.of(
() -> new ArrayList<R>(),
(l, a) -> l.addAll(mapper.apply(a)),
(l, r) -> { l.addAll(r); return l; },
Collector.Characteristics.UNORDERED
);
}
/* Trying to preserve type of collection, but does not work. Suspect because of Generics limitation of Java.
contra-variant/covariant problem. List<String> != Collection<String> in Java.
*/
public static final <T, R, C extends Collection<R>> Collector<T, C, C> flattenCollector3(Supplier<C> resultSupplier, Function<T, C> mapper) {
return Collector.of(
resultSupplier,
(l, a) -> l.addAll(mapper.apply(a)),
(l, r) -> { l.addAll(r); return l; },
Collector.Characteristics.UNORDERED
);
}
public static void main(String[] args) {
Function<String, Collection<Integer>> toStringCharsColl = s -> s.chars().boxed().collect(Collectors.toList());
Collection<Integer> result1 = Stream.of("een", "twee", "drie")
.collect(flattenCollector2(toStringCharsColl));
Collection<Integer> result1a = Stream.of("een", "twee", "drie")
.collect(flattenCollector3(() -> new ArrayList(), toStringCharsColl));
Function<String, List<Integer>> toStringCharsList = s -> s.chars().boxed().collect(Collectors.toList());
List<Integer> result2 = Stream.of("een", "twee", "drie")
.collect(flattenCollector2(toStringCharsList));
List<Integer> result2a = Stream.of("een", "twee", "drie")
.collect(flattenCollector3(() -> new ArrayList(), toStringCharsList));
Function<String, Set<Integer>> toStringCharsSet = s -> s.chars().boxed().collect(Collectors.toSet());
List<Integer> result3 = Stream.of("een", "twee", "drie")
.collect(flattenCollector2(toStringCharsSet));
List<Integer> result3a = Stream.of("een", "twee", "drie")
.collect(flattenCollector3(() -> new HashSet(), toStringCharsSet));
System.out.println("ok");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment