JDK1.8 新特性Stream和Lambda

JDK1.8 新特性Stream和Lambda的简单实用

Stream特点
  • 无存储。stream不是一种数据结构,它只是某种数据源的一个视图,数据源可以是一个数组,Java容器或I/O
    channel等。
  • 为函数式编程而生。对stream的任何修改都不会修改背后的数据源,比如对stream执行过滤操作并不会删除被过滤的元素,而是会产生一个不包含被过滤元素的新stream。
  • 惰式执行。stream上的操作并不会立即执行,只有等到用户真正需要结果的时候才会执行。
  • 可消费性。stream只能被“消费”一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成。
获取stream
@Test
    public void getStream() {
        //数组
        String[] arr = new String[]{"aa","bb","cc"};
        Stream<String> arrStream = Arrays.stream(arr);
        //集合
        List<String> list = Arrays.asList("aa","bb","cc");
        Stream<String> colStream = list.stream();
        //值
        Stream<String> stream = Stream.of("aa","bb","cc");
    }
stream方法使用

构建实体User类——使用lombok插件自动生成各种方法

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {

    private String name;
    private int age;
}

测试要用到的数据:

List<User> list = Arrays.asList(
	     // name,age
	     new User("张三", 11),
	     new User("王五", 20),
	     new User("王五", 91),
	     new User("张三", 8),
	     new User("李四", 44),
	     new User("李四", 44),
	     new User("李四", 44)
);
forEach() 使用该方法迭代流中的每个数据
@Test
public void testForEach() {
    //java8 ago
    System.out.println("java8 ago");
    for (User user: list){
        System.out.println(user);
    }
    //java8 lambda
    System.out.println("java 8 lambda");
    list.forEach(user -> System.out.println(user));

    //java8 stream lambda
    System.out.println("java 8 stream lambda");
    list.stream().forEach(user -> System.out.println(user));
}
sorted() 使用该方法排序数据
 @Test
 public void testSort() {
     System.out.println("----------排序前-----------");
     list.forEach(user -> System.out.println(user));
     System.out.println("----------排序后-----------");
     // java 8 以前
     System.out.println("java8 ago");
     Collections.sort(list, new Comparator<User>() {

         @Override
         public int compare(User o1, User o2){
             return o1.getAge()-o2.getAge();
         }
     });
     for(User user : list) {
         System.out.println(user);
     }
     // java 8 stream方法引用
     System.out.println("java 8 stream 方法引用");
     list.stream().sorted(Comparator.comparing(User::getAge)).forEach(user -> System.out.println(user));
 }
filter():使用该方法过滤
@Test
   public void testFilter(){
       //输出年龄大于50的人
       System.out.println("过滤前");
       list.forEach(user -> System.out.println(user));
       //java 8 前
       System.out.println("java 8 前");
       for (User user: list){
           if (user.getAge() > 50){
               System.out.println(user);
           }
       }
        //java 8 stream
        System.out.println("java 8 stream");
        list.stream().filter(user -> user.getAge() >50).forEach(user -> System.out.println(user));
        System.out.println("过滤后");
    }
limit():使用该方法截断
   @Test
   public void testLimit() {
       // 从第三个开始截断,只输出前三个
       System.out.println("-----截断前-----");
       list.forEach(user -> System.out.println(user));
       System.out.println("-----截断后-----");
       //java 8 前
       System.out.println("java 8 前");
       for (int i = 0; i < 3; i++) {
           System.out.println(list.get(i));
       }

       //java 8 stream
       System.out.println("java 8 stream");
       list.stream().limit(3).forEach(user -> System.out.println(user));
   }
skip():与limit互斥,使用该方法跳过元素
 @Test
   public void testSkip() {
       // 跳过前三个元素,从第四个开始输出
       System.out.println("-----跳过前-----");
       list.forEach(user -> System.out.println(user));
       System.out.println("-----跳过后-----");
       // java 8 前
       System.out.println("java 8 前");
       for (int i = 3; i < list.size(); i++) {
           System.out.println(list.get(i));
       }
       //java 8 stream
       System.out.println("java 8 stream");
       list.stream().skip(3).forEach(user -> System.out.println(user));
   }
distinct():使用该方法去重
 /**
    * distinct():使用该方法去重
    * 注意:必须重写对应泛型的hashCode()和equals()方法
    */
   @Test
   public void testDdistinct(){
       List<User> users = new ArrayList<>(list);
       System.out.println("去重前");
       list.forEach(user -> System.out.println(user));
       System.out.println("去重后");
       //java 8 前
       System.out.println("java 8 前");
       for (int i = 0; i < users.size()-1;i++) {
           for (int j = users.size()-1;j>i;j--){
               if (users.get(j).getAge() == users.get(i).getAge() && users.get(j).getName().
                       equals(users.get(i).getName())){
                   users.remove(i);
               }
           }
       }
       for (User user : users){
           System.out.println(user);
       }
       //java 8 stream
       System.out.println("java 8 stream");
       users.stream().distinct().forEach(user -> System.out.println(user));
   }
/**
    * 去重+按照年龄小于40以后从大到小+只取前二
    */
   @Test
   public void demo() {
       list.stream().distinct().filter(user -> user.getAge() < 40).
               sorted(Comparator.comparing(User::getAge).reversed()).
               limit(2).forEach(user -> System.out.println(user));
   }
max,min,sum,avg,count
  /**
    *   max,min,sum,avg,count
    *   测试计算
    */
   @Test
   public void testNum(){
       IntSummaryStatistics num = list.stream().mapToInt(user -> user.getAge()).
               summaryStatistics();
       System.out.println("总人数:" + num.getCount());
       System.out.println("平均年龄:" + num.getAverage());
       System.out.println("最大年龄:" + num.getMax());
       System.out.println("最小年龄:" + num.getMin());
       System.out.println("年龄之和:" + num.getSum());
   }
map()

/**
* map():接收一个方法作为参数,
* 该函数会被应用到每个元素上,
* 并将其映射成一个新的元素
*/

   @Test
   public void testMap(){
       //只输出所有人的年龄
       list.stream().forEach(user -> System.out.println(user.getAge()));
       System.out.println("映射后--------->");
       List<Integer> ages = list.stream().map(user -> user.getAge()).collect(toList());
       ages.forEach(age -> System.out.println(age));
       
      //小写转大写
       List<String> word = Arrays.asList("aaa","bbb","ccc");
       System.out.println("全部大写-------->");
       List<String> collect = word.stream().map(s -> s.toUpperCase()).collect(toList());
       collect.forEach(s -> System.out.println(s));
   }

flatMap()

/**
    * flatMap():对每个元素执行mapper指定的操作,
    * 并用所有mapper返回的Stream中的元素组成一个新的Stream
    * 作为最终返回结果,通俗易懂就是将原来的stream中的
    * 所有元素都展开组成一个新的stream
    */
   @Test
   public void testFlatMap() {
       //创建一个 装有两个泛型的integer的集合
       Stream<List<Integer>> stream = Stream.of(Arrays.asList(1,2,3),Arrays.asList(4,5));
       Stream<Integer> integerStream = stream.flatMap(
       (Function<List<Integer>, Stream<Integer>>) integers -> integers.stream());
       // 为新的集合
       List<Integer> collect = integerStream.collect(toList());
       System.out.println("新stream大小" + collect.size());
       System.out.println("------合并和---------");
       collect.forEach(o -> System.out.println(o));
   }
findFirst()
 /**
    * findFirst() :
    * 使用该方法获取第一个元素
    */
   @Test
   public void testFindFirst() {
       User user = list.stream().findFirst().get();
       System.out.println(user);
   }
reduce() :多面手
   /**
    * reduce() :多面手
    * reduce 操作可以实现从一组元素中生成一个值
    * sum()、max()、min()、count()等都是reduce操作,
    * 将他们单独设为函数只是因为常用
    * 例如:找到年龄最大的
    */
   @Test
   public void reduce() {
       List<User> list = Arrays.asList(
           new User("张三", 11),
           new User("王五", 20),
           new User("王五", 91),
           new User("张三", 8),
           new User("李四", 44),
           new User("李四", 44),
           new User("李四", 44)
       );

       //第一种使用reduce
       Optional<User> reduce = list.stream().reduce((s1, s2) -> s1.getAge() > s2.getAge() ? s1 : s2);
       User user = reduce.get();
       System.out.println(user);

       //第二种使用单独的方法
       Optional<User> min = list.stream().min(Comparator.comparing(User::getAge));
       User user2 = min.get();
       System.out.println(user2);

       //通过reduce求年龄的总和
       Integer reduce2 = list.stream().reduce(0,// 该参数为初始值
               (integer, user3) -> integer + user3.getAge(),// 该参数为累加器,新元素如何累加
               ((integer, integer2) -> integer + integer2));// 多个部分如何合并
       System.out.println(reduce2);
   }
使用collect()做字符串join
   /**
     * 使用collect()做字符串join
     */
    @Test
    public void ColletJoinTest() {
        //使用Collectors.joining()拼接字符串
        Stream<String> stream = Stream.of("张三","李四","王五","赵六");
//        String s = stream.collect(Collectors.joining());//张三李四王五赵六
//        String s = stream.collect(Collectors.joining("-")); //张三-李四-王五-赵六
          String s = stream.collect(Collectors.joining("-", "(",")"));//(张三-李四-王五-赵六)

        System.out.println(s);
    }
Stream转换成List或Set
   // Stream转换成List或Set
    @Test
    public void StreamTest(){
        Stream<String> stream = Stream.of("I", "love", "you", "too","too");
        List<String> list = stream.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);// 方式1
        // List<String> list = stream.collect(Collectors.toList());// 方式2
        //Set<String> list = stream.collect(Collectors.toSet());// 方式3
        System.out.println(list);
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaotian_dev

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值