Skip to content

Instantly share code, notes, and snippets.

@pinzolo
Last active March 3, 2016 07:36
Show Gist options
  • Save pinzolo/ab1ff422e89143d862b0 to your computer and use it in GitHub Desktop.
Save pinzolo/ab1ff422e89143d862b0 to your computer and use it in GitHub Desktop.
わりと使える集計メソッド郡
package pinzolo.util.collectors;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
public class ListWithTappingCollector<T> implements Collector<T, List<T>, List<T>> {
private Consumer<List<T>> tapper;
public ListWithTappingCollector(Consumer<List<T>> tapper) {
this.tapper = tapper;
}
@Override
public Supplier<List<T>> supplier() {
return ArrayList<T>::new;
}
@Override
public BiConsumer<List<T>, T> accumulator() {
return (list, obj) -> list.add(obj);
}
@Override
public BinaryOperator<List<T>> combiner() {
return (list1, list2) -> {
list1.addAll(list2);
return list1;
};
}
@Override
public Function<List<T>, List<T>> finisher() {
return (list) -> {
if (tapper != null) {
tapper.accept(list);
}
return list;
};
}
@Override
public Set<Collector.Characteristics> characteristics() {
return Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.UNORDERED));
}
}
package pinzolo.util.collectors;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
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 java.util.stream.Collector;
public class UniqueCountingCollector<T> implements Collector<T, Set<T>, Long> {
@Override
public Supplier<Set<T>> supplier() {
return HashSet<T>::new;
}
@Override
public BiConsumer<Set<T>, T> accumulator() {
return (set, obj) -> set.add(obj);
}
@Override
public BinaryOperator<Set<T>> combiner() {
return (set1, set2) -> {
set1.addAll(set2);
return set1;
};
}
@Override
public Function<Set<T>, Long> finisher() {
return set -> Long.valueOf(set.size());
}
@Override
public Set<Collector.Characteristics> characteristics() {
return Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.UNORDERED));
}
}
package sanaq.util.collectors;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedHashSet;
import java.util.List;
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 java.util.stream.Collector;
public class UniqueListCollector<T> implements Collector<T, Set<T>, List<T>> {
public UniqueListCollector() { }
@Override
public Supplier<Set<T>> supplier() {
return LinkedHashSet<T>::new;
}
@Override
public BiConsumer<Set<T>, T> accumulator() {
return (set, obj) -> set.add(obj);
}
@Override
public BinaryOperator<Set<T>> combiner() {
return (set1, set2) -> {
set1.addAll(set2);
return set1;
};
}
@Override
public Function<Set<T>, List<T>> finisher() {
return ArrayList<T>::new;
}
@Override
public Set<Collector.Characteristics> characteristics() {
return Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.UNORDERED));
}
}
package pinzolo.util;
import static java.util.stream.Collectors.*;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import pinzolo.util.collectors.UniqueCountingCollector;
import pinzolo.util.collectors.ListWithTappingCollector;
import pinzolo.util.collectors.UniqueListCollector;
public class ExCollectors {
public static <T> Collector<T, ?, Long> uniqueCounting() {
return new UniqueCountingCollector<>();
}
public static <T, U> Collector<T, ?, Long> uniqueCounting(Function<T, U> mapper) {
return mapping(mapper, uniqueCounting());
}
public static Collector<BigDecimal, ?, BigDecimal> summingBigDecimal() {
return reducing(BigDecimal.ZERO, BigDecimal::add);
}
public static <T> Collector<T, ?, BigDecimal> summingBigDecimal(Function<T, BigDecimal> mapper) {
return reducing(BigDecimal.ZERO, mapper, BigDecimal::add);
}
public static <T, K> Collector<T, ?, Map<K, List<T>>> ordinalGroupingBy(Function<? super T, ? extends K> classifier) {
return ordinalGroupingBy(classifier, toList());
}
public static <T, K, A, D> Collector<T, ?, Map<K, D>> ordinalGroupingBy(Function<? super T, ? extends K> classifier,
Collector<? super T, A, D> downstream) {
return groupingBy(classifier, LinkedHashMap::new, downstream);
}
public static <T> Collector<T, ?, List<T>> toListWithTapping(Consumer<List<T>> tapper) {
return new ListWithTappingCollector<>(tapper);
}
public static <T> Collector<T, ?, Set<T>> toOrdinalSet() {
return toCollection(LinkedHashSet::new);
}
public static <T> Collector<T, ?, List<T>> toUniqueList() {
return new UniqueListCollector<>();
}
}
package pinzolo.util
import java.util.stream.Collectors
import java.util.stream.Stream
import spock.lang.Specification
class ExCollectorsTestClass {
def value
}
class ExCollectorsTest extends Specification {
def "要素の重複を考慮するカウント"() {
def stream = Stream.of("abc", "aaa", "bbb", "abc")
expect:
stream.collect(ExCollectors.uniqueCounting()) == 3
}
def "メソッド結果による重複考慮カウント"() {
def stream = Stream.of("a", "ab", "abc", "aaa")
expect:
stream.collect(ExCollectors.uniqueCounting { it.length() }) == 3
}
def "BigDecimalの合計を算出する"() {
def stream = Stream.of(new BigDecimal(1), new BigDecimal(2), new BigDecimal(3))
expect:
stream.collect(ExCollectors.summingBigDecimal()) == new BigDecimal(6)
}
def "メソッド結果によるBigDecimal合計算出"() {
def stream = Stream.of(new ExCollectorsTestClass(value: new BigDecimal(1)), new ExCollectorsTestClass(value: new BigDecimal(2)), new ExCollectorsTestClass(value: new BigDecimal(3)))
expect:
stream.collect(ExCollectors.summingBigDecimal { it.value }) == new BigDecimal(6)
}
def "要素順を考慮したグルーピングを行う"() {
def stream = Stream.of("ab", "bc", "abc", "a", "aaa", "abc")
def map = stream.collect(ExCollectors.ordinalGroupingBy( { it.length() }))
expect:
map.size() == 3
map.entrySet()[0].getKey() == 2
map.entrySet()[0].getValue() == ["ab", "bc"]
map.entrySet()[1].getKey() == 3
map.entrySet()[1].getValue() == ["abc", "aaa", "abc"]
map.entrySet()[2].getKey() == 1
map.entrySet()[2].getValue() == ["a"]
}
def "要素順を考慮したグルーピングを行い、finisherを指定する"() {
def stream = Stream.of("ab", "bc", "abc", "a", "aaa")
def map = stream.collect(ExCollectors.ordinalGroupingBy( { it.length() }, Collectors.counting()))
expect:
map.size() == 3
map.entrySet()[0].getKey() == 2
map.entrySet()[0].getValue() == 2
map.entrySet()[1].getKey() == 3
map.entrySet()[1].getValue() == 2
map.entrySet()[2].getKey() == 1
map.entrySet()[2].getValue() == 1
}
def "集約後のリストに対し処理を行う"() {
def stream = Stream.of("a", "b", "c", "d")
def count = 0
def list = stream.collect(ExCollectors.toListWithTapping({ count = it.size() }))
expect:
count == 4
list == ["a", "b", "c", "d"]
}
def "順序を保持したSetを生成する"() {
def stream = Stream.of("b", "c", "b", "a")
def set = stream.collect(ExCollectors.toOrdinalSet())
expect:
set == ["b", "c", "a"] as Set
}
def "重複を取り除いたリストを生成する"() {
def stream = Stream.of("b", "c", "b", "a")
def list = stream.collect(ExCollectors.toUniqueList())
expect:
list == ["b", "c", "a"]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment