java list stream 去除 null_Stream流的这些操作,你得知道,对你工作有很大帮助

作者:扬帆( ω )起航

原文:https://blog.csdn.net/qq_43677736

Stream流

Stream(流)是一个来自数据源的元素队列并支持聚合操作:

  • 元素是特定类型的对象,形成一个队列。Java中的Stream并不会存储元素,而 是按需计算。

  • 数据源 流的来源。可以是集合,数组等。

  • 聚合操作类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted 等。

Stream流操作的三个步骤:

  1. 创建Stream

    一个数据源(如:集合、数组),获取一个流

  2. 中间操作

    一个中间操作链,对数据源的数据进行处理

  3. 终止操作

    一个终止操作,执行中间操作链,并产生结果

创建Stream步骤:

  • 通过Collection系列集合提供的顺序流stream()或并行流parallelStream()

  • 通过Arrays中的静态方法stream()获取数据流

  • 通过Stream类中的静态方法of()

代码实例:

package com.ysh.review01_Stream;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamTest01 {
public static void main(String[] args) {
//第一种方式:通过集合中的stream()方法创建Stream
List<String> list= Arrays.asList("红太狼","灰太狼","喜羊羊");
Stream<String> stream=list.stream();
//通过集合中的parallelStream方法创建
Stream<String> stream2 = list.parallelStream();
//第二种方式:通过java.util.Arrays下的静态方法stream创建Stream
Integer[] integer=new Integer[]{1,2,4};
//这里需要注意的是Arrays中的stream方法里面的参数需要一个数组,且数组的类型是一个引用类型或者是一个包装类
Stream<Integer> stream3 = Arrays.stream(integer);
//第三种方式:通过Stream中的of方法,实际上这种方式创建Stream实际上间接的通过调用Arrays中的stream()静态方法
Stream<String> stream4=Stream.of("a","b","c");
}
}

Stream的中间操作

筛选和切片

filter:过滤器

package com.ysh.review01_Stream;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StramTest02 {
public static void main(String[] args) {
Employee employee01=new Employee("yang","hui",29);
Employee employee02=new Employee("yang","hui",49);
Employee employee03=new Employee("yang","hui",9);
Employee employee04=new Employee("yang","hui",89);
Employee employee05=new Employee("yang","hui",89);
Employee employee06=new Employee("yang","hui",89);
List<Employee> list= Arrays.asList(employee01,employee02,employee03,employee04,employee05,employee06);
//创建Stream
Stream<Employee> stream1 = list.stream();
//对stream1流进行过滤
Stream<Employee> s = stream1.filter((e) -> {
System.out.println("---------------filter------------");
//过滤掉年龄小于19
return e.getAge() >= 19;
});
s.forEach((e-> System.out.println(e)));
}
}
class Employee {
private String id;
private String name;
private int age;

public Employee() {

}

public Employee(String id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
return age == employee.age &&
id.equals(employee.id) &&
name.equals(employee.name);
}

@Override
public String toString() {
return "Employee{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}

运行结果:

2e683ce15bdbfd36bfad2bd9f3961a85.png

skip(n):指跳过Stream中存储的前n条数据(包含第n条数据),返回后n条数据,如果n大于Stream中所有元素的个数,则返回空;(Employee类如上)

package com.ysh.review01_Stream;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StramTest02 {
public static void main(String[] args) {
Employee employee01=new Employee("yang","hui",9);
Employee employee02=new Employee("yang","hui",49);
Employee employee03=new Employee("yang","hui",9);
Employee employee04=new Employee("yang","hui",89);
Employee employee05=new Employee("yang","hui",89);
Employee employee06=new Employee("yang","hui",89);
List<Employee> list= Arrays.asList(employee01,employee02,employee03,employee04,employee05,employee06);
//创建Stream
Stream<Employee> stream1 = list.stream();
//对stream1流进行过滤
Stream<Employee> s = stream1.filter((e) -> {
System.out.println("---------------filter------------");
//过滤掉年龄小于19
return e.getAge() >= 19;
}).skip(2);
//s=s.skip(5);
s.forEach((e-> System.out.println(e)));
}
}

运行截图:

761f8542e88dcb605f23628b5a21cbb6.png

distinct:筛选重复的元素,通过流生产元素的hashCode()和equals去除重复元素;

package com.ysh.review01_Stream;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

public class StramTest02 {
public static void main(String[] args) {
Employee employee01=new Employee("yang","hui",9);
Employee employee02=new Employee("yang","hui",49);
Employee employee03=new Employee("yang","hui",9);
Employee employee04=new Employee("yang","hui",89);
Employee employee05=new Employee("yang","hui",89);
Employee employee06=new Employee("yang","hui",89);
List<Employee> list= Arrays.asList(employee01,employee02,employee03,employee04,employee05,employee06);
//创建Stream
Stream<Employee> stream1 = list.stream();
//对stream1流进行过滤
Stream<Employee> s = stream1.filter((e) -> {
System.out.println("---------------filter------------");
//过滤掉年龄小于19
return e.getAge() >= 19;
}).skip(2).distinct();
//s=s.skip(5);
s.forEach((e-> System.out.println(e)));
}
}

运行截图:

8558651ee0032dcb572f9d3bf0a23ada.png

排序:

sorted(Comparable)–自然排序

package com.ysh.review01_Stream;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamTest03 {
public static void main(String[] args) {
List<String> list= Arrays.asList("c","bbb","abc","bbbb");
Stream<String> stream = list.stream();
//即通过调用String方法中CompareTo,通过一个一个的比较字符的ASCLL值,首先比较首字符的ASCLL大小,相同的话再比较下一个
stream= stream.sorted();
stream.forEach(System.out::println);
}
}

sorted(Comparator)–定制排序

package com.ysh.review01_Stream;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

public class StramTest02 {
public static void main(String[] args) {
Employee employee01=new Employee("yang","哈哈",19);
Employee employee02=new Employee("yang","hui",49);
Employee employee03=new Employee("yang","hui",79);
Employee employee04=new Employee("yang","呵呵呵",79);
Employee employee05=new Employee("yang","hui",39);
Employee employee06=new Employee("yang","hui",29);
List<Employee> list= Arrays.asList(employee01,employee02,employee03,employee04,employee05,employee06);
//创建Stream
Stream<Employee> stream1 = list.stream();
//对stream1流进行过滤
Stream<Employee> s = stream1.filter((e) -> {
System.out.println("---------------filter------------");
//过滤掉年龄小于19
return e.getAge() >= 19;
});
//s=s.skip(5);
/*此处可以使用Lambda表达式,即s.sorted((o1,o2)->{
//升序排序,如果年龄相同,则按照姓名的长度排序
if (o1.getAge()==o2.getAge()){
return o1.getName().length()-o2.getName().length();
}
//按照年龄升序排序
return o1.getAge()-o2.getAge();
})
*/
s=s.sorted(new Comparator<Employee>() {
@Override
public int compare(Employee o1, Employee o2) {
//升序排序,如果年龄相同,则按照姓名的长度排序
if (o1.getAge()==o2.getAge()){
return o1.getName().length()-o2.getName().length();
}
//按照年龄升序排序
return o1.getAge()-o2.getAge();
}
});
s.forEach((e-> System.out.println(e)));
}
}

Stream中的map和flatMap方法:

  • 流中的每一个数据,当做map方法的参数(接口),接口中抽象方法的参数,进行制定操作,最终得到一个结果,最后所有的结果返回去成为一个流

  • 流中的每一个数据当作参数,进行操作,得到的结果必须是一个流,最终会结合成一个流返回

package com.ysh.review01_Stream;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class StreamTest04 {
public static void main(String[] args) {
Stream<String> stream=Stream.of("aaa","bbbb","ccccc");
//map方法是每一个数据当作一个流,即以上{aaa}、{bbbb}、{ccccc}各是一个Stream流集合,即达到得到多个Stream流集合
//可以理解为Stream流中包含Stream流
//因为这里的testCharacter()的方法我返回的是一个Stream
//Stream> streamStream = stream.map((e) -> testCharacter(e));
Stream<Stream<Character>> streamStream = stream.map((e) -> {
List<Character> list = new ArrayList<>();
for (Character c : e.toCharArray()) {
list.add(c);
}
return list.stream();
});
streamStream.forEach((e)->{
e.forEach((e2)->{
System.out.println(e2);
});
});
Stream<String> stm=Stream.of("aaa","bbbb","ccccc");
//flatMap()方法即是把将得到的多个Stream流集合合并为一个一个Stream流集合
Stream<Character> stream1=stm.flatMap(StreamTest04::testCharacter);
//streamStream.forEach(System.out::println);
System.out.println("---------------");
stream1.forEach(System.out::println);
}
//返回一个Stream
public static Stream<Character> testCharacter(String str){
List<Character> list=new ArrayList<>();
for (Character c:str.toCharArray()){
list.add(c);
}
Stream<Character> stream=list.stream();
return stream;
}
}

终止操作

查找与匹配
  • allMatch:检查是否匹配所有元素;

  • anyMatch:检查是否至少匹配一个元素;

  • noneMatch:检查是否没有匹配所有元素;

  • findFirst:返回第一个元素;

  • findAny:返回当前流中的任意元素;

  • count:返回流中元素的总个数;

  • max:返回流中最大值;

  • min:返回流中最小值;

代码实例:

package com.ysh.review01_Stream;

import java.util.Optional;
import java.util.stream.Stream;

/**
* Stream中的终止操作
*/
public class StreamTest06 {
public static void main(String[] args) {
//获取Stream
Stream<String> stm1=Stream.of("aaaaaa","bbbbb","cccccc","dd","eee");
//allMatch()方法里面的参数是一个断言式接口,即实现必须重写test()方法
boolean b1 = stm1.allMatch((t) -> {
//检查是否匹配所有元素
return t.length() > 2;
});
Stream<String> stm2=Stream.of("aaaaaa","bbbbb","cccccc","dd","eee");
boolean b2=stm2.anyMatch((t) -> {
//检查是否至少匹配一个元素
return t.length() > 2;
});
Stream<String> stm3=Stream.of("aaaaaa","bbbbb","cccccc","dd","eee");
boolean b3=stm3.noneMatch((t) -> {
//检查是否没有匹配所有元素
return t.length() > 2;
});
Stream<String> stm4=Stream.of("aaaaaa","bbbbb","cccccc","dd","eee");
//得到流中的第一个元素
Optional<String> first = stm4.findFirst();
//输出
System.out.println(first.get());
Stream<String> stm5=Stream.of("aaaaaa","bbbbb","cccccc","dd","eee");
//返回当前流中的任意元素
Optional<String> any = stm5.findAny();
System.out.println(any.get());
Stream<String> stm6=Stream.of("aaaaaa","bbbbb","cccccc","dd","eee");
//放回流中元素的总个数
long count = stm6.count();
System.out.println(count);
Stream<String> stm7=Stream.of("aaaaaa","bbbbb","cccccc","dd","eee");
//返回流中最大值,即长度最长,长度相同则比较ASCLL值大小
Optional<String> max = stm7.max((s1, s2) -> {
if (s1.length()==s2.length()){
return s1.compareTo(s2);
}
return s1.length() - s2.length();
});
System.out.println(max.get());
Stream<String> stm8=Stream.of("aaaaaa","bbbbb","cccccc","dd","eee");
//返回流中最小值,即长度最短,长度相同则比较ASCLL值大小
Optional<String> min = stm8.min((s1, s2) -> {
if (s1.length() == s2.length()) {
return s2.compareTo(s1);
}
return s1.length() - s2.length();
});
System.out.println(min.get());
System.out.println(b3);
}
}

收集:

收集-将流转换为其他形式,接收一个Collertor接口的实现,用于给Stream中元素做 汇总的方法

  • List:把流中所有元素收集到List中,使用.collect(Collectors.toList());

  • Set:把流中所有元素收集到Set中,删除重复项,使用.collect(Collectors.toSet());

  • Map:把流中所有元素收集到Map中,当出现相同的key时会抛异常,使用 .collect(Collectors.toMap());

  • 使用collect方法求流中共有几条数据,使用.collect(Collectors.counting())

  • 使用collect方法求平均数,使用.collect(Collectors.averagingInt();

  • 使用collect方法求某个变量的总和,使用.collect(Collectors.summingDouble());

  • 使用collect方法且某个变量中值的最大值,使用.collect(Collectors.maxBy());

代码实例:

package com.ysh.review01_Stream.one;

import java.util.*;
import java.util.stream.Collectors;

public class StreamTest07 {
public static void main(String[] args) {
Student stu1=new Student("1","hhhh",18);
Student stu2=new Student("2","hhhhh",19);
Student stu3=new Student("3","oooooo",19);
Student stu4=new Student("4","aaaaa",19);
List<Student> list = Arrays.asList(stu1,stu2,stu3,stu4);
//获取所有学生的姓名流,并且存储再List集合中
List<String> collect = list.stream().map((e) -> {
return e.getName();
}).collect(Collectors.toList());
System.out.println(collect);
Set<String> set = list.stream().map((e) -> {
return e.getName();
}).collect(Collectors.toSet());
System.out.println(collect);
//将学生的姓名和年龄放入到一个集合中,当出现相同的key是会抛出一个java.lang.IllegalStateException: Duplicate key异常
Map<String, Integer> map = list.stream().collect(Collectors.toMap((e) -> e.getName(), (e2) -> e2.getAge()));
System.out.println(map);
//运用collect输出所有学生的总数
Long count2 = list.stream().collect(Collectors.counting());
System.out.println(count2);
//运用collect方法计算所有学生的平均年龄
Double collect1 = list.stream().collect(Collectors.averagingDouble((n) -> n.getAge()));
System.out.println(collect1);
//运用collect方法求所有学生的年龄之和
int agesum=list.stream().collect(Collectors.summingInt((e)->e.getAge()));
System.out.println(agesum);
//运用collect方法求所有学生中年龄最大的
Optional<Student> max2 = list.stream().collect(Collectors.maxBy((a1, a2) -> a1.getAge() - a2.getAge()));
System.out.println(max2.get());

}
}
class Student {
private String id;
private String name;
private int age;
public Student(){

}

public Student(String id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
id.equals(student.id) &&
name.equals(student.name);
}

@Override
public int hashCode() {
return Objects.hash(id, name, age);
}

@Override
public String toString() {
return "Employee{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}

最后

感谢你看到这里,文章有什么不足还请指正,觉得文章对你有帮助的话记得给我点个赞!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值