上一章学习如何使用流,这一章继续深入学习流的一些别的知识点。
连接字符串的使用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<Dish> maxCalories=menu.stream().collect(
reducing((d1,d2) -> d1.getCalories() >d2.getCalories() ?d1:d2));
分组使用Collectors.groupingBy
Map<Dish.Type, List<Dish>> dishesByType=menu.stream()
.collect(Collectors.groupingBy(Dish::getType));
System.out.println(dishesByType);
public enum CaloricLevel {
Diet,Normal,Fat
}
Map<CaloricLevel, List<Dish>> 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<Dish.Type, Map<CaloricLevel,List<Dish>>> 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<Dish.Type, Long> typesCount=menu.stream().
collect(groupingBy(Dish::getType,counting()));
查询每组中热量最高的Dish
Map<Dish.Type, Dish> mostCaloricByType=menu.stream()
.collect(groupingBy(Dish::getType,
collectingAndThen(//第二个收集器
maxBy(Comparator.comparing(Dish::getCalories)), Optional::get)));
分类汇总:
//查询每一类的总和
Map<Dish.Type, Integer> totalCaloriesByType=menu.stream().collect(groupingBy(Dish::getType,
summingInt(Dish::getCalories)));
System.out.println(totalCaloriesByType);
分区partitioningBy
Map<Boolean, List<Dish>> 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<Boolean ,List<Integer>> 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<Integer, Map<Boolean,List<Integer>>, Map<Boolean,List<Integer>>> {
@Override
public Supplier<Map<Boolean, List<Integer>>> supplier() {
return () -> new HashMap<Boolean,List<Integer>>(){{
put (true,new ArrayList<Integer>());
put (false,new ArrayList<Integer>());
}};
}
@Override
public BiConsumer<Map<Boolean, List<Integer>>, Integer> accumulator() {
return (Map<Boolean, List<Integer>> acc,Integer candidate) -> {
acc.get(isPrime(acc.get(true), candidate))
.add(candidate);
};
}
@Override
public BinaryOperator<Map<Boolean, List<Integer>>> combiner() {
return (Map<Boolean, List<Integer>> map1,
Map<Boolean,List<Integer>> map2) ->{
map1.get(true).addAll(map2.get(true));
map1.get(false).addAll(map2.get(false));
return map1;
};
}
@Override
public Function<Map<Boolean, List<Integer>>, Map<Boolean, List<Integer>>> finisher() {
return Function.identity();
}
@Override
public Set<java.util.stream.Collector.Characteristics> characteristics() {
return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH));
}
public static boolean isPrime(List<Integer> primes,int candidate){
int candidateRoot=(int) Math.sqrt((double)candidate);//优化
return takeWhile(primes, i -> i<= candidateRoot)
.stream().noneMatch(p -> candidate%p==0);
}
public static<A> List<A> takeWhile(List<A> list,Predicate<A> p){
int i=0;
for (A item : list) {
if (!p.test(item)) {
return list.subList(0, i);
}
i++;
}
return list;
}
}
public static Map<Boolean, List<Integer>> partitionPrimesWithCustomCollector(int n){
return IntStream.rangeClosed(2, n).boxed().collect(new PrimeCollector());
}
写一个简单地代替上面的代码
public static Map<Boolean, List<Integer>> findPrimes(int n){
return Stream.iterate(2, i -> i+1).limit(n)
.collect(
() -> new HashMap<Boolean,List<Integer>>(){{
put(true, new ArrayList<Integer>());
put(false, new ArrayList<Integer>());
}},
(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));
}
);
}
今天就到这里了。
网友评论