• Java集合的流Stream操作(快速筛查,统一处理)


    说明

    Java中的集合流操作需要java 8的特性支持。需要对Lambda表达式有所了解

    主要作用:

    1. 快速筛查集合元素
    2. 统一对集合元素处理

    说白了就是原来的要大量循环的操作可以使用流操作快速完成

    假设条件

    之后的代码演示将于以下的假设条件来模拟表示

    存在Message

    public class Message{
        String value;
        int code;
    }
    

    存在ShortMessage

    public class ShortMessage{
        String value;
    }
    

    Tools类中存在方法

    public static ShortMessage convert(Message msg){
        return new ShortMessage(msg.getValue);
    }
    

    存在一个数组,里面存在大量已经实例化的Message对象

    List<Message> messageList;
    

    省略get、set及构造函数无营养代码

    filter操作

    作用:快速筛查,过滤元素留下符合要求的元素生成一个新的流

    假设存在

    
    
    //快速筛查出value属性包含‘bug’的message对象
    messageList = messageList.parallelStream()//转为并行流,多线程
        .filter(msg -> msg.getValue().contains("bug"))//筛查
        .collect(Collectors.toList());//流转回list
    

    msg 相当于循环messageList中的每一个Message实例对象的临时引用

    filter返回的还是一个stream,所以是可以一直链式调用操作的,比如一直.filter.filter过滤

    filter操作接受的是一个Predicate逻辑表达式,既结果是一个布尔结果,为true的保留

    map操作

    作用:统一处理

    map操作理解起来有点复杂,请看以下例子

    假设我们需要将messageList里面的所有实例转为ShortMessage对象

    一般处理

    List<ShortMessage> shorts = new ArrayList<>();
    for(Message msg:messageList){
        shorts.add(Tools.convert(msg));
    }
    

    流map处理方式

    List<ShortMessage> shots = messageList.parallelStream()
        .map(Tools::convert)
        .collect(Collectors.toList());
    

    所以说,map操作可以了解为需要对一个流中的元素统一处理时的操作,会将流中的每一个元素循环调用方法作为参数传递进去

    注意map中的方法多次执行返回也是一个流,而这个流的存储的元素的类型是会变化的,具体看调用方法的返回类型

    map返回的流也是可以继续链式调用的

    当然也可以这样,相信下面的代码不需要我解释

    List<ShortMessage> shorts = messageList.parallelStream()
        .filter(msg -> msg.getValue().contains("bug"))
        .map(Tools::convert)
        .collect(Collectors.toList());
    

    假设我们需要将所有的Message对象的code加100

    记住,流操作里面的只要是个Lambda表达式就可以

    messageList = messageList.parallelStream()
        .map(msg -> msg.setCode(msg.getCode()+100))
        .collect(Collectors.toList());
    

    flatMap操作

    这个说明一下,以免以后忘记

    map操作可以看到可以了解为一对一映射操作,每输入一个元素,则按map中的方法规则处理转换为另外一个元素,但有的时候是一对多操作的;

    如果从字面意思上理解,就是map的扁平化操作一般用在复合数组上面,flatMap会将流中的每一个元素再转为流操作

    List<List<Message>> list;
    //如果
    list.parallelStream().flatMap(child -> child.stream());
    //那么A表示list中的子集合的流,-> 后面必须产生一个新的流,最终;flatMap会产生一个合并出来的大的流
    

    简单例子说明

    假设存在

    public class data{
        int x;
        int y;
    }
    

    修改Message类

    public class Message{
        String value;
        int code;
        Data[] datas;
        
        /**
        *[]数组和List是两回事,这里这个方法只是演示如果data是List类型情况下
        */
        public List<Data> getDataArray(){
            return Arrays.asList(data.clone());
        }
    }
    

    测试数据

    		Message m1 = new Message("message 1", new Data[]{new Data(3, 2), new Data(3, 2), new Data(3, 2)});
            Message m2 = new Message("message 2",new Data[]{new Data(4, 2), new Data(6, 2), new Data(3, 2)});
            Message m3 = new Message("message 3",new Data[]{new Data(5, 2), new Data(4, 2), new Data(4, 2)});
            Message m4 = new Message("message 4",new Data[]{new Data(6, 2), new Data(3, 2), new Data(3, 2)});
            Message m5 = new Message("message 5",new Data[]{new Data(7, 2), new Data(2, 2), new Data(7, 2)});
            Message m6 = new Message("message 6",new Data[]{new Data(8, 2), new Data(45, 2), new Data(3, 2)});
    
            List<Message> messageList = Arrays.asList(m1, m2, m3, m4, m5, m6);
    

    现在就是说,有一个messageList保存多个Message对象,每个Message对象操作一个Data类型数组

    一、找出所有x值为3的Data对象

    List<Data> collect = messageList.parallelStream()
        .map(Message::getDatas)//把data取出来,创建一个全是data[]的流
        .flatMap(Arrays::stream)//转为流,注意会合并,创建一个全是data的流
        .filter(data -> data.getX() == 3)//筛查
        .collect(Collectors.toList());
    

    换种写法,如果是list操作会更简单

            List<Data> collect1 = messageList.parallelStream().flatMap(msg -> msg.getDataArray().stream()).filter(data -> data.getX() > 3).collect(Collectors.toList());
    
    

    二、获取所有的X的值

            List<Integer> integerList = messageList.parallelStream().flatMap(ss -> ss.getDataArray().stream()).map(Data::getX).collect(Collectors.toList());
    
    

    剩下的就不一一举例了,可以发现flatMap其实可以理解为合并处理

  • 相关阅读:
    【笔记】求数据前n个主成分以及对高维数据映射为低维数据
    使用sklearn中的fetch_mldata的错误情况以及可能可行的解决方法
    【笔记】求数据的对应主成分PCA(第一主成分)
    【笔记】主成分分析法PCA的原理及计算
    【笔记】如何确定梯度计算的准确性以及调试梯度下降法
    【笔记】随机梯度下降法
    【笔记】线性回归中的梯度下降法(实现以及向量化并进行数据归一化)
    AttributeError: module 'numpy' has no attribute 'num'
    灵雀云CTO陈恺:从“鸿沟理论”看云原生,哪些技术能够跨越鸿沟?
    容器云在证券行业的探索与实践
  • 原文地址:https://www.cnblogs.com/liangshu/p/13904965.html
Copyright © 2020-2023  润新知