前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java8-Stream在集合中的8种应用案例

Java8-Stream在集合中的8种应用案例

作者头像
每天学Java
发布2020-06-01 10:46:15
1.7K0
发布2020-06-01 10:46:15
举报
文章被收录于专栏:每天学Java
前言

Java8新特性我们使用的应该比较多了,今天这里整理了个人使用最多的8种场景,希望对大家有所帮助。

遍历

遍历也许是我们使用最多的功能了,在Java8之前我们遍历集合通常会采用for循环,迭代器,而在Java8中有了更加简介的方法:

代码语言:javascript
复制
    public static void main(String[] args) {
        List<EmailModal> list = new ArrayList<>();
        EmailModal email = new EmailModal();
        email.setTitle("邮件名称");
        list.add(email)
        //方式一:普通流
        list.stream().forEach(emailModal -> {
            System.out.println(emailModal);
            System.out.println(emailModal.getTitle());
        });
        //方式二:并行流
        list.parallelStream().forEach(emailModal -> {
            System.out.println(emailModal);
            System.out.println(emailModal.getTitle());
        });
    }

方式二中,相当于使用了多线程去并行遍历,系统会根据运行服务器的资源占用情况自动进行分配。也正是因为并行流采用了多线程的方式去遍历数据,所以我们需要注意以下两点(自己遇到的坑,可能还会有其他的坑我没有发现):

1.避免在并行流中使用线程不安全的对象,比如ArrayList

2.主线程中ThreadLocal存储的线程局部变量,不能再并行流中获取

过滤

我们经常需要将集合中一些数据进行过滤,比如过滤集合中负数,过滤一些权限相关数据,在Java8之前我们更多的是使用迭代器进行remove操作,在Java8中有了两种更加简介的方法,其一:利用Collection的removeIf方法;其二:利用Stream的filter方法。

代码语言:javascript
复制
    public static void main(String[] args) {
        List<EmailModal> list = new ArrayList<>();
        EmailModal email = new EmailModal();
        email.setHtml(true);
        EmailModal email2 = new EmailModal();
        email2.setHtml(false);
        list.add(email);
        list.add(email2);
        //removeIf方法过滤html为false的对象
        list.removeIf(emailModal -> !emailModal.isHtml());
        //filter方法过滤掉html为true的对象
        list = list.stream().filter(emailModal -> !emailModal.isHtml()).collect(Collectors.toList());
        list.stream().forEach(emailModal -> {
            System.out.println(emailModal);
            System.out.println(emailModal.isHtml());
        });
    }

对于上面两种方法,我们需要区分一下,首先removeIf会将表达式中返回true的元素过滤掉,filter方法会将表达式中返回true的元素保留下来,两者是相反的。其次使用stream的filter方法过滤数据,如果想对List生效,则必须使用collect方法让list接收。

去重

去重我们经常也会使用到,对集合了解程度的不同,我们会使用不同的方法,比如最简单的方法遍历数据,使用新的空集合接受数据,利用contains方法判断是否在新集合中add元素,其次就是使用HashSet,我们不判断直接将元素放到Set中,利用集合的特效去重。但是在Java8中有更加简洁的方案,方案一:我们可以利用distinct()方法实现,如果去重元素不是基本类型而是对象的话,需要重写hashcode和equals方法,否则会去重失败。方案二:利用filter配合HashSet去除重复元素,set新增元素如果重复会返回false,刚好配合filter过滤false的特效

代码语言:javascript
复制
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("1");
        //方案一
        list.stream().distinct().forEach(s -> {
            System.out.println(s);
        });
        //方案二
        list.stream().filter(distinctByKey(String::trim)).forEach(s -> {
            System.out.println(s);
        });
    }

    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Set<Object> seen = ConcurrentHashMap.newKeySet();
        return t -> seen.add(keyExtractor.apply(t));
    }
匹配

匹配数据也是我们常用的操作,比如我们需要在集合中找到属性ID为10的对象,将其取出,Java8之前我们通常会遍历集合,使用if判断,然后匹配到使用break跳出循环,但是在Java8中,我们可以使用anyMatch达到相同的效果。

代码语言:javascript
复制
    public static void main(String[] args) {
        List<EmailModal> list = new ArrayList<>();
        EmailModal email = new EmailModal();
        email.setHtml(true);
        EmailModal email2 = new EmailModal();
        email2.setHtml(true);
        list.add(email);
        list.add(email2);
        list.stream().anyMatch(emailModal -> {
            if (emailModal.isHtml()) {
                System.out.println(emailModal.isHtml());
                //其他逻辑
                return true;
            }
            return false;
        });
    }
拼接

开发接口的时候,前端会存在传递使用某个符号(逗号)隔开的字符串,我们通常会将其转换为集合,作为批量查询的条件。或者我们需要将集合转换为逗号隔开的字符。

代码语言:javascript
复制
        String ids= "1,2,3,4,5,6";
        //转集合
        List<Integer> listIds = Arrays.asList(ids.split(","))
        .stream()
        .map(s -> Integer.parseInt(s.trim()))
        .collect(Collectors.toList());
        System.out.println(listIds);
        //转字符串
        String str = listIds.stream()
                .map(integer->integer.toString())
                .collect(Collectors.joining(","));
        System.out.println(str);
抽取单个属性

当我们调用一些第三方接口的时候,可能返回集合存储对象比较复杂,而我们只需要某个字段值的时候,我们可以通过map来实现这个效果

代码语言:javascript
复制
    public static void main(String[] args) {
        List<EmailModal> list = new ArrayList<>();
        EmailModal email = new EmailModal();
        email.setHtml(true);
        EmailModal email2 = new EmailModal();
        email2.setHtml(true);
        list.add(email);
        list.add(email2);
        List<Boolean> list2 = list.stream().map(emailModal -> emailModal.isHtml()).collect(Collectors.toList());
        System.out.println(list2);
    }
最值

获取集合中最大值和最小值方法有很多,比如排序后取值,或者遍历比较,在Java8中通过Stream的max和min方法我们很简单的实现这个功能

代码语言:javascript
复制
    public static void main(String[] args) {
        List<QuestionBankVO> list = new ArrayList<>();
        QuestionBankVO questionBankVO = new QuestionBankVO();
        questionBankVO.setId(2);
        QuestionBankVO questionBankVO2 = new QuestionBankVO();
        questionBankVO2.setId(4);
        QuestionBankVO questionBankVO3 = new QuestionBankVO();
        questionBankVO3.setId(5);
        list.add(questionBankVO);
        list.add(questionBankVO2);
        list.add(questionBankVO3);

        int maxVal = list.stream().
        max(Comparator.comparingInt(QuestionBankVO::getId)).
        get().
        getId();
        System.out.println(maxVal);

        int minVal = list.stream().
        min(Comparator.comparingInt(QuestionBankVO::getId)).
        get().
        getId();
        System.out.println(minVal);
    }
分组

就个人而言,将List转为Map的操作我遇到比较少,在Java8中可以通过groupingBy方法进行转换

代码语言:javascript
复制
    public static void main(String[] args) {
        List<QuestionBankVO> list = new ArrayList<>();
        QuestionBankVO questionBankVO = new QuestionBankVO();
        questionBankVO.setId(2);
        questionBankVO.setCode("hello");
        QuestionBankVO questionBankVO2 = new QuestionBankVO();
        questionBankVO2.setId(2);
        questionBankVO.setCode("hello2");
        QuestionBankVO questionBankVO3 = new QuestionBankVO();
        questionBankVO3.setId(5);
        questionBankVO.setCode("hello3");
        list.add(questionBankVO);
        list.add(questionBankVO2);
        list.add(questionBankVO3);

        Map<Integer, List<QuestionBankVO>> map = list.stream().collect(Collectors.groupingBy(QuestionBankVO::getId));
        for (Map.Entry<Integer,  List<QuestionBankVO>> entry : map.entrySet()) {
            System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
        }
    }
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 每天学Java 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 遍历
  • 过滤
  • 去重
  • 匹配
  • 拼接
  • 抽取单个属性
  • 最值
  • 分组
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档