package stream;
import com.xrz.entity.Car;
import com.xrz.entity.House;
import com.xrz.entity.Worker;
import org.junit.Before;
import org.junit.Test;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.util.stream.Collectors.*;
/**
* @Author XRZ
* @Date 2020/7/31 11:17
* @Version :
* @Description :
*/
public class S {
private List list;
@Before
public void before() {
list = new ArrayList<>();
list.add(new Worker("老王", "男", Boolean.FALSE, 10000, Arrays.asList(new Car("宝马"), new Car("路虎")), Arrays.asList(new House("南山区"))));
list.add(new Worker("小李", "男", Boolean.FALSE, 8000, Arrays.asList(new Car("奔驰")), null));
list.add(new Worker("小花", "女", Boolean.FALSE, 6000, null, null));
list.add(new Worker("阿静", "女", Boolean.FALSE, 5000, Arrays.asList(new Car("奔驰")), Arrays.asList(new House("福田区"))));
list.add(new Worker("小赵", "男", Boolean.TRUE, 10000, null, Arrays.asList(new House("宝安区"))));
list.add(new Worker("小美", "女", Boolean.TRUE, 13000, Arrays.asList(new Car("大众")), Arrays.asList(new House("宝安区"), new House("龙岗区"))));
}
@Test // flatMap 流的扁平化:将多个集合合并成一个集合
public void test01() {
//获取所有工人的车标
list.stream()
.map(Worker::getCarList)
.filter(Objects::nonNull)
// Stream> -> Stream
.flatMap(Collection::stream)
.map(Car::getBrand)
.collect(toList())
.forEach(brand -> {
System.out.println(brand);
});
}
@Test // allMatch、anyMatch、noneMatch 判断流中的元素是否匹配
public void test02() {
//判断全部人的薪水大于2500 true
boolean allMatch = list.stream().allMatch(v -> v.getSalary() > 2500);
//判断部分人的薪水大于10000 true
boolean anyMatch = list.stream().anyMatch(v -> v.getSalary() > 10000);
//判断全部人的薪水都不大于2500 false
boolean noneMatch = list.stream().noneMatch(v -> v.getSalary() > 2500);
}
@Test // findFirst、findAny 查找流中的元素
public void test03() {
Predicate isMan = (v) -> v.getSex().equals("男");
//获取第一个男生 老王
Optional findFifst = list.parallelStream().filter(isMan).findFirst();
//获取第一个男生 老王||小赵 在并行流中会随机返回第一个匹配上的男性
Optional findAny = list.parallelStream().filter(isMan).findAny();
}
@Test // sorted 排序
public void test04() {
//根据薪资排序 默认为ASE
list.stream()
// reversed 反序 DESC
.sorted(Comparator.comparing(Worker::getSalary)/*.reversed()*/)
.forEach(System.out::println);
// 先根据性别排序,再根据薪资排序
Comparator byName = Comparator.comparing(Worker::getSalary);
Comparator bySex = Comparator.comparing(Worker::getSex);
Comparator comparator = bySex.thenComparing(byName);
list.stream()
.sorted(comparator)
.forEach(System.out::println);
}
//===================================================[Collectors]==================================================================
@Test // Collectors.toList() 转换集合
public void test05() {
// 以下输出结果都一致
List list1 = list.stream().map(Worker::getName)
.collect(
// 初始化一个中间状态的结果容器
() -> new ArrayList(),
// 遍历流中的元素,把元素添加到中间状态的结果容器中
(z, t) -> z.add(t),
// 并行化归约过程中进行合并操作
(r, z) -> r.addAll(z)
);
List list2 = list.stream().map(Worker::getName)
.collect(
ArrayList::new,
ArrayList::add,
ArrayList::addAll
);
List list3 = list.stream().map(Worker::getName)
.collect(
LinkedList::new,
LinkedList::add,
LinkedList::addAll
);
List list4 = list.stream().map(Worker::getName).collect(toList());
List list5 = list.stream().map(Worker::getName).collect(toCollection(LinkedList::new));
}
@Test // 求值、汇总
public void test06() {
// Collectors.counting() 求数量
// Long workerCount = list.stream().count();
Long workerCount = list.stream().collect(Collectors.counting());
// Collectors.maxBy() 最大值
// Optional maxBy = list.stream().max(Comparator.comparing(Worker::getSalary));
Optional maxBy = list.stream().collect(Collectors.maxBy(Comparator.comparing(Worker::getSalary)));
// Collectors.minBy() 最小值
// Optional minBy = list.stream().min(Comparator.comparing(Worker::getSalary));
Optional minBy = list.stream().collect(Collectors.minBy(Comparator.comparing(Worker::getSalary)));
// Collectors.averagingInt() 平均值
// Double average = list.stream().mapToInt(Worker::getSalary).average().getAsDouble();
Double average = list.stream().collect(Collectors.averagingInt(Worker::getSalary));
// Collectors.summing() 求和
// Integer sum = list.stream().mapToInt(Worker::getSalary).sum();
Integer sum = list.stream().collect(Collectors.summingInt(Worker::getSalary));
// Collectors.summarizingInt() 汇总 得出以上所有结果
IntSummaryStatistics collect = list.stream().collect(Collectors.summarizingInt(Worker::getSalary));
collect.getMax();
collect.getMin();
collect.getAverage();
collect.getCount();
collect.getSum();
}
@Test // Collectors.joining 拼接
public void test07() {
// Collectors.joining("分隔符","前缀","后缀")
String join = list.stream().map(Worker::getName).collect(joining());
//归约方式
list.stream().collect(reducing("", Worker::getName, (n1, n2) -> n1 + n2));
list.stream().map(Worker::getName).collect(reducing("", Function.identity(), (n1, n2) -> n1 + n2));
//自定义收集器
String join1 = list.stream().map(Worker::getName)
.collect(
() -> new StringBuilder(),
(builder, name) -> builder.append(name),
(res, builder) -> res.append(builder)
).toString();
String join2 = list.stream().map(Worker::getName)
.collect(
StringBuilder::new,
StringBuilder::append,
StringBuilder::append
).toString();
System.out.println(join); //老王小李小花阿静小赵小美
System.out.println(join1); //老王小李小花阿静小赵小美
System.out.println(join2); //老王小李小花阿静小赵小美
}
@Test // Collectors.groupingBy() 分组
public void test08() {
// 按照性别得到工人列表
Map> map1 = list.stream().collect(groupingBy(Worker::getSex));
// 按性别分组得到工人名称列表
Map> map2 = list.stream().collect(groupingBy(Worker::getSex, mapping(Worker::getName, toList())));
// 按性别分组得到人数有多少
Map map3 = list.stream().collect(groupingBy(Worker::getSex, counting()));
// 按性别分组求各自的薪资平均值
Map map4 = list.stream().collect(groupingBy(Worker::getSex, averagingInt(Worker::getSalary)));
//二级分组
/*
根据性别分组再根据是否婚嫁分组
{
"男":{
"true": [{"name": "小王"}],
"false": [{"name": "小黄"}]
},
"女":{
"true": [{"name": "小红"}],
"false": [{"name": "小率"}]
}
}
*/
Map>> map5 = list.stream()
.collect(groupingBy(Worker::getSex, groupingBy(Worker::getMarried)));
/*
根据性别分组后再求组内薪资最高者
{
"男":{"name":"小王"},
"女":{"name":"小红"}
}
*/
Map map6 = list.stream()
.collect(groupingBy(
Worker::getSex,
//相当于collect
collectingAndThen(
//先执行collect的操作
maxBy(Comparator.comparing(Worker::getSalary)),
//再执行该参数的表达式
Optional::get
))
);
/*
根据性别分组,再将每个人旗下汽车牌子进行拼接
{
"男":{
"小李":"奔驰",
"老王":"宝马、路虎",
"小赵":""
},
"女":{
"小美":"大众",
"阿静":"奔驰",
"小花":"",
}
}
*/
Map> map7 = list.stream()
.collect(groupingBy(Worker::getSex,
groupingBy(Worker::getName,
collectingAndThen(
mapping(Worker::getCarList, toList()),
v -> v.stream()
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.map(Car::getBrand)
.collect(joining("、"))
)
)
));
}
@Test // Collectors.partitioningBy() 分区
public void test09(){
// 按婚嫁进行分区
Map> par1 = list.stream().collect(partitioningBy(Worker::getMarried));
// 按工资分水岭1w进行分区 {false=[老王, 小李, 小花, 阿静, 小赵], true=[小美]}
Map> par2 = list.stream()
.collect(partitioningBy(
worker -> worker.getSalary() > 10000,
mapping(Worker::getName, toList())
)
);
}
}