Java 8 Stream流的常见操作

Stream流的使用

在 Java 8 中, 集合接口有两个方法来生成流:

stream() − 为集合创建串行流。

parallelStream() − 为集合创建并行流。

串行流

如果是数组的话,可以使用 Arrays.stream() 或者 Stream.of() 创建流;如果是集合的话,可以直接使用 stream() 方法创建流,因为该方法已经添加到 Collection 接口中。
示例1:

//集合创建流的方法
 public static void main(String[] args) {
        String[] arr = new String[]{"aaa", "bbb", "ccc"};
        Stream<String> stream = Arrays.stream(arr);
		//方法一
        stream = Stream.of("aaa", "bbb", "ccc");
        //方法二
        List<String> list = new ArrayList<>();
        list.add("xxx");
        list.add("yyy");
        list.add("zzz");
        stream = list.stream();
    }

示例2:

//Map创建流的方法
public static void main(String[] args) {
        //map获取流
        Map<Object, Object> map = new HashMap<>();
        map.put("a","111");
        map.put("b","222");
        map.put("c","333");
        map.put("d","444");
        Stream<Object> keyStream = map.keySet().stream();
        Stream<Object> valueStream = map.values().stream();
        Stream<Map.Entry<Object, Object>> entryStream = map.entrySet().stream();
        //筛选过滤  筛选出value = "111","222"的数据
        Map<Object, Object> collect = entryStream.filter(s -> "111".equals(s.getValue()) || "222".equals(s.getValue())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        System.out.println(collect); //结果:{a=111, b=222}
    }

并行流

并行流就是将一个流的内容分成多个数据块,并用不同的线程分别处理每个不同数据块的流。
可以调用的 parallelStream() 方法。当然也可以通过 stream.parallel() 将普通流转换成并行流。并行流也能通过sequential()方法转换为顺序流,但要注意:流的并行和顺序转换不会对流本身做任何实际的变化,仅仅是打了个标记而已。并且在一条流水线上对流进行多次并行 / 顺序的转换,生效的是最后一次的方法调用。
示例:

public static void main(String[] args) {
        //1、直接获取并行流
        List<Integer> list = new ArrayList<>();
        Stream<Integer> parallelStream = list.parallelStream();
        //2、串行流转并行流
        List<Integer> list2 = new ArrayList<>();
        Stream<Integer> parallelStream2 = list2.stream().parallel();
        //3、并行流转顺序流
        Stream<Integer> sequential = parallelStream2.sequential();
    }

操作流

Stream 类提供了很多有用的操作流的方法如下:

方法作用
filter()接收lambda,从流中排除某些操作
limit()截断流,使其元素不超过给定对象
skip(n)跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit(n)互补
distinct筛选,通过流所生成元素的hashCode()和equals去除重复元素
map接受Lambda,将元素转换成其他形式或提取信息。接受一个函数作为参数,该函数会被应用到每个元素上,并
sorted()自然排序(Comparable)
sorted(Comparator com)定制排序(Comparator)
allMatch检查是否匹配所有元素
anyMatch检查是否至少匹配一个元素
noneMatch检查是否没有匹配所有元素
findFirst返回第一个元素
findAny返回当前流中的任意元素
count返回流中元素的总个数
max返回流中最大值
min返回流中最小值
reduce归约操作可以将流中元素反复结合起来,得到一个值
collect将流转换为其他形式,接收一个Collector接口实现,用于给Stream中汇总的方法

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

1)过滤

示例:

public static void main(String[] args) {
        //通过 filter() 方法可以从流中筛选出我们想要的元素
        List<String> list = new ArrayList<>();
        list.add("徐凤年");
        list.add("李淳罡");
        list.add("青鸟");
        list.add("邓太阿");
        //筛选出带有“邓”的字符串。
        Stream<String> stream = list.stream().filter(s-> s.contains("邓"));
        stream.forEach(System.out::println);
    }

2)截断

示例:

public static void main(String[] args) {
        //通过 limit() 方法可以从流中截取出我们想要的元素
        List<String> list = new ArrayList<>();
        list.add("徐凤年");
        list.add("李淳罡");
        list.add("青鸟");
        list.add("邓太阿");
        //筛选出前3条数据
        list.stream().limit(3).forEach(System.out::println); 
    }

3)跳过元素

示例:

public static void main(String[] args) {
        //通过 skip() 方法可以从流中跳过某元素筛选出我们想要的元素
        List<String> list = new ArrayList<>();
        list.add("徐凤年");
        list.add("李淳罡");
        list.add("青鸟");
        list.add("邓太阿");
        //筛选出跳过"徐凤年"的list
        list.stream().skip(1).forEach(System.out::println);
    }

4)去重

示例:

 public static void main(String[] args) {
        // 通过distinct()方法去重
        List<String> stringList = new ArrayList<String>() {{
            add("A");
            add("A");
            add("B");
            add("B");
            add("C");
        }};
        stringList = stringList.stream().distinct().collect(Collectors.toList());
        System.out.println(stringList);
        //实体类列表的去重【注意:实体类需要重写equals() 以及 hashCode() 方法,否则distinct()不生效】
        List<UserInfo> userInfoList = new ArrayList<UserInfo>() {{
            add(new UserInfo("张三","18"));
            add(new UserInfo("张三","18"));
            add(new UserInfo("李四","21"));
            add(new UserInfo("王五","44"));
            add(new UserInfo("赵六","48"));
            add(new UserInfo("赵六","88"));
        }};
        userInfoList = userInfoList.stream().distinct().collect(Collectors.toList());
        System.out.println("userInfoList:"+userInfoList);
        //根据 List<Object> 中 Object 某个属性去重【指定属性去重】
        List<UserInfo> userInfoList2 = userInfoList.stream().collect(
                collectingAndThen(
                        toCollection(() -> new TreeSet<>(Comparator.comparing(UserInfo::getUserName))), ArrayList::new)
        );
        System.out.println("userInfoList2:"+userInfoList2);
    }

5)映射

示例:

 public static void main(String[] args) {
        //map()方法指定映射
        List<String> list = new ArrayList<>();
        list.add("徐凤年");
        list.add("李淳罡");
        list.add("青鸟");
        list.add("邓太阿");
        Stream<Integer> stream = list.stream().map(String::length);
        stream.forEach(System.out::println); //结果 3 3 2 3
    }

6)排序

示例:

 public static void main(String[] args) {
        //sorted()方法 实体类列表的排序
        List<UserInfo> userInfoList = new ArrayList<UserInfo>() {{
            add(new UserInfo("张三", "18"));
            add(new UserInfo("李四", "21"));
            add(new UserInfo("王五", "66"));
            add(new UserInfo("赵六", "16"));
            add(new UserInfo("赵六", "88"));
        }};
        //升序排序
        userInfoList = userInfoList.stream().sorted(Comparator.comparing(UserInfo::getAge)).collect(Collectors.toList());
        //降序排序  reversed()
        userInfoList = userInfoList.stream().sorted(Comparator.comparing(UserInfo::getAge).reversed()).collect(Collectors.toList());
    }

7)匹配

示例:

 public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("徐凤年");
        list.add("李淳罡");
        list.add("青鸟");
        list.add("邓太阿");
		//anyMatch:判断的条件里,任意一个元素成功,返回true
        boolean  anyMatchFlag = list.stream().anyMatch(s-> s.contains("徐"));
        //allMatch:判断条件里的元素,所有的都是,返回true
        boolean  allMatchFlag = list.stream().allMatch(s-> s.length() > 1);
        //noneMatch:与allMatch相反,判断条件里的元素,所有的都不是,返回true
        boolean  noneMatchFlag = list.stream().noneMatch(s -> s.endsWith("李"));
        System.out.println(anyMatchFlag);
        System.out.println(allMatchFlag);
        System.out.println(noneMatchFlag);
    }

8)返回第一个元素

示例:

public static void main(String[] args) {
        //findFirst()方法 返回列表中的第一个元素
        List<String> list = Arrays.asList("C", "C++", "JAVA", "Python","JON","COM");
        Optional<String> first = list.parallelStream().filter(s -> s.startsWith("C")).findFirst();
        //findAny()方法,返回的元素是不确定的
        Optional<String> findAny = list.parallelStream().filter(s -> s.startsWith("C")).findAny();
        System.out.println("first:"+first);
        System.out.println("findAny:"+findAny);
    }

9)返回流中的任意元素

示例:

public static void main(String[] args) {
        //findAny()方法 返回任意一条数据
        List<UserInfo> userInfoList = new ArrayList<UserInfo>() {{
            add(new UserInfo("张三","18"));
            add(new UserInfo("李四","21"));
            add(new UserInfo("王五","44"));
            add(new UserInfo("赵六","48"));
        }};
        //筛选出"王五"的数据,返回实体,orElse (null)表示如果一个都没找到返回null【orElse ()中可以塞默认值。】
        UserInfo userInfo = userInfoList.stream().filter(s->"王五".equals(s.getUserName())).findAny().orElse(null);
        System.out.println(userInfo);
    }

10)聚合函数

示例:

public static void main(String[] args) {
        //count()方法 统计元素总数
        List<String> list = Arrays.asList("AAA", "BBB", "CCC", "DDD");
        long count = list.stream().count();
        System.out.println("count:" + count); //结果 count:4
        //max()最大值
        List<Integer> maxList = Arrays.asList(10, 20, 30, 40);
        Optional<Integer> maxOptional = maxList.stream().max(Comparator.comparing(Function.identity()));
        System.out.println("max:"+maxOptional.get()); //结果 max:40
        //min()最小值
        List<Integer> minList = Arrays.asList(10, 20, 30, 40);
        Optional<Integer> maxOptional2 = minList.stream().min(Comparator.comparing(Function.identity()));
        System.out.println("min:"+maxOptional2.get());//结果 min:10
    }

11)归约操作

``
示例:

public static void main(String[] args) {
        //reduce()方法 归约操作
        int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        // 方法一
        int sum = Arrays.stream(numbers).reduce(0, (a, b) -> a + b);// 55
        //方法二
        int sum2 = Arrays.stream(numbers).reduce(0, Integer::sum);// 55
        //数学运算
        int sum3 = Arrays.stream(numbers).reduce(0, (a, b) -> a - b);// -55
        int sum4 = Arrays.stream(numbers).reduce(0, (a, b) -> a * b);// 0
        int sum5 = Arrays.stream(numbers).reduce(0, (a, b) -> a / b); // 0
        //最大和最小
        int max = Arrays.stream(numbers).reduce(0, (a, b) -> a > b ? a : b);  // 10
        int max1 = Arrays.stream(numbers).reduce(0, Integer::max);            // 10

        int min = Arrays.stream(numbers).reduce(0, (a, b) -> a < b ? a : b);  // 0
        int min1 = Arrays.stream(numbers).reduce(0, Integer::min);            // 0
    }

11)规约操作

将流转换为其他形式,接收一个Collector接口实现,用于给Stream中汇总的方法
示例:

public static void main(String[] args) {
        //collect()方法 将流转换为其他形式,接收一个Collector接口实现,用于给Stream中汇总的方法
        String[] strings = {"AAA", "BBB", "CCC", "DDD"};
        //Collectors.toList() 收集元素到List集合
        List<String> collectList = Arrays.stream(strings).collect(Collectors.toList());
        //Collectors.toSet() 收集元素到set集合
        Set<String> collectSet = Arrays.stream(strings).collect(Collectors.toSet());
        //Collectors.toMap(String::toString,o->o) 收集元素到map集合
        Map<String, Object> collectMap =Arrays.stream(strings).collect(Collectors.toMap(String::toString,o->o));
        //Collectors.toCollection()  收集元素到指定集合
        ArrayList<String> arrayList = Arrays.stream(strings).collect(Collectors.toCollection(ArrayList::new));
    }

注意:记录stream流的一些常用的操作方法(●'◡'●)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值