JDK8-2-流(3)- 流操作(2)
关联上篇:
JDK8-2-流(2)- 流操作
连接字符串 java.util.stream.Collectors.joining
import static java.util.stream.Collectors.joining;
public class JoinTest {
public static final List<Dish> menu = Arrays.asList(
new Dish("pork", false, 800, Dish.Type.MEAT),
new Dish("beef", false, 700, Dish.Type.MEAT),
new Dish("chicken", false, 400, Dish.Type.MEAT));
public static void joinTest() {
String shortMenu = menu.stream()
.map(Dish::getName)
.collect(joining(",", "[", "]"));
System.out.println(shortMenu);
}
public static void main(String[] args) {
joinTest();
}
}
结果:
[pork,beef,chicken]
分组
Map<String, List<Integer>> map = Arrays.asList(1, 2, 3, 4, 5)
.stream()
.collect(Collectors.groupingBy(i -> i % 2 == 0 ? "偶数" : "奇数"));
System.out.println(map);
结果:
{偶数=[2, 4], 奇数=[1, 3, 5]}
多级分组
public static void groupByTest2() {
final List<Dish> menu = Arrays.asList(
new Dish("pork", false, 800, Dish.Type.MEAT),
new Dish("pork", false, 800, Dish.Type.MEAT),
new Dish("beef", false, 700, Dish.Type.MEAT),
new Dish("chicken", false, 400, Dish.Type.MEAT),
new Dish("french fries", true, 530, Dish.Type.OTHER),
new Dish("rice", true, 350, Dish.Type.OTHER),
//季节水果
new Dish("season fruit", true, 120, Dish.Type.OTHER),
new Dish("pizza", true, 550, Dish.Type.OTHER),
//虾
new Dish("prawns", false, 300, Dish.Type.FISH),
//鲑鱼,三文鱼,
new Dish("salmon", false, 450, Dish.Type.FISH));
Map<Dish.Type, Map<String, List<Dish>>> map = menu.stream()
.collect(Collectors.groupingBy(dish -> dish.getType(), Collectors.groupingBy(dish ->
dish.getCalories() < 400 ? "低卡路里" : "高卡路里")));
System.out.println(map);
}
{FISH={低卡路里=[Dish{name='prawns', vegetarian=false, calories=300, type=FISH}], 高卡路里=[Dish{name='salmon', vegetarian=false, calories=450, type=FISH}]}, OTHER={低卡路里=[Dish{name='rice', vegetarian=true, calories=350, type=OTHER}, Dish{name='season fruit', vegetarian=true, calories=120, type=OTHER}], 高卡路里=[Dish{name='french fries', vegetarian=true, calories=530, type=OTHER}, Dish{name='pizza', vegetarian=true, calories=550, type=OTHER}]}, MEAT={高卡路里=[Dish{name='pork', vegetarian=false, calories=800, type=MEAT}, Dish{name='pork', vegetarian=false, calories=800, type=MEAT}, Dish{name='beef', vegetarian=false, calories=700, type=MEAT}, Dish{name='chicken', vegetarian=false, calories=400, type=MEAT}]}}
按子组收集数据
例如筛选每种类型菜肴中最高卡路里的菜肴
Map<Dish.Type, Optional<Dish>> map = menu.stream()
.collect(Collectors.groupingBy(Dish::getType,
Collectors.maxBy(Comparator.comparing(Dish::getCalories))));
System.out.println(map);
{OTHER=Optional[Dish{name='pizza', vegetarian=true, calories=550, type=OTHER}], MEAT=Optional[Dish{name='pork', vegetarian=false, calories=800, type=MEAT}], FISH=Optional[Dish{name='salmon', vegetarian=false, calories=450, type=FISH}]}
Collectors.collectingAndThen 把收集器的结果转换为另一种类型
上例中,返回的 value 为 Optional 类型,如下转换成 Dish 类型:
Map<Dish.Type, Dish> map = menu.stream()
.collect(Collectors.groupingBy(Dish::getType,
Collectors.collectingAndThen(
Collectors.maxBy(Comparator.comparing(Dish::getCalories)),
Optional::get)
));
System.out.println(map);
{FISH=Dish{name='salmon', vegetarian=false, calories=450, type=FISH}, OTHER=Dish{name='pizza', vegetarian=true, calories=550, type=OTHER}, MEAT=Dish{name='pork', vegetarian=false, calories=800, type=MEAT}}
。。。待续