JAva 8 in action:第六章学習:データストリーム収集データ、カスタムコレクタ質量数
6976 ワード
前の章では、ストリームの使用方法を学び、この章では、ストリームの他の知識点を深く学び続けます.
接続文字列の使用joining()
reducing工場方法
グループはCollectors.groupingByを使用
マルチレベルパケット:上記のコードを改善します.タイプと熱でグループ化します.
インポートクラスを覚えています:import static java.util.stream.Collectors.;Collectorsは書かなくてもいいです.*
分類クエリDishの各typeの合計.
各グループの中で最も熱量の高いDishを検索
分類要約:
パーティションpartitioningBy
質量数と非質量数の判断
カスタムコレクタ100以内の質量数を探す
上のコードの代わりに簡単に書く
今日はここまでです.
接続文字列の使用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
上のコードの代わりに簡単に書く
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));
}
);
}
今日はここまでです.