部分内容来自以下博客:
https://www.jianshu.com/p/7eaa0969b424
1 流式处理
JDK1.8中新增的流式处理提供了一种高效且易于使用的处理数据的方式,它可以对集合执行非常复杂的查找、过滤和映射数据等操作,极大的简化了对于集合的使用。借助流式处理,可以像使用SQL语句一样对集合进行操作。
JDK1.8通过内部迭代来实现对流的处理,一个流式处理可以分为三个部分:转换成流、中间操作、终止操作。
2 Collector接口
在对流进行的终止操作中,有一个方法是collect(),其作用是收集元素并进行处理,最终返回处理后的非流对象。
查看其方法定义如下:
R collect(Collector super T, A, R> collector);
可以看到,collect()方法要求传入一个Collector接口的实例对象,Collector可以看做是用来处理流的工具,在Collectors里面封装了很多Collector工具。
2.1 全局变量
Collector主要包含五个参数,它的行为也是由这五个参数来定义的,如下所示:
// supplier参数用于生成结果容器,容器类型为A。
Supplier supplier();
// accumulator用于归纳元素,泛型T就是元素,它会将流中的元素同结果容器A发生操作。
BiConsumer accumulator();
// combiner用于合并两个并行执行的结果,将其合并为最终结果A。
BinaryOperator combiner();
// finisher用于将之前完整的结果R转为A。
Function finisher();
// characteristics表示当前Collector的特征值,是一个不可变的Set。
Set characteristics();
2.2 枚举
Characteristics这个特征值是一个枚举:
enum Characteristics {// 多线程并行。CONCURRENT,// 无序。UNORDERED,// 无需转换结果。IDENTITY_FINISH
}
2.3 构造方法
Collector拥有两个of方法用于生成Collector实例,其中一个拥有上面所有五个参数,另一个四个参数,不包括finisher参数。
// 四参方法,用于生成一个Collector,T代表流中的元素,R代表最终的结果。因为没有finisher参数,所以需要有IDENTITY_FINISH特征值。
public static Collector of(Supplier supplier,BiConsumer accumulator,BinaryOperator combiner,Characteristics... characteristics) {Objects.requireNonNull(supplier);Objects.requireNonNull(accumulator);Objects.requireNonNull(combiner);Objects.requireNonNull(characteristics);Set cs &#61; (characteristics.length &#61;&#61; 0)? Collectors.CH_ID: Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH,characteristics));return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, cs);
}// 五参方法&#xff0c;用于生成一个Collector&#xff0c;T代表流中的元素&#xff0c;A代表中间结果&#xff0c;R代表最终结果&#xff0c;finisher用于将A转换为R。
public static Collector of(Supplier supplier,BiConsumer accumulator,BinaryOperator combiner,Function finisher,Characteristics... characteristics) {Objects.requireNonNull(supplier);Objects.requireNonNull(accumulator);Objects.requireNonNull(combiner);Objects.requireNonNull(finisher);Objects.requireNonNull(characteristics);Set cs &#61; Collectors.CH_NOID;if (characteristics.length > 0) {cs &#61; EnumSet.noneOf(Characteristics.class);Collections.addAll(cs, characteristics);cs &#61; Collections.unmodifiableSet(cs);}return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, finisher, cs);
}
3 Collectors工具类
Collectors是一个工具类&#xff0c;是JDK预实现Collector的工具类&#xff0c;它内部提供了多种Collector。
3.1 toCollection方法
将流中的元素全部放置到一个集合中返回&#xff0c;这里使用Collection&#xff0c;泛指多种集合。
方法&#xff1a;
public static > Collector toCollection(Supplier collectionFactory) {return new CollectorImpl<>(collectionFactory, Collection::add,(r1, r2) -> { r1.addAll(r2); return r1; },CH_ID);
}
实例&#xff1a;
public static void main(String[] args) {List list &#61; Arrays.asList("123", "521", "100", "228", "838", "250", "345");System.out.println(list);// [123, 521, 100, 228, 838, 250, 345]LinkedList newList &#61; list.stream().collect(Collectors.toCollection(LinkedList::new));System.out.println(newList);// [123, 521, 100, 228, 838, 250, 345]
}
3.2 toList方法
将流中的元素放置到一个List集合中返回&#xff0c;默认为ArrayList。
方法&#xff1a;
public static
Collector> toList() {return new CollectorImpl<>((Supplier>) ArrayList::new, List::add,(left, right) -> { left.addAll(right); return left; },CH_ID);
}
实例&#xff1a;
public static void main(String[] args) {List list &#61; Arrays.asList("123", "521", "100", "228", "838", "250", "345");System.out.println(list);// [123, 521, 100, 228, 838, 250, 345]List newList &#61; list.stream().collect(Collectors.toList());System.out.println(newList);// [123, 521, 100, 228, 838, 250, 345]
}
3.3 toSet方法
将流中的元素放置到一个Set集合中返回&#xff0c;默认为HashSet。
方法&#xff1a;
public static Collector> toSet() {return new CollectorImpl<>((Supplier>) HashSet::new, Set::add,(left, right) -> { left.addAll(right); return left; },CH_UNORDERED_ID);
}
实例&#xff1a;
public static void main(String[] args) {List list &#61; Arrays.asList("123", "521", "100", "228", "838", "250", "345");System.out.println(list);// [123, 521, 100, 228, 838, 250, 345]Set newSet &#61; list.stream().collect(Collectors.toSet());System.out.println(newSet);// [100, 123, 521, 345, 228, 838, 250]
}
3.4 toMap方法
根据传入的键生成器和值生成器&#xff0c;将生成的键和值保存到一个Map中返回&#xff0c;键和值的生成都依赖于元素&#xff0c;可以指定出现重复键时的处理方案和保存结果的Map。
还有支持并发toConcurrentMap方法&#xff0c;同样有三种重载方法&#xff0c;与toMap基本一致&#xff0c;只是它最后使用的Map是并发ConcurrentHashMap。
方法&#xff1a;
// 指定键和值的生成方式&#xff0c;遇到键冲突的情况默认抛出异常&#xff0c;默认使用HashMap。
public static Collector> toMap(Function super T, ? extends K> keyMapper,Function super T, ? extends U> valueMapper) {return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
}
// 指定键和值的生成方式&#xff0c;遇到键冲突的情况使用传入的方法处理&#xff0c;默认使用HashMap。
public static Collector> toMap(Function super T, ? extends K> keyMapper,Function super T, ? extends U> valueMapper,BinaryOperator mergeFunction) {return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
}
// 指定键和值的生成方式&#xff0c;遇到键冲突的情况使用传入的方法处理&#xff0c;使用传入的Map类型返回数据。前两种方式最终还是调用此方法来返回Map数据。
public static > Collector toMap(Function super T, ? extends K> keyMapper,Function super T, ? extends U> valueMapper,BinaryOperator mergeFunction,Supplier mapSupplier) {BiConsumer accumulator &#61; (map, element) -> map.merge(keyMapper.apply(element),valueMapper.apply(element),mergeFunction);return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
}
实例&#xff1a;
public static void main(String[] args) {Map newMap &#61; null;List list &#61; Arrays.asList("123", "521", "100", "228", "838", "250", "345");System.out.println(list);// [123, 521, 100, 228, 838, 250, 345]// 123和100的键都是1&#xff0c;导致冲突&#xff0c;默认抛出异常&#xff0c;使用limit截取前两个元素。newMap &#61; list.stream().limit(2).collect(Collectors.toMap(e -> e.substring(0, 1), e -> e));System.out.println(newMap);// {1&#61;123, 5&#61;521}// 传入主键冲突时的处理方法&#xff0c;保留先插入的值&#xff0c;默认使用HashMap&#xff0c;对主键由小到大排序。newMap &#61; list.stream().collect(Collectors.toMap(e -> e.substring(0, 1), e -> e, (m, n) -> m));System.out.println(newMap);// {1&#61;123, 2&#61;228, 3&#61;345, 5&#61;521, 8&#61;838}// 传入主键冲突时的处理方法&#xff0c;保留新插入的值&#xff0c;默认使用LinkedHashMap&#xff0c;对主键按照插入顺序排序。newMap &#61; list.stream().collect(Collectors.toMap(e -> e.substring(0, 1), e -> e, (m, n) -> n, LinkedHashMap::new));System.out.println(newMap);// {1&#61;100, 5&#61;521, 2&#61;250, 8&#61;838, 3&#61;345}
}
3.5 joining方法
将流中的元素全部以字符串的方式连接到一起&#xff0c;可以指定连接符&#xff0c;也可以指定前后缀。
方法&#xff1a;
// 将流中的元素全部以字符串的方式连接到一起&#xff0c;不使用连接符&#xff0c;也不指定前后缀。
public static Collector joining() {return new CollectorImpl(StringBuilder::new, StringBuilder::append,(r1, r2) -> { r1.append(r2); return r1; },StringBuilder::toString, CH_NOID);
}
// 将流中的元素全部以字符串的方式连接到一起&#xff0c;使用指定的连接符&#xff0c;不指定前后缀。
public static Collector joining(CharSequence delimiter) {return joining(delimiter, "", "");
}
// 将流中的元素全部以字符串的方式连接到一起&#xff0c;使用指定的连接符&#xff0c;使用指定的前后缀。
public static Collector joining(CharSequence delimiter,CharSequence prefix,CharSequence suffix) {return new CollectorImpl<>(() -> new StringJoiner(delimiter, prefix, suffix),StringJoiner::add, StringJoiner::merge,StringJoiner::toString, CH_NOID);
}
实例&#xff1a;
public static void main(String[] args) {String str &#61; null;List list &#61; Arrays.asList("123", "521", "100", "228", "838", "250", "345");System.out.println(list);// [123, 521, 100, 228, 838, 250, 345]str &#61; list.stream().collect(Collectors.joining());System.out.println(str);// 123521100228838250345str &#61; list.stream().collect(Collectors.joining("-"));System.out.println(str);// 123-521-100-228-838-250-345str &#61; list.stream().collect(Collectors.joining("-", "<", ">"));System.out.println(str);// <123-521-100-228-838-250-345>
}
3.6 mapping方法
将流中的元素按照传入的方法进行处理&#xff0c;并将结果按照指定的格式返回。
方法&#xff1a;
public static
Collector mapping(Function super T, ? extends U> mapper,Collector super U, A, R> downstream) {BiConsumer downstreamAccumulator &#61; downstream.accumulator();return new CollectorImpl<>(downstream.supplier(),(r, t) -> downstreamAccumulator.accept(r, mapper.apply(t)),downstream.combiner(),downstream.finisher(),downstream.characteristics());
}
实例&#xff1a;
public static void main(String[] args) {List scoreList &#61; new ArrayList();scoreList.add(new Score("2019", "10", "张三", 1));scoreList.add(new Score("2019", "11", "李四", 1));scoreList.add(new Score("2019", "12", "王五", 1));List names &#61; scoreList.stream().collect(Collectors.mapping(Score::getName, Collectors.toList()));System.out.println(names);// [张三, 李四, 王五]
}
3.7 collectingAndThen方法
该方法是按照传入的collector处理完之后&#xff0c;对归纳的结果进行再处理。
方法&#xff1a;
public static Collector collectingAndThen(Collector downstream,Function finisher) {Set characteristics &#61; downstream.characteristics();if (characteristics.contains(Collector.Characteristics.IDENTITY_FINISH)) {if (characteristics.size() &#61;&#61; 1)characteristics &#61; Collectors.CH_NOID;else {characteristics &#61; EnumSet.copyOf(characteristics);characteristics.remove(Collector.Characteristics.IDENTITY_FINISH);characteristics &#61; Collections.unmodifiableSet(characteristics);}}return new CollectorImpl<>(downstream.supplier(),downstream.accumulator(),downstream.combiner(),downstream.finisher().andThen(finisher),characteristics);
}
实例&#xff1a;
public static void main(String[] args) {List list &#61; Arrays.asList("123", "521", "100", "228", "838", "250", "345");System.out.println(list);// [123, 521, 100, 228, 838, 250, 345]Integer size &#61; list.stream().collect(Collectors.collectingAndThen(Collectors.toList(), List::size));System.out.println(size);// 7
}
3.8 counting方法
该方法主要用来计数。
方法&#xff1a;
public static Collector counting() {return reducing(0L, e -> 1L, Long::sum);
}
实例&#xff1a;
public static void main(String[] args) {List list &#61; Arrays.asList("123", "521", "100", "228", "838", "250", "345");System.out.println(list);// [123, 521, 100, 228, 838, 250, 345]Long count &#61; list.stream().collect(Collectors.counting());System.out.println(count);// 7
}
3.9 reducing方法
对流中的元素做统计归纳&#xff0c;有三个重载方法&#xff0c;和Stream里的三个reduce方法对应&#xff0c;二者是可以替换使用的&#xff0c;作用完全一致。
方法&#xff1a;
// 返回一个可以直接产生Optional类型结果的Collector&#xff0c;没有初始值。
public static Collector> reducing(BinaryOperator op) {class OptionalBox implements Consumer {T value &#61; null;boolean present &#61; false;&#64;Overridepublic void accept(T t) {if (present) {value &#61; op.apply(value, t);}else {value &#61; t;present &#61; true;}}}return new CollectorImpl>(OptionalBox::new, OptionalBox::accept,(a, b) -> { if (b.present) a.accept(b.value); return a; },a -> Optional.ofNullable(a.value), CH_NOID);
}
// 返回一个可以直接产生结果的Collector&#xff0c;指定初始值。
public static Collector reducing(T identity, BinaryOperator op) {return new CollectorImpl<>(boxSupplier(identity),(a, t) -> { a[0] &#61; op.apply(a[0], t); },(a, b) -> { a[0] &#61; op.apply(a[0], b[0]); return a; },a -> a[0],CH_NOID);
}
// 返回一个可以直接产生结果的Collector&#xff0c;指定初始值&#xff0c;在返回结果之前先使用传入的方法将流进行转换。
public static Collector reducing(U identity,Function super T, ? extends U> mapper,BinaryOperator op) {return new CollectorImpl<>(boxSupplier(identity),(a, t) -> { a[0] &#61; op.apply(a[0], mapper.apply(t)); },(a, b) -> { a[0] &#61; op.apply(a[0], b[0]); return a; },a -> a[0], CH_NOID);
}
实例&#xff1a;
public static void main(String[] args) {List list &#61; Arrays.asList("123", "521", "100", "228", "838", "250", "345");System.out.println(list);// [123, 521, 100, 228, 838, 250, 345]Optional optional &#61; list.stream().limit(4).map(String::length).collect(Collectors.reducing(Integer::sum));System.out.println(optional);// Optional[12]Integer integer &#61; list.stream().limit(3).map(String::length).collect(Collectors.reducing(0, Integer::sum));System.out.println(integer);// 9Integer sum &#61; list.stream().limit(4).collect(Collectors.reducing(0, String::length, Integer::sum));System.out.println(sum);// 12
}
3.10 minBy方法和maxBy方法
生成一个用于获取最小值或者最大值的Optional结果的Collector。
方法&#xff1a;
public static Collector> minBy(Comparator super T> comparator) {return reducing(BinaryOperator.minBy(comparator));
}
public static Collector> maxBy(Comparator super T> comparator) {return reducing(BinaryOperator.maxBy(comparator));
}
实例&#xff1a;
public static void main(String[] args) {List list &#61; Arrays.asList("123", "521", "100", "228", "838", "250", "345");System.out.println(list);// [123, 521, 100, 228, 838, 250, 345]Optional max &#61; list.stream().collect(Collectors.maxBy((m, n) -> Integer.valueOf(m) - Integer.valueOf(n)));System.out.println(max);// Optional[838]Optional min &#61; list.stream().collect(Collectors.minBy((m, n) -> Integer.valueOf(m) - Integer.valueOf(n)));System.out.println(min);// Optional[100]
}
3.11 summingInt方法、summingLong方法和summingDouble方法
生成一个用于求元素和的Collector&#xff0c;首先将元素转换类型&#xff0c;然后再求和。
参数的作用就是将元素转换为指定的类型&#xff0c;最后结果与转换后类型一致。
方法&#xff1a;
public static Collector summingInt(ToIntFunction super T> mapper) {return new CollectorImpl<>(() -> new int[1],(a, t) -> { a[0] &#43;&#61; mapper.applyAsInt(t); },(a, b) -> { a[0] &#43;&#61; b[0]; return a; },a -> a[0], CH_NOID);
}
public static Collector summingLong(ToLongFunction super T> mapper) {return new CollectorImpl<>(() -> new long[1],(a, t) -> { a[0] &#43;&#61; mapper.applyAsLong(t); },(a, b) -> { a[0] &#43;&#61; b[0]; return a; },a -> a[0], CH_NOID);
}
public static Collector summingDouble(ToDoubleFunction super T> mapper) {return new CollectorImpl<>(() -> new double[3],(a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t));a[2] &#43;&#61; mapper.applyAsDouble(t); },(a, b) -> { sumWithCompensation(a, b[0]);a[2] &#43;&#61; b[2]; return sumWithCompensation(a, b[1]); },a -> computeFinalSum(a), CH_NOID);
}
实例&#xff1a;
public static void main(String[] args) {List list &#61; Arrays.asList("123", "521", "100", "228", "838", "250", "345");System.out.println(list);// [123, 521, 100, 228, 838, 250, 345]Integer intCollect &#61; list.stream().collect(Collectors.summingInt(Integer::parseInt));System.out.println(intCollect);// 2405Long longCollect &#61; list.stream().collect(Collectors.summingLong(Long::parseLong));System.out.println(longCollect);// 2405Double doubleCollect &#61; list.stream().collect(Collectors.summingDouble(Double::parseDouble));System.out.println(doubleCollect);// 2405.0
}
3.12 summarizingInt方法、summarizingLong方法和summarizingDouble方法
这三个方法适用于汇总的&#xff0c;返回值分别是IntSummaryStatistics、LongSummaryStatistics和DoubleSummaryStatistics。
在这些返回值中包含有流中元素的指定结果的数量、和、最大值、最小值、平均值。
方法&#xff1a;
public static Collector summarizingInt(ToIntFunction super T> mapper) {return new CollectorImpl(IntSummaryStatistics::new,(r, t) -> r.accept(mapper.applyAsInt(t)),(l, r) -> { l.combine(r); return l; }, CH_ID);
}
public static Collector summarizingLong(ToLongFunction super T> mapper) {return new CollectorImpl(LongSummaryStatistics::new,(r, t) -> r.accept(mapper.applyAsLong(t)),(l, r) -> { l.combine(r); return l; }, CH_ID);
}
public static Collector summarizingDouble(ToDoubleFunction super T> mapper) {return new CollectorImpl(DoubleSummaryStatistics::new,(r, t) -> r.accept(mapper.applyAsDouble(t)),(l, r) -> { l.combine(r); return l; }, CH_ID);
}
实例&#xff1a;
public static void main(String[] args) {List list &#61; Arrays.asList("123", "521", "100", "228", "838", "250", "345");System.out.println(list);// [123, 521, 100, 228, 838, 250, 345]IntSummaryStatistics intSummaryStatistics &#61; list.stream().collect(Collectors.summarizingInt(Integer::parseInt));System.out.println(intSummaryStatistics);// {count&#61;7, sum&#61;2405, min&#61;100, average&#61;343.571429, max&#61;838}LongSummaryStatistics longSummaryStatistics &#61; list.stream().collect(Collectors.summarizingLong(Long::parseLong));System.out.println(longSummaryStatistics);// {count&#61;7, sum&#61;2405, min&#61;100, average&#61;343.571429, max&#61;838}DoubleSummaryStatistics doubleSummaryStatistics &#61; list.stream().collect(Collectors.summarizingDouble(Double::parseDouble));System.out.println(doubleSummaryStatistics);// {count&#61;7, sum&#61;2405.000000, min&#61;100.000000, average&#61;343.571429, max&#61;838.000000}
}
3.13 averagingInt方法、averagingLong方法和averagingDouble方法
生成一个用于求元素平均值的Collector&#xff0c;首先将元素转换类型&#xff0c;然后再求平均值。
参数的作用就是将元素转换为指定的类型&#xff0c;求平均值涉及到除法操作&#xff0c;结果一律为Double类型。
方法&#xff1a;
public static Collector averagingInt(ToIntFunction super T> mapper) {return new CollectorImpl<>(() -> new long[2],(a, t) -> { a[0] &#43;&#61; mapper.applyAsInt(t); a[1]&#43;&#43;; },(a, b) -> { a[0] &#43;&#61; b[0]; a[1] &#43;&#61; b[1]; return a; },a -> (a[1] &#61;&#61; 0) ? 0.0d : (double) a[0] / a[1], CH_NOID);
}
public static Collector averagingLong(ToLongFunction super T> mapper) {return new CollectorImpl<>(() -> new long[2],(a, t) -> { a[0] &#43;&#61; mapper.applyAsLong(t); a[1]&#43;&#43;; },(a, b) -> { a[0] &#43;&#61; b[0]; a[1] &#43;&#61; b[1]; return a; },a -> (a[1] &#61;&#61; 0) ? 0.0d : (double) a[0] / a[1], CH_NOID);
}
public static Collector averagingDouble(ToDoubleFunction super T> mapper) {return new CollectorImpl<>(() -> new double[4],(a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t)); a[2]&#43;&#43;; a[3]&#43;&#61; mapper.applyAsDouble(t); },(a, b) -> { sumWithCompensation(a, b[0]); sumWithCompensation(a, b[1]); a[2] &#43;&#61; b[2]; a[3] &#43;&#61; b[3]; return a; },a -> (a[2] &#61;&#61; 0) ? 0.0d : (computeFinalSum(a) / a[2]), CH_NOID);
}
实例&#xff1a;
public static void main(String[] args) {List list &#61; Arrays.asList("123", "521", "100", "228", "838", "250", "345");System.out.println(list);// [123, 521, 100, 228, 838, 250, 345]double intAverage &#61; list.stream().collect(Collectors.averagingInt(Integer::parseInt));System.out.println(intAverage);// 343.57142857142856double longAverage &#61; list.stream().collect(Collectors.averagingLong(Long::parseLong));System.out.println(longAverage);// 343.57142857142856double doubleAverage &#61; list.stream().collect(Collectors.averagingDouble(Double::parseDouble));System.out.println(doubleAverage);// 343.57142857142856
}
3.14 groupingBy方法
生成一个拥有分组功能的Collector&#xff0c;有三个重载方法。
方法&#xff1a;
// 只需一个分组参数classifier&#xff0c;内部自动将结果保存到一个Map中&#xff0c;每个Map键的类型即classifier的结果类型&#xff0c;默认将组的元素保存在List中。
public static Collector>> groupingBy(Function super T, ? extends K> classifier) {return groupingBy(classifier, toList());
}
// 在上面方法的基础上增加了对流中元素的处理方式的Collector&#xff0c;默认是List。
public static Collector> groupingBy(Function super T, ? extends K> classifier,Collector super T, A, D> downstream) {return groupingBy(classifier, HashMap::new, downstream);
}
// 在第二个方法的基础上再添加了结果Map的生成方法&#xff0c;默认是HashMap。
public static > Collector groupingBy(Function super T, ? extends K> classifier,Supplier mapFactory,Collector super T, A, D> downstream) {Supplier downstreamSupplier &#61; downstream.supplier();BiConsumer downstreamAccumulator &#61; downstream.accumulator();BiConsumer
实例&#xff1a;
public static void main(String[] args) {List list &#61; Arrays.asList("123", "521", "100", "228", "838", "250", "345");System.out.println(list);// [123, 521, 100, 228, 838, 250, 345]Map> groupByFirst &#61; list.stream().collect(Collectors.groupingBy(e -> e.substring(0, 1)));System.out.println(groupByFirst);// {1&#61;[123, 100], 2&#61;[228, 250], 3&#61;[345], 5&#61;[521], 8&#61;[838]}Map> groupByLast &#61; list.stream().collect(Collectors.groupingBy(e -> e.substring(e.length() - 1), Collectors.toSet()));System.out.println(groupByLast);// {0&#61;[100, 250], 1&#61;[521], 3&#61;[123], 5&#61;[345], 8&#61;[228, 838]}Map> groupByLength &#61; list.stream().collect(Collectors.groupingBy(String::length, HashMap::new, Collectors.toSet()));System.out.println(groupByLength);// {3&#61;[100, 123, 521, 345, 228, 838, 250]}
}
3.15 partitioningBy方法
将流中的元素按照给定的校验规则的结果分为两个部分&#xff0c;放到Map中返回&#xff0c;键是Boolean类型&#xff0c;值为元素的列表List。
方法&#xff1a;
// 只需一个校验参数predicate。
public static Collector>> partitioningBy(Predicate super T> predicate) {return partitioningBy(predicate, toList());
}
// 在上面方法的基础上增加了对流中元素的处理方式的Collector&#xff0c;默认的处理方法就是Collectors.toList()。
public static Collector> partitioningBy(Predicate super T> predicate, Collector super T, A, D> downstream) {BiConsumer downstreamAccumulator &#61; downstream.accumulator();BiConsumer, T> accumulator &#61; (result, t) ->downstreamAccumulator.accept(predicate.test(t) ? result.forTrue : result.forFalse, t);BinaryOperator op &#61; downstream.combiner();BinaryOperator> merger &#61; (left, right) ->new Partition<>(op.apply(left.forTrue, right.forTrue),op.apply(left.forFalse, right.forFalse));Supplier> supplier &#61; () ->new Partition<>(downstream.supplier().get(),downstream.supplier().get());if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {return new CollectorImpl<>(supplier, accumulator, merger, CH_ID);}else {Function, Map> finisher &#61; par ->new Partition<>(downstream.finisher().apply(par.forTrue),downstream.finisher().apply(par.forFalse));return new CollectorImpl<>(supplier, accumulator, merger, finisher, CH_NOID);}
}
实例&#xff1a;
public static void main(String[] args) {List list &#61; Arrays.asList("123", "521", "100", "228", "838", "250", "345");System.out.println(list);// [123, 521, 100, 228, 838, 250, 345]Map> moreThan &#61; list.stream().collect(Collectors.partitioningBy(e -> Integer.parseInt(e) > 300));System.out.println(moreThan);// {false&#61;[123, 100, 228, 250], true&#61;[521, 838, 345]}Map> lessThan &#61; list.stream().collect(Collectors.partitioningBy(e -> Integer.parseInt(e) <300, Collectors.toSet()));System.out.println(lessThan);// {false&#61;[521, 345, 838], true&#61;[100, 123, 228, 250]}
}