java8自定义收集器_java8 in action:第六章学习:数据流收集数据,自定义收集器找质数...

上一章学习如何使用流,这一章继续深入学习流的一些别的知识点。

连接字符串的使用joining()

String str=menu.stream()

.map(Dish::getName)

.collect(joining());

String str2=menu.stream()

.map(Dish::getName)

.collect(joining(","));

reducing 工厂方法

//第一个参数,指没有元素时的返回值

//第二个参数,将dish转换成一个的热量int

//第三个参数,BinaryOperator,求和

int totalCalories=menu.stream().collect(reducing(0,Dish::getCalories,(i,j) -> i+j));

//热量最高的

Optional maxCalories=menu.stream().collect(

reducing((d1,d2) -> d1.getCalories() >d2.getCalories() ?d1:d2));

分组使用Collectors.groupingBy

Map> dishesByType=menu.stream()

.collect(Collectors.groupingBy(Dish::getType));

System.out.println(dishesByType);

public enum CaloricLevel {

Diet,Normal,Fat

}

Map> dishesByCaloricLevel=menu.stream().collect(

Collectors.groupingBy( dish -> {

if (dish.getCalories()<=400) return CaloricLevel.Diet;

else if(dish.getCalories()<=700) return CaloricLevel.Normal;

else return CaloricLevel.Fat;

}));

多级分组:改进上面的代码。按类型和热量分组。

Map>> dishesByCaloricLevel=menu.stream().collect(

Collectors.groupingBy(Dish::getType,

Collectors.groupingBy( dish -> {

if (dish.getCalories()<=400) return CaloricLevel.Diet;

else if(dish.getCalories()<=700) return CaloricLevel.Normal;

else return CaloricLevel.Fat;

})));

记得导入类:import static java.util.stream.Collectors.;就不用写Collectors了。*

分类查询Dish的各个type的总和。

Map typesCount=menu.stream().

collect(groupingBy(Dish::getType,counting()));

查询每组中热量最高的Dish

Map mostCaloricByType=menu.stream()

.collect(groupingBy(Dish::getType,

collectingAndThen(//第二个收集器

maxBy(Comparator.comparing(Dish::getCalories)), Optional::get)));

分类汇总:

//查询每一类的总和

Map totalCaloriesByType=menu.stream().collect(groupingBy(Dish::getType,

summingInt(Dish::getCalories)));

System.out.println(totalCaloriesByType);

分区partitioningBy

Map> partitionedMenu2=menu.stream().collect(partitioningBy(dish -> dish.getCalories()>=300));

System.out.println(partitionedMenu2);

判断质数与非质数

public static boolean isPrime(int candidate){

int candidateRoot=(int) Math.sqrt((double)candidate);//优化

return IntStream.rangeClosed(2, candidateRoot)

.noneMatch(i ->candidate%i==0);

}

public static Map> partitionPrimes(int n){

return IntStream.rangeClosed(2, n).boxed().collect(partitioningBy(candidate -> isPrime(candidate)));

}

自定义收集器找100以内的质数

import java.util.ArrayList;

import java.util.Collections;

import java.util.EnumSet;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.Set;

import java.util.function.BiConsumer;

import java.util.function.BinaryOperator;

import java.util.function.Function;

import java.util.function.Predicate;

import java.util.function.Supplier;

import java.util.stream.Collector;

import java.util.stream.IntStream;

public class PrimeCollector implements Collector>, Map>> {

@Override

public Supplier>> supplier() {

return () -> new HashMap>(){{

put (true,new ArrayList());

put (false,new ArrayList());

}};

}

@Override

public BiConsumer>, Integer> accumulator() {

return (Map> acc,Integer candidate) -> {

acc.get(isPrime(acc.get(true), candidate))

.add(candidate);

};

}

@Override

public BinaryOperator>> combiner() {

return (Map> map1,

Map> map2) ->{

map1.get(true).addAll(map2.get(true));

map1.get(false).addAll(map2.get(false));

return map1;

};

}

@Override

public Function>, Map>> finisher() {

return Function.identity();

}

@Override

public Set characteristics() {

return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH));

}

public static boolean isPrime(List primes,int candidate){

int candidateRoot=(int) Math.sqrt((double)candidate);//优化

return takeWhile(primes, i -> i<= candidateRoot)

.stream().noneMatch(p -> candidate%p==0);

}

public static List takeWhile(List list,Predicate p){

int i=0;

for (A item : list) {

if (!p.test(item)) {

return list.subList(0, i);

}

i++;

}

return list;

}

}

public static Map> partitionPrimesWithCustomCollector(int n){

return IntStream.rangeClosed(2, n).boxed().collect(new PrimeCollector());

}

写一个简单地代替上面的代码

public static Map> findPrimes(int n){

return Stream.iterate(2, i -> i+1).limit(n)

.collect(

() -> new HashMap>(){{

put(true, new ArrayList());

put(false, new ArrayList());

}},

(acc,candidate ) -> {

acc.get( PrimeCollector.isPrime(acc.get(true), candidate))

.add(candidate);

},

(map1,map2 ) -> {

map1.get(true).addAll(map2.get(true));

map2.get(false).addAll(map2.get(false));

}

);

}

今天就到这里了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值