Java8新特性之使用流

之前我们介绍了流的概念和基本使用,同集合做了对比,基本对流有一个大概的了解了,接下来学习下如何使用流来完成工作。
一.筛选和切片
1.用谓词筛选
Streams接口支持filter方法,该操作会接受一个谓词(一个返回boolean的函数)作为参数,并返回一个包含所有谓词的元素的流。例如筛选出所有素菜,创建一张素食菜单:    
 List<Dish> vegetarianMenu = menu.Stream()
                                        .filter( Dish:isVegetarian)
                                        .collect( toList());
2.筛选各异的元素
流支持一个叫做distinct的方法,它会返回一个元素各异(根据流所生成元素的hashCode和equals方法实现)的流。例如,筛选列表中所有的偶数,并确保没有重复:
List<Integer> numbers = Arrays. asList(1,2,1,3,3,2,4);
           numbers.stream().filter(n -> n%2 == 0).distinct().forEach(System.out ::println);
3.截短流
流支持limit(n)方法,该方法会返回一个不超过给定长度的流。所需的长度作为参数传递给limit。如果流是有序的,则最多会返回前n个元素。例如,给出热量超过300卡路里的前三道菜:
     List<Dish> dishes = menu.stream()
                                      .filter(n -> n.getCalories > 300)
                                      .limit(3)
                                      .collect( toList());
4.跳过元素
流还支持skip(n)方法,返回一个扔掉了前n个元素的流。如果流中元素不足n个,则返回一个空流。limit(n)和skip(n)是互补的。例如,跳过超过300卡路里的头两道菜,返回剩下的:      
List<Dish> dishes = menu.stream()
                                      .filter(n -> n.getCalories > 300)
                                      .skip(2)
                                      .collect( toList());
二.映射
一个非常常见的数据处理套路就是从某些对象中选择信息。比如在SQL里,你可以从表中选择一列。Stream API也通过map和flatMap方法提供了类似的工具。
1.对流中没一个元素应用函数
流支持map方法,它会接受一个函数作为参数。这个函数会被应用到每个元素中,并将其映射成一个新的元素。
例如,给定一个单词列表,返回另一个列表,显示每个单词中有几个字母,需要对列表中的每个元素应用一个函数,应用的函数接受一个单词,并返回其长度。
List<String> words = Arrays.asList("Java8", "Lambdas","In" ,"Action" );
          List<Integer> wordLengths = words .stream()
                                                 .map(String::length)
                                                 .collect(toList());
练习:
给定一个数字列表,如何返回一个由每个数的平方构成的列表呢?如给定[1,2,3,4,5],应该返回[1,4,9,16,25]
List<Integer> numbers = Arrays.asList(1,2,3,4,5);
           numbers.stream().map( n -> n*n ).forEach(System.out::println);
三.查找和匹配
另一个常见的数据处理套路是看看数据集中的某些元素是否匹配一个给定的属性。Stream API通过allMatch,anyMatch,noneMatch,findFirst和findAny方法提供这样的工具。
1.检查谓词是否至少匹配一个元素
     anyMatch方法可以回答"流中是否有一个元素能匹配给定的谓词"。如,查看菜单里面是否有素食可以选择:
public static void anyMatchTest(){
           if(menu .stream().anyMatch(Dish::isVegetarian)){
              System. out.println("The menu is (somewhat) vegetarian friendly");
          }
     }
2.检查谓词是否匹配所有元素
     allMatch方法和anyMatch类似,查看流中的元素是否都能匹配给定的谓词。如,看看菜品是否都有利于健康:     
public static void allMatchTest(){
           if(menu .stream().allMatch(d -> d.getCalories() < 1000)){
              System. out.println("The menu is healthy friendly");
          }
     }
3.查找元素
     findAny方法将返回当前六中的任意元素。如找到一道素食菜肴:   
public static void findAnyTest(){
          Optional<Dish> dish = menu.stream().filter(Dish::isVegetarian).findAny();
     }
4.查找第一个元素
     findFirst用来找到第一个元素,如找到第一个平方能被3整除的整数:    
public static void findFirstTest(){
          List< Integer> someNumbers = Arrays.asList(1,2,3,4,5);
          Optional<Integer> firstSquareDivisibleByThree =
                    someNumbers.stream().map(n -> n*n ).filter(n -> n%3 == 0).findFirst();
     }
四.规约
本节中,我们可以看到如何把一个流中的元素结合起来,使用reduce操作来表达更复杂的查询,如"计算菜单中的总卡路里"或"菜单中卡路里最高的菜是哪一个"。这样的查询可以被归类为规约操作。
1.元素求和
List<Integer> numbers = Arrays. asList(1,2,3,4,5);
           int sum = numbers.stream().reduce(0, ( a, b) -> a+b );
reduce接受两个参数,一个初始值,一个BinaryOperator<T>,这里我们用的是 ( a, b) -> a+b
2.最大值和最小值
public static void maxTest(){
          List<Integer> numbers = Arrays.asList(1,2,3,4,5);
          Optional<Integer> max = numbers.stream().reduce(Integer::max);
          Optional<Integer> max2 = numbers.stream().reduce((x ,y ) -> x < y ?x :y );
          Optional<Integer> min = numbers.stream().reduce(Integer::min);
          Optional<Integer> min2 = numbers.stream().reduce((x ,y ) -> x > y ?x :y );
     }
五.构建流
本节介绍如何从值序列,数组,文件来创建流,甚至由生成函数来创建无限流。
1.由值创建流
public static void makeStreamByValue(){
          Stream< String> stream = Stream.of("Java8", "Lambdas","In" ,"Action" );
           stream.map(String::toUpperCase).forEach(System. out::println);
     }
2.由数组生成流
public static void makeStreamByArray(){
           int []numbers = {2,3,5,7,11,13};
           int sum = Arrays.stream( numbers).sum();
     }
3.由函数生成流,创建无限流
Stream API 提供了静态方法来从函数生成流,Stream.iterate和Stream.generate,这两个操作可以创建无限流,不像从固定集合创建的流那样有固定大小的流。一般来说 应该使用limit来对这种流加以限制,避免打印无穷多个值。
例如,生成一个所有正偶数的流:
public static  void makeStreamByMethod(){
           Stream.iterate (0, n -> n+2).limit(10).forEach(System.out::println);
     }
练习,生成斐波那契数列
Stream.iterate(new int[]{0}, t -> new int []{t[1], t[0]+t [1]}).map(t -> t[0]).forEach(System.out::println);




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 8引入了Stream API,它是一种新的处理集合的方式,可以用更简洁、更易读的代码处理集合数据。Stream API提供了非常方便的、高效的数据处理方式,包括筛选、排序、映射、归约等。 下面是一些Stream的常用操作: 1. filter():筛选符合条件的元素 ```java List<String> list = Arrays.asList("apple", "orange", "banana", "pear", "peach"); List<String> result = list.stream().filter(str -> str.contains("e")).collect(Collectors.toList()); ``` 2. map():将元素转换成其他形式或提取信息 ```java List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5); List<Integer> result = nums.stream().map(num -> num * num).collect(Collectors.toList()); ``` 3. sorted():对元素进行排序 ```java List<Integer> nums = Arrays.asList(5, 3, 1, 2, 4); List<Integer> result = nums.stream().sorted().collect(Collectors.toList()); ``` 4. distinct():去重 ```java List<Integer> nums = Arrays.asList(1, 2, 3, 3, 4, 4, 5); List<Integer> result = nums.stream().distinct().collect(Collectors.toList()); ``` 5. limit():截取中前n个元素 ```java List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5); List<Integer> result = nums.stream().limit(3).collect(Collectors.toList()); ``` 6. skip():跳过中前n个元素 ```java List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5); List<Integer> result = nums.stream().skip(3).collect(Collectors.toList()); ``` 7. reduce():将中元素归约为一个值 ```java List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5); int result = nums.stream().reduce(0, (a, b) -> a + b); ``` 这些操作只是Stream API中的一部分,还有很多其他操作可以使用。Stream API可以让我们更加方便地处理集合数据,提高开发效率。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值