stream流对象的认识与使用&stream流中方法精简总结


Java8的两个重大改变,一个是Lambda表达式,另一个就是本节要讲的Stream API表达式。

一、Stream 流对象的作用

Stream 是Java8中处理集合的关键抽象概念,它可以对集合进行非常复杂的查找、过滤、筛选等操作。

Stream(流) 类用于来简化集合类的使用,Stream 本质上是个接口,接口中定义了很多对 Stream 对象的操作;

二、Stream的操作步骤

1、创建Stream
从一个数据源,如集合、数组中获取流。
2、中间操作
一个操作的中间链,对数据源的数据进行操作。
3、终止操作
一个终止操作,执行中间操作链,并产生结果。

要注意的是,对流的操作完成后需要进行关闭操作(或者用JAVA7的try-with-resources)。(流的关闭就是在操作体外执行的操作)

三、特征

  1. 单次处理,一次处理结束后,当前stream就关闭了
  2. 支持并行操作

四、举个简单的例子

假设有一个Person类和一个Person列表,现在有两个需求:1)找到年龄大于18岁的人并输出;2)找出所有中国人的数量。

@Data
class Person {
    private String name;
    private Integer age;
    private String country;
    private char sex;

    public Person(String name, Integer age, String country, char sex) {
        this.name = name;
        this.age = age;
        this.country = country;
        this.sex = sex;
    }
}
List<Person> personList = new ArrayList<>();
personList.add(new Person("欧阳雪",18,"中国",'F'));
personList.add(new Person("Tom",24,"美国",'M'));
personList.add(new Person("Harley",22,"英国",'F'));
personList.add(new Person("向天笑",20,"中国",'M'));
personList.add(new Person("李康",22,"中国",'M'));
personList.add(new Person("小梅",20,"中国",'F'));
personList.add(new Person("何雪",21,"中国",'F'));
personList.add(new Person("李康",22,"中国",'M'));

在JDK8以前,我们可以通过遍历列表来完成。但是在有了Stream API后,可以这样来实现:

public static void main(String[] args) {

    // 1)找到年龄大于18岁的人并输出;
    personList.stream().filter((p) -> p.getAge() > 18).forEach(System.out::println);

    System.out.println("-------------------------------------------");

    // 2)找出所有中国人的数量
    long chinaPersonNum = personList.stream().filter((p) -> p.getCountry().equals("中国")).count();
    
    System.out.println("中国人有:" + chinaPersonNum + "个");
}

输出结果:

Person(name=Tom, age=24, country=美国, sex=M)
Person(name=Harley, age=22, country=英国, sex=F)
Person(name=向天笑, age=20, country=中国, sex=M)
Person(name=李康, age=22, country=中国, sex=M)
Person(name=小梅, age=20, country=中国, sex=F)
Person(name=何雪, age=21, country=中国, sex=F)
Person(name=李康, age=22, country=中国, sex=M)
-------------------------------------------
中国人有:6

在这个例子中,personList.stream()是创建流,filter()属于中间操作,forEach、count()是终止操作。

五、stream流中方法精简总结

方法名简介
allMatch检查 Stream 中的所有元素,全部都通过检测则返回 true
anyMatch检查 Stream 中的所有元素,全部都通过检测则返回 true
noneMatch当流中每个元素都不符合该断言时才返回true
count返回流中元素的总个数
max返回stream中的最大值
min返回stream中的最小值
sort对stream中的元素排序
filter过滤 Stream中的元素
map将流中的一个值转换成一个新的值
collect接收一个Collector实例,将流中元素收集成另外一个数据结构
collect(toList())通过 Stream 生成一个列表
flatMap将多个 Stream 连接成一个 Stream
reduce从一组值中生成一个新的值
of返回包含参数中单个指定元素的顺序Stream
distinct去重
findFirst返回流中第一个元素
findAny返回流中的任意元素

六、操作方法的使用详解

stream流结合lambda表达式使用起来非常方便。
可以学习一下lambda表达式的使用,有空我会在CSDN上总结

1. allMatch和anyMatch

allMatch:检查 Stream 中的所有元素,全部都通过检测则返回 true,否则 false

anyMatch:检查 Stream 中的所有元素,至少有一个通过检测则返回 true,否则 false

    //allMatch
    System.out.println("----->"+list.stream().allMatch(n->n.getClass() == Integer.class));
    //anyMatch
    System.out.println("----->"+list.stream().anyMatch(n->n>1));
2. max,min和sort

max:返回stream中的最大值

min:返回stream中的最小值

sort:对stream中的元素排序

        //遍历
        list.stream().forEach(a -> System.out.println(a));
        //max
        System.out.println("----->"+list.stream().max((a,b)->a-b).get());
        //min
        System.out.println("----->"+list.stream().min((a,b)->a-b).get());
        //sort
        list.stream().sorted((a,b)->a-b).forEach(a->System.out.println(a));

3. filter和map

filter:筛选 Stream 元素,符合条件的留下并组成一个新的 Stream 。

map:依次对 Stream 中的元素进行指定的函数操作,并将按顺序将函数操作的返回值组合到一个新的 Stream 中。

        //筛选filter
        list.stream().filter(n->n>6).forEach(n->System.out.println(n));
        //map
        list.stream().map(n->n+1).forEach(n->System.out.println(n));
4. of
用法: static Stream of(T t)
参数: 此方法接受强制参数t,该参数是Stream中的单个元素。
返回值: Stream of(T t)返回包含单个指定元素的顺序Stream。

// Java code for Stream of(T t) 
// to get a sequential Stream 
// containing a single element. 
  
import java.util.*; 
import java.util.stream.Stream; 
  
class GFG { 
  
    // Driver code 
    public static void main(String[] args) 
    { 
        // Creating an Stream having single element only 
        Stream stream = Stream.of("Geeks"); 
  
        // Displaying the Stream having single element 
        stream.forEach(System.out::println); 
    } 
}

输出:Geeks
5. distinct和collect

distinct:去重

collect:可以做collectors中的一些操作,如:连接,转list,分组等

        //collect
        Stream.of("1","2","3").collect(Collectors.toList()).forEach(n->System.out.println(n));
        //去重distinct
        Stream.of("2","2","2").distinct().forEach(n->System.out.println(n));

其中,.collect(Collectors.toList()) 方法将操作后返回的 Stream 生成一个 List。

6. collect(toList()) & filter

collect(toList()) 的作用是通过一个 Stream 对象生成 List 对象,案例:

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = list.stream().filter((value) -> value > 2).collect(toList());
result.forEach((value) -> System.out.print(value));

解析:创建了一个 List 对象并初始化,然后筛选出大于 2 的值,输出。

filter 方法的作用是过滤 Stream 中的元素,filter 方法是一个高阶函数,
接收一个函数接口作为参数,此高阶函数返回一个 boolean 值,返回 true 的元素会保留下来;

collect(toList()) 方法将 filter 操作返回的 Stream 生成一个 List。

高阶函数:接收或返回一个函数接口的函数称为高阶函数。
函数接口:只包含一个函数的接口成为函数接口。

7. map

map 函数的作用是将流中的一个值转换成一个新的值,举个例子,我们要将一个 List 转换成 List ,那么就可以使用 map 方法,案例:

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<String> result = list.stream().map(value -> String.format("String:%s", value)).collect(toList());
result.forEach(System.out::print);

解析:map 方法将 Integer 元素转换成 String 并使用 collect(toList()) 方法生成一个新的 List。

System.out::print 是 (value) -> System.out.print(value) 的简化版写法。

8. flatMap

将多个 Stream 连接成一个 Stream。案例:

List<String> list = Arrays.asList("abc", "def", "ghi");
List<Character> result = list.stream().flatMap(value -> {
    char[] chars = value.toCharArray();
    Character[] characters = new Character[chars.length];
    for(int i = 0; i < characters.length; i++){
        characters[i] = chars[i];
    }
    return Stream.of(characters);
}).collect(toList());
result.forEach(System.out::println);

解析:首先定义一个 List 对象,将这个对象中的每一个 String 都分割成一个字母并生成一个新的 List 对象。

上面代码先遍历 list ,通过 flatMap 函数将每个 String 元素都生成一个新的 Stream 并将这些 Stream 连接成一个新的 Stream。
9. reduce

从一组值中生成一个新的值

List<Integer> list = Arrays.asList(0, 1, 2, 3);
int count = list.stream().reduce(0, (acc, item) -> acc + item).intValue();
System.out.println(count);

reduce 函数的一个参数为循环的初始值,这里计算累加时初始值为 0,acc 代表已经计算的结果,item 表示循环的每个元素。
10. 收集操作

collect:接收一个Collector实例,将流中元素收集成另外一个数据结构。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值