目录
一、简介
Java 8 API 添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据,类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API 将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如查找,过滤, 排序,聚合等等操作。Stream API可以极大提高Java程序员的工作效率,让代码更简洁,干净。
- Stream本身不会存储元素
- Stream不会改变数据源对象,相反会返回产生一个持有结果的新Stream
- Steam操作是延迟执行的,这意味着他们会等到需要结果的时候才执行
二、创建Stream的常用方法
2.1 使用Stream中的静态方法:of()、iterate()、generate()
@Test
public void stream(){
//1.1传入可变参数,字符串,数字等
Stream<String> stringStream = Stream.of("Alian", "boy", "cat", "papa");
//1.2传入对象
Stream<User> userStream = Stream.of(new User("BAT031", "胡一菲", "销售部", 28, 3500));
//2.1generate方法参数为Function<T, T>函数型接口的子类,比如产生正奇数
Stream<Integer> oddStream = Stream.iterate(1, (x) -> x + 2);
oddStream.limit(5).forEach(System.out::println);
//3.1generate方法参数为Supplier<T> 供给型接口,比如生成1-1000的随机数:(int) Math.round(Math.random() * (m - n) + n)
Stream<Integer> generateStream = Stream.generate(() -> (int) Math.round(Math.random() * (1000 - 1) + 1));
generateStream.limit(10).forEach(System.out::println);//打印10个随机数
}
2.2 使用Collection下的 stream() 和 parallelStream() 方法
stream是顺序流,parallelStream是并行流。
@Test
public void streamAndParallelStream(){
//初始化一个list列表
List<String> fruitList = Arrays.asList("apple","banana","orange","watermelon","pear");
//获取一个顺序流
Stream<String> stream = fruitList.stream();
System.out.println("--------获取顺序流的结果-----------");
stream.forEach(System.out::println);
//获取一个并行流
Stream<String> parallel = fruitList.parallelStream();
System.out.println("--------获取并行流的结果-----------");
parallel.forEach(System.out::println);
}
运行结果:
--------获取顺序流的结果-----------
apple
banana
orange
watermelon
pear
--------获取并行流的结果-----------
orange
watermelon
banana
apple
pear
2.3 使用Arrays 中的 stream() 方法,将数组转成流
@Test
public void arraysToStream(){
//初始化一个String数组(当然也可以去其他类型的数组)
String[] animal = new String[]{"cat","dog","pig","chicken","duck"};
Stream<String> animalStream = Arrays.stream(animal);
animalStream.forEach(System.out::println);
}
运行结果:
cat
dog
pig
chicken
duck
2.4 使用BufferedReader.lines() 方法
@Test
public void readLineStream() throws FileNotFoundException {
//通过BufferedReader获取到一个流(要自己写一个文件哦,比如我这里的"C:\\myStream.txt")
BufferedReader bufReader = new BufferedReader(new FileReader("C:\\myStream.txt"));
Stream<String> lineStream = bufReader.lines();
lineStream.forEach(System.out::println);
}
运行结果:
我在使用Java 8 Stream API进行测试(BufferedReader.lines()方式获取流)
三、中间操作符(Intermediate operations)
3.1 无状态(Stateless)
3.1.1 filter - 过滤操作
filter方法对原Stream按照指定条件过滤,在新建的Stream中,只包含满足条件的元素,将不满足条件的元素过滤掉。
@Test
public void filter() {
//初始化一个用户列表
List<User> userList = Arrays.asList(
new User("BAT001", "胡昊天", "销售部", 28, 3500),
new User("BAT002", "王大锤", "销售部", 27, 3000),
new User("BAT003", "唐二鹏", "研发部", 32, 9900),
new User("BAT004", "王一林", "研发部", 30, 9000));
//过滤出用户表中年龄大于28岁的员工
List<User> collect = userList.stream().filter(f -> f.getAge() > 28).collect(Collectors.toList());
System.out.println("年龄大于28岁的员工信息:" + collect);
//过滤出用户表中年龄大于28岁并且工资大于9000元的员工
List<User> collect2 = userList.stream().filter(f -> (f.getAge() > 28 && f.getSalary() > 9000)).collect(Collectors.toList());
System.out.println("年龄大于28岁并且工资大于9000元的员工信息:" + collect2);
}
运行结果:
年龄大于28岁的员工信息:[User(id=BAT003, name=唐二鹏, age=32, department=研发部, salary=9900.0), User(id=BAT004, name=王一林, age=30, department=研发部, salary=9000.0)]
年龄大于28岁并且工资大于9000元的员工信息:[User(id=BAT003, name=唐二鹏, age=32, department=研发部, salary=9900.0)]
3.1.2 map - 映射、转换操作
map接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。map方法将对于Stream中包含的元素使用给定的转换函数进行转换操作,新生成的Stream只包含转换生成的元素。
@Test
public void map() {
//初始化一个用户列表
List<User> userList = Arrays.asList(
new User("BAT005", "梁南生", "研发部", 27, 8000),
new User("BAT006", "包雅馨", "财务部", 25, 6000),
new User("BAT007", "罗考聪", "测试部", 35, 7400.0));
//获取列表中员工的姓名(新生成的Stream只包含转换生成的元素)
List<String> collect = userList.stream().map(User::getName).collect(Collectors.toList());
System.out.println("获取到的员工姓名:" + collect);
//mapToDouble
System.out.println("员工的工资都转成double:");
userList.stream().mapToDouble(User::getSalary).forEach(System.out::println);
//mapToInt
System.out.println("员工的年龄都转成int:");
userList.stream().mapToInt(User::getAge).forEach(System.out::println);
}
运行结果:
获取到的员工姓名:[梁南生, 包雅馨, 罗考聪]
员工的工资都转成double:
8000.0
6000.0
7400.0
员工的年龄都转成int:
27
25
35
3.1.3 flatmap - 映射、转换操作
flatmap接收一个函数作为参数,将流中的每个值都转换成另一个流,然后把所有流连接成一个流。每个部分流中的每个值成单独小流,再串成一个整体流。即对Stream中的每一个元素通过转换函数转换,不同的是,该换转函数的对象是一个Stream,也不会再创建一个新的Stream,而是将原Stream的元素取代为转换的Stream
@Test
public void flatMap() {
//flatmap接收的参数是一个Stream
System.out.println("一、把流中的短横线替换后输出的结果:");
Stream.of("A-l-i-a-n ","l-o-v-e ","C-S-D-N").flatMap(e->Stream.of(e.split("-"))).forEach(System.out::print);
System.out.println();
System.out.println("二、把流中的每个数据乘以10的结果:");
Stream.of(2,5,8,9).flatMap(n->Stream.of(n*10)).forEach(System.out::println);
}
运行结果:
一、把流中的短横线替换后输出的结果:
Alian love CSDN
二、把流中的每个数据乘以10的结果:
20
50
80
90
3.1.4 peek - 挑出操作
peek方法和map一样能得到流中的每一个元素,只不过map接收的是一个Function表达式,有返回值;而peek接收的是Consumer表达式,没有返回值。peek方法会生成一个包含原Stream的所有元素的新Stream,同时会提供一个消费函数(Consumer实例),新Stream每个元素被消费的时候都会执行给定的消费函数,并且消费函数优先执行。
@Test
public void peek() {
//初始化一个用户列表
List<User> userList = Arrays.asList(
new User("BAT008", "张伟杰", "测试部", 24, 7000),
new User("BAT009", "胡俊伟", "研发部", 24, 4500));
List<User> collect = userList.stream().peek(p -> p.setDepartment("运维部")).collect(Collectors.toList());
System.out.println("部门都改为运维部:"+collect);
}
运行结果:
部门都改为运维部后的信息:[User(id=BAT008, name=张伟杰, age=24, department=运维部, salary=7000.0), User(id=BAT009, name=胡俊伟, age=24, department=运维部, salary=4500.0)]
3.2 有状态(Stateful)
3.2.1 distinct - 去重操作
distinct方法对原Stream中重复的元素进行剔除,生成的新Stream中没有没有重复的元素。
@Test
public void distinct() {
System.out.println("按照类型去重结果:");
Stream.of(3, 6, 9, 3, 9, 5).distinct().forEach(System.out::println);
List<User> userList = Arrays.asList(
new User("BAT010", "胡健儿", "人事部", 23, 4000),
new User("BAT010", "胡健儿", "人事部", 23, 4000),
new User("BAT011", "陶建文", "运维部", 25, 8000));
System.out.println("按照对象去重结果:");
userList.stream().distinct().forEach(System.out::println);
}
运行结果:
按照类型去重结果:
3
6
9
5
按照对象去重结果:
User(id=BAT010, name=胡健儿, age=23, department=人事部, salary=4000.0)
User(id=BAT011, name=陶建文, age=25, department=运维部, salary=8000.0)
3.2.2 sorted - 自然排序
sorted方法将对原Stream进行排序,返回一个有序的新Stream。
@Test
public void sorted() {
//自然排序结果
System.out.println("数字自然排序结果:");
Stream.of(15, 28, 6, 9).sorted().forEach(System.out::println);
System.out.println("字符自然排序结果:");
Stream.of("b", "ab", "ba", "c").sorted().forEach(System.out::println);
}
运行结果:
数字自然排序结果:
6
9
15
28
字符自然排序结果:
ab
b
ba
c
3.2.3 sorted(Comparator com) - 指定排序
sorted(Comparator)方法接收一个自定义排序规则函数(Comparator)。
@Test
public void sortedWithCompare() {
List<User> userList = Arrays.asList(
new User("BAT010", "胡健儿", "人事部", 23, 4000),
new User("BAT011", "陶建文", "运维部", 25, 8000),
new User("BAT012", "张萌萌", "行政部", 20, 3500));
//按照年龄升序排序
System.out.println("按照年龄升序排序");
userList.stream().sorted(Comparator.comparingInt(User::getAge)).forEach(System.out::println);
//按照年龄倒序排序
System.out.println("按照年龄倒序排序");
userList.stream().sorted(Comparator.comparingInt(User::getAge).reversed()).forEach(System.out::println);
}
运行结果:
按照年龄升序排序
User(id=BAT012, name=张萌萌, age=20, department=行政部, salary=3500.0)
User(id=BAT010, name=胡健儿, age=23, department=人事部, salary=4000.0)
User(id=BAT011, name=陶建文, age=25, department=运维部, salary=8000.0)
按照年龄倒序排序
User(id=BAT011, name=陶建文, age=25, department=运维部, salary=8000.0)
User(id=BAT010, name=胡健儿, age=23, department=人事部, salary=4000.0)
User(id=BAT012, name=张萌萌, age=20, department=行政部, salary=3500.0)
3.2.4 limit - 限流操作
limit(n)方法限制从流中获得前n个数据。
@Test
public void limit() {
List<User> userList = Arrays.asList(
new User("BAT010", "胡健儿", "人事部", 23, 4000),
new User("BAT011", "陶建文", "运维部", 25, 8000),
new User("BAT012", "张萌萌", "行政部", 20, 3500));
//按照年龄倒序排序后取前面两条记录
System.out.println("按照年龄倒序排序后取前面两条记录:");
userList.stream().sorted(Comparator.comparingInt(User::getAge).reversed()).limit(2).forEach(System.out::println);
}
运行结果:
按照年龄倒序排序后取前面两条记录:
User(id=BAT011, name=陶建文, age=25, department=运维部, salary=8000.0)
User(id=BAT010, name=胡健儿, age=23, department=人事部, salary=4000.0)
3.2.5 skip - 跳过操作
skip(n)方法跳过n元素可以配合limit进行操作。
@Test
public void skip() {
List<User> userList = Arrays.asList(
new User("BAT010", "胡健儿", "人事部", 23, 4000),
new User("BAT011", "陶建文", "运维部", 25, 8000),
new User("BAT012", "张萌萌", "行政部", 20, 3500));
//按照年龄倒序排序后取前面两条记录
System.out.println("按照年龄倒序排序后跳过一条数据取两条记录:");
userList.stream().sorted(Comparator.comparingInt(User::getAge).reversed()).skip(1).limit(2).forEach(System.out::println);
}
运行结果:
按照年龄倒序排序后跳过一条数据取两条记录:
User(id=BAT010, name=胡健儿, age=23, department=人事部, salary=4000.0)
User(id=BAT012, name=张萌萌, age=20, department=行政部, salary=3500.0)
四、终结操作符(Terminal operations)
4.1 非短路操作
4.1.1 forEach - 遍历操作
forEach方法前面已经用了好多次,其用于遍历Stream中的所元素,顺序流下按照插入数据的顺序进行输出,并行流的时候是随机输出的。
@Test
public void forEach() {
//初始化一个数据列表
List<Integer> list = Arrays.asList(2, 3, 4, 5, 6);
System.out.println("顺序流下输出:");
list.stream().sorted().forEach(f -> System.out.println("forEach顺序流下数据:" + f));
System.out.println("并行流下输出:");
list.parallelStream().forEach(f -> System.out.println("forEach并行流下数据:" + f));
List<User> userList = Arrays.asList(
new User("BAT010", "胡健儿", "人事部", 23, 4000),
new User("BAT011", "陶建文", "运维部", 25, 8000),
new User("BAT012", "张萌萌", "行政部", 20, 3500));
//按照年龄倒序排序后取前面两条记录
System.out.println("跳过前面一条数据后输出:");
userList.stream().skip(1).forEach(System.out::println);
}
运行结果:
顺序流下输出:
forEach顺序流下数据:2
forEach顺序流下数据:3
forEach顺序流下数据:4
forEach顺序流下数据:5
forEach顺序流下数据:6
并行流下输出:
forEach并行流下数据:4
forEach并行流下数据:6
forEach并行流下数据:5
forEach并行流下数据:2
forEach并行流下数据:3
跳过前面一条数据后输出:
User(id=BAT011, name=陶建文, age=25, department=运维部, salary=8000.0)
User(id=BAT012, name=张萌萌, age=20, department=行政部, salary=3500.0)
4.1.2 forEachOrdered - 遍历操作
forEachOrdered方法与forEach类似,都是遍历Stream中的所有元素,不同的是,如果该Stream预先设定了顺序,会按照预先设定的顺序执行(Stream是无序的),默认为元素插入的顺序。顺序流下按照插入数据的顺序进行输出,并行流的时候流的遇到顺序得到保持。
@Test
public void forEachOrdered() {
List<Integer> list = Arrays.asList(2, 3, 4, 5, 6, 7);
System.out.println("forEachOrdered顺序流下输出:");
list.parallelStream().forEachOrdered(f -> System.out.println("forEachOrdered顺序流下数据:" + f));
System.out.println();
System.out.println("forEachOrdered并行流下输出(流的遇到顺序得到保持):");
list.parallelStream().forEachOrdered(f -> System.out.println("forEachOrdered并行流下数据:" + f));
}
运行结果:
forEachOrdered顺序流下输出:
forEachOrdered顺序流下数据:2
forEachOrdered顺序流下数据:3
forEachOrdered顺序流下数据:4
forEachOrdered顺序流下数据:5
forEachOrdered顺序流下数据:6
forEachOrdered顺序流下数据:7
forEachOrdered并行流下输出(流的遇到顺序得到保持):
forEachOrdered并行流下数据:2
forEachOrdered并行流下数据:3
forEachOrdered并行流下数据:4
forEachOrdered并行流下数据:5
forEachOrdered并行流下数据:6
forEachOrdered并行流下数据:7
4.1.3 toArray - 数组操作
toArray 转成数组,也可以提供自定义数组生成器
@Test
public void toArray() {
Object[] animal= Stream.of("cat", "dog", "pig", "chicken", "duck").toArray();
for(Object a:animal){
System.out.println("数组里有:"+a);
}
}
运行结果:
数组里有:cat
数组里有:dog
数组里有:pig
数组里有:chicken
数组里有:duck
4.1.4 reduce - 规约操作
reduce方法是一个规约操作,所有的元素归约成一个。比如对所有元素求和,乘积等。这里实现了一个求和和乘积的方法,并指定了初始化的值分别为0和1(乘法指定1开始,不然没有意义).
@Test
public void reduce() {
int sum = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).reduce(0, Integer::sum);
System.out.println("1到10的和等于:" + sum);
int product = Stream.of(1, 2, 3, 4, 5).reduce(1, (e1, e2) -> e1 * e2);
System.out.println("1到5的乘积等于:" + product);
}
运行结果:
1到10的和等于:55
1到5的乘积等于:120
4.1.5 collect - 收集操作
collect 操作我们也使用了很多次了,就不过多详细介绍了
@Test
public void collect() {
//初始化一个用户列表
List<User> userList = Arrays.asList(
new User("BAT004", "王一林", "研发部", 30, 9000),
new User("BAT005", "梁南生", "研发部", 27, 8000),
new User("BAT006", "包雅馨", "财务部", 25, 6000),
new User("BAT007", "罗考聪", "测试部", 35, 7400.0));
//按年龄排序后转为list
System.out.println("----------转list后的结果----------");
userList.stream().sorted(Comparator.comparingInt(User::getAge)).collect(Collectors.toList()).forEach(System.out::println);
//按工资排序后转为set
System.out.println("----------转set后的结果----------");
userList.stream().sorted(Comparator.comparingDouble(User::getSalary)).collect(Collectors.toCollection(LinkedHashSet::new)).forEach(System.out::println);
//以员工的编号做为key,员工信息作为value转换为map
System.out.println("----------以员工的编号做为key,员工信息作为value转换为map----------");
Map<String, User> collect = userList.stream().collect(Collectors.toMap(User::getId, u -> u));
collect.forEach((x, y) -> System.out.println(x + "->" + y));
//把名字用逗号分隔
System.out.println("----------名字拼接后结果----------");
String nameStr = userList.stream().map(User::getName).collect(Collectors.joining(","));
System.out.println(nameStr);
System.out.println("----------按部门分组统计----------");
//按部门进行分组统计人数
Map<String, Long> groupingBy = userList.stream().collect(Collectors.groupingBy(User::getDepartment, Collectors.counting()));
groupingBy.forEach((x, y) -> System.out.println(x + "->" + y));
//获取工资汇总信息
System.out.println("----------工资汇总信息----------");
DoubleSummaryStatistics statistics = userList.stream().collect(Collectors.summarizingDouble(User::getSalary));
System.out.println("最高工资:" + statistics.getMax());
System.out.println("最低工资:" + statistics.getMin());
System.out.println("工资总和:" + statistics.getSum());
System.out.println("平局工资:" + statistics.getAverage());
System.out.println("总记录数:" + statistics.getCount());
}
运行结果:
----------转list后的结果----------
User(id=BAT006, name=包雅馨, age=25, department=财务部, salary=6000.0)
User(id=BAT005, name=梁南生, age=27, department=研发部, salary=8000.0)
User(id=BAT004, name=王一林, age=30, department=研发部, salary=9000.0)
User(id=BAT007, name=罗考聪, age=35, department=测试部, salary=7400.0)
----------转set后的结果----------
User(id=BAT006, name=包雅馨, age=25, department=财务部, salary=6000.0)
User(id=BAT007, name=罗考聪, age=35, department=测试部, salary=7400.0)
User(id=BAT005, name=梁南生, age=27, department=研发部, salary=8000.0)
User(id=BAT004, name=王一林, age=30, department=研发部, salary=9000.0)
----------以员工的编号做为key,员工信息作为value转换为map----------
BAT004->User(id=BAT004, name=王一林, age=30, department=研发部, salary=9000.0)
BAT007->User(id=BAT007, name=罗考聪, age=35, department=测试部, salary=7400.0)
BAT005->User(id=BAT005, name=梁南生, age=27, department=研发部, salary=8000.0)
BAT006->User(id=BAT006, name=包雅馨, age=25, department=财务部, salary=6000.0)
----------名字拼接后结果----------
王一林,梁南生,包雅馨,罗考聪
----------按部门分组统计----------
测试部->1
财务部->1
研发部->2
----------工资汇总信息----------
最高工资:9000.0
最低工资:6000.0
工资总和:30400.0
平局工资:7600.0
总记录数:4
4.1.6 max - 最大值操作
max方法根据指定的Comparator,返回一个Optional,该Optional中的value值就是Stream中最大的元素。
@Test
public void max() {
//初始化一个用户列表
List<User> userList = Arrays.asList(
new User("BAT005", "梁南生", "研发部", 27, 8000),
new User("BAT006", "包雅馨", "财务部", 25, 6000),
new User("BAT007", "罗考聪", "测试部", 35, 7400.0));
//筛选出年龄最大的员工信息
Optional<User> userOptional = userList.stream().max(Comparator.comparingInt(User::getAge));
//只是演示此处不做判断了
User user = userOptional.get();
System.out.println("年龄最大的员工信息:" + user);
}
运行结果:
年龄最大的员工信息:User(id=BAT007, name=罗考聪, age=35, department=测试部, salary=7400.0)
4.1.7 min - 最小值操作
min方法根据指定的Comparator,返回一个Optional,该Optional中的value值就是Stream中最小的元素。
@Test
public void min() {
//初始化一个用户列表
List<User> userList = Arrays.asList(
new User("BAT005", "梁南生", "研发部", 27, 8000),
new User("BAT006", "包雅馨", "财务部", 25, 6000),
new User("BAT007", "罗考聪", "测试部", 35, 7400.0));
//筛选出工资最低的员工信息
Optional<User> userOptional = userList.stream().min(Comparator.comparingDouble(User::getSalary));
//只是演示此处不做判断了
User user = userOptional.get();
System.out.println("工资最低的员工信息:" + user);
}
运行结果:
工资最低的员工信息:User(id=BAT006, name=包雅馨, age=25, department=财务部, salary=6000.0)
4.1.8 count - 统计操作
count方法将返回Stream中元素的个数,一般用于流中间操作后的统计。
@Test
public void count() {
//初始化一个用户列表
List<User> userList = Arrays.asList(
new User("BAT005", "梁南生", "研发部", 27, 8000),
new User("BAT006", "包雅馨", "财务部", 25, 6000),
new User("BAT007", "罗考聪", "测试部", 35, 7400.0));
//统计年龄小于30的员工的个数
long count = userList.stream().filter(f -> f.getAge() < 30).count();
System.out.println("年龄小于30的员工的个数:" + count);
}
运行结果:
年龄小于30的员工的个数:2
4.2 短路操作(short-circuiting)
4.2.1 anyMatch - 匹配操作(任意一个匹配)
anyMatch方法按照指定的条件匹配到Stream中任意一个元素则返回true,否则返回false。
@Test
public void anyMatch() {
List<User> userList = Arrays.asList(
new User("BAT005", "梁南生", "研发部", 27, 8000),
new User("BAT006", "包三雅", "财务部", 25, 6000),
new User("BAT007", "罗考聪", "测试部", 35, 7400),
new User("BAT008", "张伟杰", "测试部", 24, 7000));
//匹配任意一个年龄大于35岁的员工
boolean b = userList.stream().anyMatch(p -> p.getAge() > 35);
System.out.println("匹配任意一个年龄大于34岁的员工:" + b);
//匹配任意一个“张”姓的员工
boolean flag = userList.stream().anyMatch(p -> p.getName().startsWith("张"));
System.out.println("匹配任意一个“张”姓的员工:" + flag);
}
运行结果:
匹配任意一个年龄大于34岁的员工:false
匹配任意一个“张”姓的员工:true
4.2.2 allMatch - 匹配操作(所有都匹配)
allMatch方法按照指定的条件匹配Stream中所有的元素才返回true,否则返回false。
@Test
public void allMatch() {
List<User> userList = Arrays.asList(
new User("BAT009", "胡俊伟", "研发部", 24, 4500),
new User("BAT010", "胡健儿", "人事部", 23, 4000),
new User("BAT011", "陶建文", "运维部", 25, 8000),
new User("BAT012", "张萌萌", "行政部", 20, 3500));
//匹配所有人年龄都大于22岁
boolean b = userList.stream().allMatch(p -> p.getAge() > 22);
System.out.println("所有人年龄都大于22岁:" + b);
//匹配所有人年龄都大于18岁
boolean flag = userList.stream().allMatch(p -> p.getAge() > 18);
System.out.println("所有人年龄都大于18岁:" + flag);
}
运行结果:
所有人年龄都大于22岁:false
所有人年龄都大于18岁:true
4.2.3 noneMatch - 匹配操作(没有一个匹配)
noneMatch方法按照指定的条件,Stream中没有一个元素匹配得上才返回true,否则返回false。
@Test
public void noneMatch() {
List<User> userList = Arrays.asList(
new User("BAT001", "胡昊天", "销售部", 28, 3500),
new User("BAT002", "王大锤", "销售部", 27, 3000),
new User("BAT003", "唐二鹏", "研发部", 32, 9900),
new User("BAT004", "王一林", "研发部", 30, 9000),
new User("BAT005", "梁南生", "研发部", 27, 8000));
//匹配没有一个“李”姓员工
boolean b = userList.stream().noneMatch(p -> p.getName().startsWith("李"));
System.out.println("没有一个李姓员工:" + b);
//匹配没有一个“胡”姓员工
boolean flag = userList.stream().noneMatch(p -> p.getName().startsWith("胡"));
System.out.println("没有一个胡姓员工:" + flag);
}
运行结果:
没有一个李姓员工:true
没有一个胡姓员工:false
4.2.4 findFirst - 查找操作(找第一个)
findFirst方法用于获取Stream中的第一个元素的Optional,如果Stream为空,则返回一个空的Optional。
@Test
public void findFirst() {
List<User> userList = Arrays.asList(
new User("BAT003", "唐二鹏", "研发部", 32, 9900),
new User("BAT004", "王一林", "研发部", 30, 9000),
new User("BAT005", "梁南生", "研发部", 27, 8000),
new User("BAT006", "包雅欣", "财务部", 25, 6000)
);
Optional<User> first = userList.stream().findFirst();
System.out.println("查找到的第一个员工信息:" + first.get());
}
运行结果:
查找到的第一个员工信息:User(id=BAT003, name=唐二鹏, age=32, department=研发部, salary=9900.0)
4.2.5 findAny - 查找操作(找任意一个)
findAny方法用于获取Stream中的某个元素的Optional,如果Stream为空,则返回一个空的Optional,顺序流中总是返回第一个元素。
@Test
public void findAny() {
List<User> userList = Arrays.asList(
new User("BAT006", "包雅欣", "财务部", 25, 6000),
new User("BAT003", "唐二鹏", "研发部", 32, 9900),
new User("BAT004", "王一林", "研发部", 30, 9000),
new User("BAT005", "梁南生", "研发部", 27, 8000)
);
Optional<User> userOptional = userList.stream().filter(p->p.getAge()<30).findAny();
userOptional.ifPresent(user -> System.out.println("查找到的任意一个员工信息:" + user));
}
运行结果:
查找到的任意一个员工信息:User(id=BAT006, name=包雅欣, age=25, department=财务部, salary=6000.0)
结语
以上就是今天要讲的内容,主要介绍了Stream里一些常见的方法使用,平常还是需要多去看下API,加强练习,才能熟练,对我们后续写代码有极大的帮助。