Stream流

本文介绍了Java中的StreamAPI,展示了如何使用Stream进行数据过滤、转换和收集操作,强调了其在函数式编程中的作用,如filter、map、forEach等方法,并通过实例解释了Stream的中间操作和终结操作,以及如何进行流的生成和合并。
摘要由CSDN通过智能技术生成

1.Stream流体验

import java.util.ArrayList;

public class StreamDemo {
    public static void main(String[] args) {
        //创建一个集合,存储多个字符串元素
        ArrayList<String> list = new ArrayList<String>();

        list.add("张三");
        list.add("张曼玉");
        list.add("王祖贤");
        list.add("张三丰");
        list.add("张敏");
        list.add("张无忌");

        //把集合中所有以"张"开头的元素存储到一个新的集合
        ArrayList<String> zhangList = new ArrayList<String>();

        for(String s : list) {
            if(s.startsWith("张")) {
                zhangList.add(s);
            }
        }

//        System.out.println(zhangList);

        //把"张"开头的集合中的长度为3的元素存储到一个新的集合
        ArrayList<String> threeList = new ArrayList<String>();

        for(String s : zhangList) {
            if(s.length() == 3) {
                threeList.add(s);
            }
        }

//        System.out.println(threeList);

        //遍历上一步得到的集合
        for(String s : threeList) {
            System.out.println(s);
        }
        System.out.println("--------");

        //Stream流来改进
//        list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));
        list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(System.out::println);
    }
}

使用Stream流的方式完成过滤操作
list.stream().filter(s->s.startsWith("张")).filter(s->s.length()==3);
直接阅读代码的字面意思即可完美展示无关逻辑方式的语义: 生成流、过滤姓张、过滤长度为3、逐一打印
Stream流把真正的函数式编程风格引入到Java中

2.Stream流的生成方法

方法名说明
list.stream()生成流:通过数据源(集合,数组等)生成流
filter()中间操作:一个流后面可以跟随零个或多个中间操作, 其目的主要是打开流,做出某种程度的数据过滤映射,然后返回一个新的流,交给下一个操作使用
forEach()终结操作:一个流只能有一个终结操作,当这个操作执行后,流就被使用“光" 了,无法再被操作。所以这必定是流的最后一个操作

 

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.stream.Stream;

public class MyStream {
    public static void main(String[] args) {

        //单列集合
        ArrayList<String> list=new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        //Stream<String> stream=list.stream();
        //stream.forEach(s->System.out.println(s));
        list.stream().forEach(s->System.out.println(s));
       /* aaa
        bbb
        ccc*/
        System.out.println("===========");

        //双列集合
        HashMap<String,Integer> hm=new HashMap<>();
        hm.put("zhangsan",23);
        hm.put("lisi",24);
        hm.put("wangwu",25);
        hm.put("zhaoliu",26);
        hm.put("qianqi",27);
        //双列集合不能直接获取Stream流,有两种方法
        //KeySet
            //先获取到所有键
            //再把这个set集合中所有的键放到Stream流中
        hm.keySet().stream().forEach(s->System.out.println(s));
        /*lisi
        qianqi
        zhaoliu
        zhangsan
        wangwu*/
        System.out.println("===========");

        //entrySet
            //先获取到生源地键值对对象
            //再把这个Set集合中所有的键值对对象放到Stream流中
        hm.entrySet().stream().forEach(s->System.out.println(s));
        /*lisi=24
        qianqi=27
        zhaoliu=26
        zhangsan=23
        wangwu=25*/
        System.out.println("===========");

        //数组
        int[] arr={1,2,3,4,5};
        Arrays.stream(arr).forEach(s->System.out.println(s));
        System.out.println("===========");

        //同种数据类型的多个数据
        Stream.of(1,2,3,4,5,6,7,8).forEach(s->System.out.println(s));

    }

}

3.Stream流的中间操作方法

中间操作的意思是,执行完此方法之后,Stream流依然可以继续执行其他操作。

方法名说明
Stream filter(Predicate predicate)用于对流中的数据进行过滤
Stream limit(long maxSize)返回此流中的元素组成的流,截取前指定参数个数的数据
Stream skip(long n)跳过指定参数个数的数据,返回由该流的剩余元素组成的流
static Stream concat(Stream a, Stream b)合并a和b两个流为一个流
Stream distinct()返回由该流的不同元素(根据Object.equals(Object) )组成的流
Stream sorted()返回由此流的元素组成的流,根据自然顺序排序
Stream sorted(Comparator comparator)返回由该流的元素组成的流,根据提供的Comparator进行排序
Stream map(Function mapper)返回由给定函数应用于此流的元素的结果组成的流
IntStream mapToInt(ToIntFunction mapper)返回一个IntStream其中包含将给定函数应用于此流的元素的结

 filter


import java.util.ArrayList;

public class Demo {
    public static void main(String[] args) {
        //创建一个集合存储多个元素
        ArrayList<String> list = new ArrayList<>();

        list.add("小黑");
        list.add("张无忌");
        list.add("大熊猫");
        list.add("张三峰");
        list.add("小白");
        list.add("张飞");

        //需要1:把list集合中以张开头的在控制台输出
        list.stream().filter(s -> s.startsWith("张")).forEach(System.out::println);
        System.out.println("--------");
//        张无忌
//        张三峰
//        张飞

        //需要2:把list集合中长度为3的元素输出
        list.stream().filter(s -> s.length() == 3).forEach(System.out::println);
        System.out.println("--------");
//        张无忌
//        大熊猫
//        张三峰

        //需求3:把以张开头,长度为3的在控制台输出
        list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(System.out::println);
//        张无忌
//        张三峰
    }
}

limit 和 skip


import java.util.ArrayList;

public class Demo {
    public static void main(String[] args) {
        //创建一个集合存储多个元素
        ArrayList<String> list = new ArrayList<>();

        list.add("小黑");
        list.add("张无忌");
        list.add("大熊猫");
        list.add("张三峰");
        list.add("小白");
        list.add("张飞");

        //需要1:取前三个数据在控制台输出
        list.stream().limit(3).forEach(System.out::println);
        System.out.println("---------");
//        小黑
//        张无忌
//        大熊猫

        //需求2:跳过3个元素,把剩下的在控制台输出
        list.stream().skip(3).forEach(System.out::println);
        System.out.println("---------");
//        张三峰
//        小白
//        张飞

        //需求3:跳过2个元素,把剩下元素的前两个输出
        list.stream().skip(2).limit(2).forEach(System.out::println);
//        大熊猫
//        张三峰
    }
}

 concat 和 distinct


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

public class Demo {
    public static void main(String[] args) {
        //创建一个集合存储多个元素
        ArrayList<String> list = new ArrayList<>();

        list.add("小黑");
        list.add("张无忌");
        list.add("大熊猫");
        list.add("张三峰");
        list.add("小白");
        list.add("张飞");

        //需要1:取前4个数据组成一个流
        Stream<String> s1 = list.stream().limit(4);

        //需求2:跳过2个数据组成一个流
        Stream<String> s2 = list.stream().skip(2);

        //需求3:合并1,2结果得到的流,并输出
//        Stream.concat(s1,s2).forEach(System.out::println);
//        小黑
//        张无忌
//        大熊猫
//        张三峰
//        大熊猫
//        张三峰
//        小白
//        张飞

        //需求4:合并1,2结果得到的流,并输出,要求结果不重复
        Stream.concat(s1, s2).distinct().forEach(System.out::println);
//        小黑
//        张无忌
//        大熊猫
//        张三峰
//        小白
//        张飞
    }
}

 sorted()和sorted(Comparator comparator)


import java.util.ArrayList;

public class Demo {
    public static void main(String[] args) {
        //创建一个集合存储多个元素
        ArrayList<String> list = new ArrayList<>();

        list.add("b123");
        list.add("a1");
        list.add("f1234");
        list.add("c12");
        list.add("e12345");
        list.add("d12345");

        //需要1:按照字母顺序在控制台输出
        list.stream().sorted().forEach(System.out::println);
//        a1
//        b123
//        c12
//        d12345
//        e12345
//        f1234

        //需求2:按照字符串长度,长度相同自然排序
        list.stream().sorted((s1, s2) -> {
            int num1 = s1.length() - s2.length();
            int num2 = num1 == 0 ? s1.compareTo(s2) : num1;
            return num2;
        }).forEach(System.out::println);
//        a1
//        c12
//        b123
//        f1234
//        d12345
//        e12345
    }
}

map 和 mapToInt


import java.util.ArrayList;

public class Demo {
    public static void main(String[] args) {
        //创建一个集合存储多个元素
        ArrayList<String> list = new ArrayList<>();

        list.add("10");
        list.add("20");
        list.add("30");
        list.add("40");
        list.add("50");

        //需要:将集合中的字符串转换为整数后在控制台输出
//        list.stream().map(s->Integer.parseInt(s)).forEach(System.out::println);
        //方法引用
//        list.stream().map(Integer::parseInt).forEach(System.out::println);
//        list.stream().mapToInt(Integer::parseInt).forEach(System.out::println);
//        10
//        20
//        30
//        40
//        50

        //InStream中方法 :int sum()返回流中元素总和
        int result = list.stream().mapToInt(Integer::parseInt).sum();
        System.out.println(result); //150
    }
}

4.Stream流的终结操作方法 

 终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作。

方法名说明
void forEach(Consumer action)对此流的每个元素执行操作,Consumer接口中的方法——void accept(T t)对给定的参数执行此操作
long count()返回此流中的元素数

import java.util.ArrayList;

public class Demo {
    public static void main(String[] args) {
        //创建一个集合存储多个元素
        ArrayList<String> list = new ArrayList<>();

        list.add("小黑");
        list.add("张三忌");
        list.add("大熊猫");
        list.add("张天峰");
        list.add("小白");
        list.add("张飞");

        //需求1:输出集合中的元素
        list.stream().forEach(System.out::println);
//        小黑
//        张无忌
//        大熊猫
//        张三峰
//        小白
//        张飞

        //需求2:统计以张开头的个数
        long count = list.stream().filter(s -> s.startsWith("张")).count();
        System.out.println(count); //3
    }
}

5.Stream流的收集操作

附加:在Stream流中无法直接修改集合,数组等数据源中的数据,修改的是流上的数据

Stream流的收集方法

方法名说明
R collect(Collector collector)但是这个收集方法的参数是一个Collector 接口

工具类Collectors提供了具体的收集方式

方法名说明
public static Collector toList()把元素收集到List集合中
public static Collector toSet()把元素收集到Set集合中
public static Collector toMap(Function keyMapper,Function valueMapper)把元素收集到Map集合中

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

public class Demo {
    public static void main(String[] args) {
        //创建list集合存储多个元素
        ArrayList<String> list = new ArrayList<>();
        list.add("小黑");
        list.add("大熊猫");
        list.add("张飞");
        list.add("小熊猫");

        //需求1:得到名字为三个字的流
        Stream<String> listStream = list.stream().filter(name -> name.length() == 3);

        //需求2:把使用Stream操作得到数据存入list集合并遍历
        List<String> names = listStream.collect(Collectors.toList());
        for (String name : names) {
            System.out.println(name);
//            大熊猫
//            小熊猫
        }

        //创建Set集合对象
        Set<Integer> set = new HashSet<>();
        set.add(10);
        set.add(20);
        set.add(30);
        set.add(40);

        //需求3:得到年龄大于25的流
        Stream<Integer> setStream = set.stream().filter(age -> age > 25);

        //需求4:把使用Stream操作得到数据存入set集合并遍历
        Set<Integer> ages = setStream.collect(Collectors.toSet());
        for (Integer age : ages) {
            System.out.println(age);
//            40
//            30
        }

        //定义个字符串数组,由姓名和年龄组成
        String[] strArray = {"小黑,10", "小白,20", "小熊猫,30", "大熊猫,40"};

        //需求5:得到字符串数组中年龄大于25的流
        Stream<String> arrayStream = Stream.of(strArray).filter(s -> Integer.parseInt(s.split(",")[1]) > 28);
        
        //需求6:把使用Stream操作得到数据存入map集合并遍历,姓名做键,年龄做值
        Map<String, Integer> map = arrayStream.collect(Collectors.toMap(s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1])));
        Set<String> keySet = map.keySet();
        for (String key : keySet) {
            Integer vlaue = map.get(key);
            System.out.println(key + "," + vlaue);
//            大熊猫,40
//            小熊猫,30
        }
    }
}

练习:

 演员类:

public class Actor {
    private String name;

    public Actor(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Actor{" +
                "name='" + name + '\'' +
                '}';
    }
}

 测试类:

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

public class StreamTest {
    public static void main(String[] args) {
        //创建集合
        ArrayList<String> manList = new ArrayList<String>();
        manList.add("张国立");
        manList.add("张晋");
        manList.add("刘烨");
        manList.add("郑伊健");
        manList.add("徐峥");
        manList.add("王宝强");


        ArrayList<String> womanList = new ArrayList<String>();
        womanList.add("郑爽");
        womanList.add("杨幂");
        womanList.add("关晓彤");
        womanList.add("张天爱");
        womanList.add("杨幂");
        womanList.add("赵丽颖");

/*
        //男演员只要名字为3个字的前两人
        Stream<String> stream1 = manList.stream().filter(s -> s.length() == 3).limit(2);

        //女演员只要姓杨的,并且不要第一个
        Stream<String> stream2 = womanList.stream().filter(s -> s.startsWith("杨")).skip(1);

        //把过滤后的男演员姓名和女演员姓名合并到一起
        Stream<String> stream = Stream.concat(stream1, stream2);

        //把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据
//        stream.map(Actor::new).forEach(System.out::println);
        stream.map(Actor::new).forEach(p -> System.out.println(p.getName()));
*/

        Stream.concat(manList.stream().filter(s -> s.length() == 3).limit(2),
                        womanList.stream().filter(s -> s.startsWith("杨")).skip(1)).map(Actor::new).
                forEach(p -> System.out.println(p.getName()));

    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值