前言:
内容:
stream流是对集合迭代器的增强,使得对集合可以进行高效的聚合操作(过滤,排序、统计分组)或者大批量数据操作,stream流中用到了lambda表达式进行高效率代码书写。lambda可以用来代替匿名函数,使得代码更为简洁。
stream流可分为stream串行流(默认)和parallelStream并行流。一般来说,并行流是不安全的,需要加同步锁;并行流一般适用于CPU使用较多的环境下的通信,因此一些I/O操作频繁的情况不适用并行流。
stream流应用大体流程
1) 把集合转换成流stream
2) 在管道里对流进行中间操作
3) 得到最后的结果,并将流转成集合
lambda表达式的使用条件有
1) 接口中只有一个未被实现
2) 有默认实现的方法除外(default)
3) Object类对应的方法除外
综上,lambda是基于函数式接口编程。
1、与lambda相识
lambda表达式(参数)->{表达式};其中参数可以带数据类型,表达式只有一条可以舍弃大括号,同理参数若有多个便不能舍弃括号。为了方便理解下面是一个打卡的简单例子
/**
* @Auther:刘兰斌
* @Date: 2021/05/30/10:40
* @Explain:
*/
public class test116 {
//打卡
interface Sign{
void sign(String people);
}
//员工打卡
public void signway(String people,Sign si){
si.sign(people);
}
public static void main(String[] args) {
test116 tes6 = new test116();
String people ="小刚";
//法一:用lambda表达式
tes6.signway(people,p -> System.out.println(p));
//法二:用匿名内部类
// Sign s = new Sign() {
// @Override
// public void sign(String people) {
// System.out.println(people);
// }
// };
// tes6.signway(people,s);
}
}
再来一个案例,下面
在这个吃苹果的案例中,lambda表达式部分相当于使用方法的引用去实现,将表达式中的逻辑方法传入到eat方法中,随后对其进行相同逻辑操作。
public class LambdaTest {
@Test
public void test() {
eat((a,b)-> a+b);
}
public static void eat(myinterface mface) {
System.out.println(mface.eatApple("小飞", 1));
}
@FunctionalInterface
interface myinterface {
String eatApple(String name, int number);
}
}
2、初识stream
例a
public static void main(String[] args) {
List<String> names = Arrays.asList("Tommi", "Davy", "Philipp", "Henry", "Roy", "Jack", "Jerry");
List<String> res = names.stream()
.filter(e -> e.startsWith("J"))
.map(String::toLowerCase)
.sorted()
.collect(Collectors.toList());
System.out.println(res);
}
结果:[jack, jerry]
解析:上面例子中集合转成流后,filter()中存放着过滤规则,可以用lambda表达式或者谓词逻辑;map()存放着对每个元素的数据转换规则,包括自定义的函数或者系统自带的函数;sorted()存放着排序规则,默认升序排列,最后将流再转成集合。若数据的存储方式为数组,那么转换方式为:int[] a= {2,4,5,6}; Stream.of(a)…
public static void main(String[] args) {
String[] str = {
"Tommi", "Davy", "Philipp", "Henry", "Roy", "Jack", "Jerry"};
Stream.of(str)
.mapToInt(s -> s.length())//等价于.mapToInt(String::length)
.forEach(System.out::println);
}
}
同样的,集合类中的set、map都可以转换。
如果是文本文件则用Files.lines获取:如下
public static void main(String[] args) {
//文本转成流操作
try {
Stream<String> stream6 = Files.lines(Paths.get("src/main/resources/test116.txt"));
List<String> res = stream6.filter(s -> s.equals("Haha"))
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(res);
} catch (IOException e) {
e.printStackTrace();
}
}
例b
在filter()中使用谓词逻辑,可以增加程序的复用性。当然可以直接在filter中写lambda表达式,如下面例子中的filter可以写成
filter(s->s.getAge>60 && s.getGender().euquals(“F”))
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* @Auther:刘兰斌
* @Date: 2021/05/30/12:01
* @Explain:为了方便描述,将对象与测试方法写在一起
* 需求:找出年龄超过60的女性职工
*/
public class FilterTest {
public static void main(String[] args) {
Staff staff01 = new Staff(1,23,"F","Rick","Beethoven");
Staff staff02 = new Staff(2,13,"M","Rock","ven");
Staff staff03 = new Staff(3,73,"M","Re","oven");
Staff staff04 = new Staff(4,53,"F","james","Bee");
Staff staff05 = new Staff(5,63,"M","Raty","hove");
Staff staff06 = new Staff(6,33,"M","dtt","love");
Staff staff07 = new Staff(7,83,"F","yu","ko");
Staff staff08 = new Staff(8,103,"M","tu","so");
Staff staff09 = new Staff(9