Skip to content

Instantly share code, notes, and snippets.

@michalmela
Last active July 24, 2019 13:35
Show Gist options
  • Save michalmela/208b3d3c253ff0ff1a013753a1064846 to your computer and use it in GitHub Desktop.
Save michalmela/208b3d3c253ff0ff1a013753a1064846 to your computer and use it in GitHub Desktop.
import java.util.EnumSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static java.util.Collections.unmodifiableSet;
class Scratch {
public static void main(String[] args) {
System.out.println(
Stream.of("foo").collect(new JoiningWithCutoffCollector<>(2, "_"))
);
System.out.println(
Stream.of("foo", "bar").collect(new JoiningWithCutoffCollector<>(2, "_"))
);
System.out.println(
Stream.of("foo", "bar", "baz").collect(new JoiningWithCutoffCollector<>(2, "_"))
);
System.out.println(
Stream.of("foo", "bar", "baz", "boo").collect(new JoiningWithCutoffCollector<>(2, "_"))
);
}
}
class JoiningWithCutoffCollector<A> implements Collector<A, JoiningWithCutoffCollector.Intermediate, String> {
private final int cutoff;
private final String separator;
private static final String moreSuffix = "-more";
public static class Intermediate {
private final StringBuilder builder;
private final AtomicInteger count;
public Intermediate() {
builder = new StringBuilder();
count = new AtomicInteger(0);
}
public Intermediate(StringBuilder builder, AtomicInteger count) {
this.builder = builder;
this.count = count;
}
}
public JoiningWithCutoffCollector(int cutoff, String separator) {
this.cutoff = cutoff;
this.separator = separator;
}
@Override
public Supplier<Intermediate> supplier() {
return Intermediate::new;
}
@Override
public BiConsumer<Intermediate, A> accumulator() {
return (intermediate, next) -> {
if (intermediate.count.getAndIncrement() < cutoff) {
intermediate.builder.append(intermediate.builder.length() > 0 ? separator : "").append(next);
}
};
}
@Override
public BinaryOperator<Intermediate> combiner() {
return (first, second) -> new Intermediate(
new StringBuilder(String.join(separator, first.builder.toString(), second.builder.toString())),
new AtomicInteger(first.count.get() + second.count.get())
);
}
@Override
public Function<Intermediate, String> finisher() {
return intermediate -> {
int finalCount = intermediate.count.get() - cutoff;
if (finalCount > 0) {
intermediate.builder.append(separator).append(finalCount).append(moreSuffix);
}
return intermediate.builder.toString();
};
}
@Override
public Set<Characteristics> characteristics() {
return emptySet();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment