【Java】JAVA8中stream流常用的方法(一篇全搞定)

Java 8引入了许多新的特性和改进,其中一些最重要的特性包括:

  1. Lambda表达式:Lambda表达式是一种更简洁的函数式编程方式,允许以更简洁的方式编写匿名函数。
  2. 方法引用:方法引用允许直接通过方法的名称引用已存在的方法,可以简化代码并使得代码更易读。
  3. Stream API:Stream API提供了一种流式处理集合数据的方式,可以进行过滤、映射、排序、聚合等操作,极大地简化了集合的处理。
  4. 默认方法:接口现在可以包含默认方法的实现,这样在接口的现有实现中添加新方法时可以避免破坏现有代码。
  5. Optional类:Optional类是一个容器对象,可以用来包装一个可能为null的值,可以避免显式的空指针检查。
  6. 函数式接口:函数式接口是只包含一个抽象方法的接口,可用于Lambda表达式和方法引用。
  7. 新的日期时间API:引入了java.time包,提供了更好的日期和时间处理方式,包括LocalDate、LocalTime、LocalDateTime等类。
  8. 并发增强:引入了新的并发框架,如CompletableFuture类,提供了更强大且易于使用的并发编程方式。

这些新特性使得Java代码更加简洁、可读性更强,并且提供了更好的API和工具来处理集合、日期、并发等常见任务。

        下面我就来对Stream API的使用使用简单的例子进行演示:(下面的代码包含了详细的注释,直接复制在idea中进行测试即可。)

JAVA代码:

import com.alibaba.fastjson.JSON;

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

class User {
    public User(String name, String age, int height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }

    private String name;
    private String age;
    private int height;


    public String getName() {
        return name;
    }

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

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", height=" + height +
                '}';
    }
}


public class Main {
    public static void main(String[] args) {
        // 创建三个user
        User user1 = new User("张三", "17", 180);
        User user2 = new User("李四", "18", 175);
        User user3 = new User("王五", "19", 170);
        User user4 = new User("赵六", "20", 190);
        User user5 = new User("钱七", "21", 160);
        User user6 = new User("老八", "22", 172);
        User user7 = new User("老九", "23", 169);
        /**
         * 1.添加对象
         * */
        //(1)、new一个list,一个一个添加
        List<User> userList = new ArrayList<>();
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);
        userList.add(user5);
        userList.add(user6);
        userList.add(user7);
        //(2)、Stream流:创建动态list,可以添加元素
        // stream流,创建的是动态数组,可以添加元素
        List<User> userListStream = Stream.of(user1, user2, user3, user4, user5, user6, user7).collect(Collectors.toList());

		/*(3)、如果创建一个固定长度的list,可以使用Arrays.asList()直接返回一个list
		本质是将一个数组转成list,数组的大小是固定的,所以此list不能添加元素,
		如果调用add方法增加新的元素,会报异常:java.lang.UnsupportedOperationException
		当元素是固定时,可以采用这个;*/
        // 本质是将一个数组转成list,数组的大小是固定的,所以此list不能添加元素
        // 如果调用add方法增加新的元素,会报异常:java.lang.UnsupportedOperationException
        List<String> s = Arrays.asList("1", "2", "3");
        System.out.println("userList:" + userList);
        //userList:[User{name='张三', age='17', height=180}, User{name='李四', age='18', height=175}, User{name='王五', age='19', height=170}, User{name='赵六', age='20', height=190}, User{name='钱七', age='21', height=160}, User{name='老八', age='22', height=172}, User{name='老九', age='23', height=169}]
        System.out.println("userListStream:" + userListStream);
        //userListStream:[User{name='张三', age='17', height=180}, User{name='李四', age='18', height=175}, User{name='王五', age='19', height=170}, User{name='赵六', age='20', height=190}, User{name='钱七', age='21', height=160}, User{name='老八', age='22', height=172}, User{name='老九', age='23', height=169}]
        System.out.println("s:" + s);
        //s:[1, 2, 3]

        /**
         * 2.遍历(获取集合中的某一列)
         * */
        //拿上面userList举例,我取出list中所有user的name属性放到一个新的list中:
        //(1)、遍历
        // 创建一个集合用来存储用户的名字
        List<String> userNameList = new ArrayList<>();
        for (User user : userList) {
            userNameList.add(user.getName());
        }
        //(2)、Stream流:map
        // Stream流
        List<String> userNameListStream = userList.stream().map(User::getName).collect(Collectors.toList());
        System.out.println("-----------------------------------------------");

        System.out.println("userNameList:" + userNameList);
        //userNameList:[张三, 李四, 王五, 赵六, 钱七, 老八, 老九]
        System.out.println("userNameListStream:" + userNameListStream);
        //userNameListStream:[张三, 李四, 王五, 赵六, 钱七, 老八, 老九]

        /**
         * 3.过滤filter
         * */
        //3、过滤,或者说是根据一个判断条件筛选出目标对象
        //还拿上面的userList,比如我要筛选出userList中name不为空的user
        //(1)、遍历加 if
        List<User> newUserList = new ArrayList<>();
        // if判断
        for (User user : userList) {
            if (user.getName() != null) {
                newUserList.add(user);
            }
        }

        //(2)、Stream流:filter
        // 获取userName不为空的user的List
        List<User> newUserListStream = userList.stream().filter(user -> user.getName() != null).collect(Collectors.toList());

        System.out.println("-----------------------------------------------");
        System.out.println("newUserList:" + newUserList);
        //newUserList:[User{name='张三', age='17', height=180}, User{name='李四', age='18', height=175}, User{name='王五', age='19', height=170}, User{name='赵六', age='20', height=190}, User{name='钱七', age='21', height=160}, User{name='老八', age='22', height=172}, User{name='老九', age='23', height=169}]
        System.out.println("newUserListStream:" + newUserListStream);
        //newUserListStream:[User{name='张三', age='17', height=180}, User{name='李四', age='18', height=175}, User{name='王五', age='19', height=170}, User{name='赵六', age='20', height=190}, User{name='钱七', age='21', height=160}, User{name='老八', age='22', height=172}, User{name='老九', age='23', height=169}]

        /**
         * 4.分组groupby
         * */
        //4、分组
        // 把userList中的user根据年龄分组:
        //(1)、遍历加 if
        Map<String, List<User>> map = new HashMap<>();
        // if判断
        for (User user : userList) {
            if (map.get(user.getAge()) == null) {
                map.put(user.getAge(), new ArrayList());
            }
            map.get(user.getAge()).add(user);
        }
        //(2)、Stream流:groupingBy
        Map<String, List<User>> mapStream = userList.stream().collect(Collectors.groupingBy(User::getAge, Collectors.toList()));

        System.out.println("-----------------------------------------------");
        System.out.println("map:" + map);
        //map:{22=[User{name='老八', age='22', height=172}], 23=[User{name='老九', age='23', height=169}], 17=[User{name='张三', age='17', height=180}], 18=[User{name='李四', age='18', height=175}], 19=[User{name='王五', age='19', height=170}], 20=[User{name='赵六', age='20', height=190}], 21=[User{name='钱七', age='21', height=160}]}
        System.out.println("mapStream:" + mapStream);
        //mapStream:{22=[User{name='老八', age='22', height=172}], 23=[User{name='老九', age='23', height=169}], 17=[User{name='张三', age='17', height=180}], 18=[User{name='李四', age='18', height=175}], 19=[User{name='王五', age='19', height=170}], 20=[User{name='赵六', age='20', height=190}], 21=[User{name='钱七', age='21', height=160}]}


        /**
         * 5.求和
         * */
        //5、求和
        //(1)、int、double、long:
        //求和的普通遍历方式跟上面差不多(遍历进行求和即可),就不举例了;
        double heightSumStream = userList.stream().mapToDouble(User::getHeight).sum();
        System.out.println("-----------------------------------------------");
        System.out.println("heightSumStream" + heightSumStream);
        //heightSumStream1216.0

        /**
         * 6.Map、List相互转换
         * */
        //6、Map、List互转
        //(1)、list转map:
        //a、遍历:
        Map<String, User> userMap = new HashMap<>();
        for (User user : userList) {
            //key为user.getName(),value为user对象
            userMap.put(user.getName(), user);
        }

		/*b、stream流:
		    用Collectors的toMap方法转换List,一般会遇到两个问题。
		(1)转换map,key重复问题;
			代码中使用(key1,key2)->key2表达式可以解决此类问题,如果出现重复的key就使用key2覆盖前面的key1,也可以定义成(key1,key2)->key1,保留key1,根据自己的业务场景来调整。
		(2)空指针异常,即转为map的value是null。这个可以用filter过滤;*/
        Map<String, User> userMapStream = userList.stream().collect(Collectors.toMap(User::getName, Function.identity(), (key1, key2) -> key2));
        System.out.println("-----------------------------------------------");
        System.out.println("userMap:" + userMap);
        //userMap:{钱七=User{name='钱七', age='21', height=160}, 李四=User{name='李四', age='18', height=175}, 张三=User{name='张三', age='17', height=180}, 老九=User{name='老九', age='23', height=169}, 老八=User{name='老八', age='22', height=172}, 王五=User{name='王五', age='19', height=170}, 赵六=User{name='赵六', age='20', height=190}}
        System.out.println("userMapStream:" + userMapStream);
        //userMapStream:{钱七=User{name='钱七', age='21', height=160}, 李四=User{name='李四', age='18', height=175}, 张三=User{name='张三', age='17', height=180}, 老九=User{name='老九', age='23', height=169}, 老八=User{name='老八', age='22', height=172}, 王五=User{name='王五', age='19', height=170}, 赵六=User{name='赵六', age='20', height=190}}


        /**
         * 7.map转list
         * */
        //(2)、map转list:
        //		a、遍历:
        List<User> userMapToList = new ArrayList<>();
        for (String userName : userMap.keySet()) {
            userMapToList.add(userMap.get(userName));
        }
        //		b、stream流:
        List<User> userMapToListStream = userMapStream.entrySet().stream().map(e -> e.getValue()).collect(Collectors.toList());
        System.out.println("-----------------------------------------------");
        System.out.println("userMapToList:" + userMapToList);
        //userMapToList:[User{name='钱七', age='21', height=160}, User{name='李四', age='18', height=175}, User{name='张三', age='17', height=180}, User{name='老九', age='23', height=169}, User{name='老八', age='22', height=172}, User{name='王五', age='19', height=170}, User{name='赵六', age='20', height=190}]
        System.out.println("userMapToListStream:" + userMapToListStream);
        //userMapToListStream:[User{name='钱七', age='21', height=160}, User{name='李四', age='18', height=175}, User{name='张三', age='17', height=180}, User{name='老九', age='23', height=169}, User{name='老八', age='22', height=172}, User{name='王五', age='19', height=170}, User{name='赵六', age='20', height=190}]

        /**
         * 8.做判断
         * */
		/*
		(1)、anyMatch():
				判断的条件里,任意一个元素成功,返回true;
				比如上面的userlList,我想判断是否有height > 175的:*/
        boolean b = userList.stream().anyMatch(user -> user.getHeight() > 175);
        System.out.println("-----------------------------------------------");
        System.out.println("anyMatch:" + b);
        //anyMatch:true


        //(2)、allMatch():
        //		allMatch:判断条件里的元素,所有的都是,返回true;
        //		比如上面的userlList,我想判断是否全部height > 175的:
        boolean b1 = userList.stream().allMatch(user -> user.getHeight() > 175);
        System.out.println("-----------------------------------------------");
        System.out.println("allMatch:" + b1);
        //allMatch:false


        //		3)、noneMatch():
        //		与allMatch相反,判断条件里的元素,所有的都不是,返回true
        boolean b2 = userList.stream().noneMatch(user -> user.getHeight() > 175);
        System.out.println("-----------------------------------------------");
        System.out.println("noneMatch:" + b2);
        //noneMatch:false

        //(4)、求取目标和:
        long count = userList.stream().filter(user -> user.getHeight() > 175).count();
        System.out.println("-----------------------------------------------");
        System.out.println("count:" + count);
        //count:4


        /**
         * 9.多个条件
         * */
        //   A.获取所有数据,过滤掉第一条和最后一条
        System.out.println("-----------------------------------------------");
        userList.stream().skip(1).limit((userList.size()) - 2).forEach(System.out::println);
     /*   User{name='李四', age='18', height=175}
          User{name='王五', age='19', height=170}
          User{name='赵六', age='20', height=190}
          User{name='钱七', age='21', height=160}
          User{name='老八', age='22', height=172}*/


        //B.获取身高最大的用户信息
        //第一种方式
        System.out.println("-----------------------------------------------");
        userList.stream().sorted((s1, s2) -> s2.getHeight() - s1.getHeight()).limit(1).forEach(System.out::println);
        //User{name='赵六', age='20', height=190}


        //第二种方式(使用Comparator.comparing())
        Optional<User> collect = userList.stream().collect(Collectors.maxBy(Comparator.comparing(User::getHeight)));
        System.out.println("-----------------------------------------------");
        System.out.println("身高最高的用户信息:" + collect);
        //身高最高的用户信息:Optional[User{name='赵六', age='20', height=190}]


        //C.获取年龄最大的两个用户的 姓
        System.out.println("-----------------------------------------------");
        userList.stream().sorted((s1, s2) -> s2.getHeight() - s1.getHeight()).limit(2).forEach(System.out::println);
        /**
         * User{name='赵六', age='20', height=190}
         * User{name='张三', age='17', height=180}
         * */


        System.out.println("-----------------------------------------------");
        userList.stream().sorted(Comparator.comparing(User::getHeight).reversed()).limit(2).forEach(System.out::println);
        /**
         * User{name='赵六', age='20', height=190}
         * User{name='张三', age='17', height=180}
         * */

        System.out.println("-----------------------------------------------");
        userList.stream()
                .sorted(Comparator.comparing(User::getHeight))
                .limit(2)
                .forEach(user -> System.out.println(user));


        System.out.println("-----------------------------------------------");
        userList.stream().sorted(new Comparator<User>() {//先进性排序再进行获取每个用户的名字的首字母
            @Override
            public int compare(User o1, User o2) {
                return o2.getHeight() - o1.getHeight();
            }
        }).map(new Function<User, String>() { //T是User类(因为要利用User类进行调用get/set方法),返回值类型是String类型
            @Override
            public String apply(User t) {
                // String substring(int beginIndex, int endIndex) 返回一个字符串,该字符串是此字符串的子字符串。
                return t.getName().substring(0, 1);//获取字符串中的第一个字符

                //return t.getName().substring(t.getName().length()-1,t.getName().length());  //D.获取年龄最大的两个用户的 姓名的最后一个字
            }
        }).limit(2).forEach(System.out::println);
        System.out.println("-----------------------------------------------");

        /**
         * 赵
         * 张
         * */
        // lambda表达式进行简化
        userList.stream().sorted((o1, o2) -> o2.getHeight() - o1.getHeight()).map(t -> t.getName().substring(0, 1)).limit(2).forEach(System.out::println);
        /**
         * 赵
         * 张
         * */
        System.out.println("-----------------------------------------------");
        /**
         *  截取索引位置1到4(不包含4)的子字符串(索引从0开始)
         * String substring2 = name.substring(1, 4);
         * 从最后一位的索引处开始截取
         * substring(t.getName().length() - 1, t.getName().length())
         * */
        userList.stream().sorted((o1, o2) -> o2.getHeight() - o1.getHeight()).map(t -> t.getName().substring(t.getName().length() - 1, t.getName().length())).limit(2).forEach(System.out::println);
        /**
         * 六
         * 三
         * */

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Mxin5

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

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

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

打赏作者

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

抵扣说明:

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

余额充值