Last active
March 3, 2016 07:36
-
-
Save pinzolo/ab1ff422e89143d862b0 to your computer and use it in GitHub Desktop.
わりと使える集計メソッド郡
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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<>(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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