java8这几个常用的流式操作如同操作数据库一般:
1、映射:
(1)map:接收lambda,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的流。
(2)flatMap:接收一个函数作为参数,将流中的每一个值都替换成另外一个流,然后把所有流连成一个流。
例子:
@Test
public void test2() {
List<String> list1 = Arrays.asList("aaa","bbb","ccc");
System.out.println("-----------将集合中的元素都转换成大写形式------");
list1.stream()
.map(s->s.toUpperCase())
.forEach(System.out::print);
System.out.println();
System.out.println("---------将集合中的名字属性提取出来------");
list.stream().map(Employee::getName)
.forEach(System.out::println);
//用map获取时,{{a,a,a},{b,b,b}} 存的是这种形式的 流 里边嵌套流
Stream<Stream<Character>> s = list1.stream()
//这个方法是将字符串拆分成字符
.map(TestStreamAPI2::filterCharater);
s.forEach(ss->{
ss.forEach(System.out::print);
});
System.out.println();
//用flatMap获取时 {a,a,a,b,b,b} 合并成一个流
Stream<Character> s1 = list1.stream()
.flatMap(TestStreamAPI2::filterCharater);
s1.forEach(System.out::print);
}
2、筛选与切片
1)filter:筛选满足条的
2)limit:只取前几个
3)skin:跳过前几个
4)distinct:去重,通过流所生成元素的hashcode()和equals()去除重复元素。
@Test
public void test3() {
list.stream().filter(e->e.getSalary()>5000)
//.limit(5)//只显示满足条件的前五条记录
.skip(2)//跳过前两条记录
.distinct()
.forEach(System.out::println);
}
3、查找与匹配
1)allMatch--检查是否匹配所有元素
2)anyMatch--检查是否至少匹配一个元素
3)noneMatch--检查是否没有匹配所有元素
4)findFirst--返回第一个元素
5)findAny--返回当前流中的任意元素
6)count--返回流中元素的个数
7)max--返回流中最大值
8)min--返回流中最小值
@Test
public void test4_1() {
//* (1)allMatch--检查是否匹配所有元素
//* (2)anyMatch--检查是否至少匹配一个元素
//* (3)noneMatch--检查是否没有匹配所有元素
//检查所有员工的工资是否都是大于5000
boolean allMatch = list.stream().allMatch(e->e.getSalary()>5000);
System.out.println(allMatch);
//检查是否至少有一个员工的工资大于5000
boolean anyMatch = list.stream().anyMatch(e->e.getSalary()>5000);
System.out.println(anyMatch);
//意思是 noneMatch中的条件都不匹配的时候,才是true
boolean noneMatch = list.stream().noneMatch(e->e.getSalary()<3000);
System.out.println(noneMatch);
}
@Test
public void test4_2() {
//(4)findFirst--返回第一个元素
//(5)findAny--返回当前流中的任意元素
//按工资排序,查找工资最高的那条数据
Optional<Employee> op1 = list.stream()
.sorted((e1,e2)->-Double.compare(e1.getSalary(), e2.getSalary()))
.findFirst();
System.out.println(op1.get());
Optional<Employee> op2 = list.stream().findAny();
System.out.println(op2.get());
}
@Test
public void test4_3() {
//(6)count--返回流中元素的个数
//(7)max--返回流中最大值
//(8)min--返回流中最小值
//获取一共多少条数据
long count = list.stream().count();
System.out.println(count);
//获取工资最高的那条数据
Optional<Employee> max = list.stream()
.max((e1,e2)->Double.compare(e1.getSalary(),e2.getSalary()));
System.out.println(max.get());
//获取工资最低的那条数据
Optional<Employee> min = list.stream()
.min((e1,e2)->Double.compare(e1.getSalary(),e2.getSalary()));
System.out.println(min.get());
//扩展:只获取最低的工资数
Optional<Double> min2 = list.stream()
.map(Employee::getSalary)
.min((e1,e2)->Double.compare(e1,e2));
System.out.println(min2.get());
}
4、归约
1)Optional<T> reduce(BinaryOperator<T> accumulator)
2)T reduce(T identity, BinaryOperator<T> accumulator)
①第一个参数是初始值
②第二个参数是二元运算
*
* 譬如这个例子:
* list.stream().reduce(0, (x,y)->x+y);
* 0:代表初始值;
* (x,y)->x+y:代表将x,y进行相加操作;
* 实现原理:一开始把那个初始值0作为x,集合中的第一个元素1作为y进行相加,得1,又把1作为x,与集合中的第二个元素2进行相加操作,以此类推。
*
* 解释:为啥都是用的reduce,返回值却不一样呢,(一个double,一个Optional)
* 因为返回double的那个起始值为0,所以得出的值不可能为空;
* 而第二种方式求得值可能是空的,返回Optional是为了防止空指针异常。
* (一定不为空的还用原来的;有可能为空的,就封装到Optional中。)
//map-reduce模式:先用map进行提取,再用reduce进行归约操作。
@Test
public void test5() {
List<Integer> list1 = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
//对数据求和
Integer sum1 = list1.stream().reduce(0, (x,y)->x+y);
System.out.println(sum1);
//对集合中的工资求和
//方式一:
Double sum2 = list.stream()
.map(Employee::getSalary)
.reduce(0.0, (x,y)->x+y);
System.out.println(sum2);
//方式二:
Optional<Double> sum3 = list.stream()
.map(Employee::getSalary)
.reduce(Double::sum);
System.out.println(sum3.get());
}
5、收集
6、扩展:
1)Collectors.summarizingDouble(Employee::getSalary);
2)Collectors.joining(“,”); 将字符串用逗号连接起来。
@Test
public void testKZ() {
DoubleSummaryStatistics collect = list.stream()
.collect(Collectors.summarizingDouble(Employee::getSalary));
System.out.println(collect.getSum());
System.out.println(collect.getCount());
System.out.println(collect.getAverage());
System.out.println(collect.getMax());
System.out.println(collect.getMin());
}
@Testpublic void test6(){
String str = list2.stream()
.map(Employee2::getName)
.collect(Collectors.joining(",","开头---","---结尾"));
System.out.println(str);
}
结果:开头---小明,张三,王五,李四,王五,李四---结尾