Java 8 新特性 Stream流-Lambda表达式的简单使用

Java 8 新特性 Stream流-Lambda表达式的简单使用

stream流全是在内存中进行操作,将数据进行全查,使用stream()流处理数据,这个是专门来处理集合的,java8 中的新特新就新在hashmap里面的数据存储上进行了改进,对数据建立索引,而且是不同的hash计算所得的数据,里面也重写了hashcode和eques方法,当两个数据的地址相同时就会判断两个数据的值是否相等,相等的话就会重新制定一个位置,当长度大于8 ,存储的大于64时就扩展为一个二叉树。这样大大的增加了它的查询效率,而在stream流中应用了lamda表达式。在比较一个id时,会对这个数据进行hash的计算,然后去找这个值,远远的减小了搜寻的范围提高了查询的效率,

话不多说直接上代码
业务要求,现在要查询展示一个树状结构的数据,比如一个地产开发项目,一个表里有总部(1级),城市(2),区域(3),项目(4),地块(5)这些,它们就像是省市县一样有层级关系的,现在想实现的功能是根据某一个id去查询这个id锁对应下的所有数据,并且查询出来的是以树结构展示的数据,

/**
     * 根据id查询树状组织架构
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "根据id查询树状组织架构")
    @GetMapping(value = "tree")
    public RespResult selectTree(String id) {
        RespResult respResult = new RespResult<>();
        try {
        	// 先查询出所有的数据
            List<OrganizationsResultExt> all = organizationsService.findAll();
            //使用for循环来遍历获取每一条数据的id
            for (OrganizationsResultExt organizationsResultExt : all) {
                if (id.equals(organizationsResultExt.getId())) {
     				// Item中存储的是它的下一层数据
                    organizationsResultExt.setItems(getChildren(all, id));
                    respResult.setData(organizationsResultExt);
                }
            }
        } catch (Exception ex) {
            LogUtil.logApplicationInfo("根据id查询树状组织架构请求错误", ex);
            respResult.setMsg(ResultEnum.DELETE_ERROE.getMsg());
        }
        return respResult;
    }

这是递归查询

 /**
     * 递归进行查询子部门方法
     *
     * @param id
     * @return
     */
    public List<OrganizationsResultExt> getChildren(List<OrganizationsResultExt> all, String id) { 
        List<OrganizationsResultExt> list = new ArrayList<>();
        // 从所有数据中遍历
        for (OrganizationsResultExt organizationsExtVo : all) {
			// 比对遍历出来的数据的父id是否与当前查询数据的id值相同,相同就添加到集合中
            if (id.equals(organizationsExtVo.getParentId())) {            organizationsExtVo.setItems(getChildren(all, organizationsExtVo.getId()));
                list.add(organizationsExtVo);
            }
        }
        return list;
    }

这种实现方式是最容易想到的,但是这样把操作数据库的语句放到了循环中,频繁操作数据库是费时且不安全的,一个接口可能占用了过大的资源,所以这也是效率方面禁止的写法
第二种:

  /**
     * 根据id查询树状组织架构
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "根据id查询树状组织架构")
    @GetMapping(value = "tree")
    public RespResult selectTree(String id) {
        RespResult respResult = new RespResult<>();
        try {
            OrganizationsResultExt organizationsExts = organizationsService.findById(id);
            organizationsExts.setItems(getChildren(id));
            respResult.setData(organizationsExts);
        } catch (Exception ex) {
            LogUtil.logApplicationInfo("根据id查询树状组织架构请求错误", ex);
            respResult.setMsg(ResultEnum.DELETE_ERROE.getMsg());
        }
        return respResult;
    }

      /**
     * 递归进行查询子部门方法
     *
     * @param id
     * @return
     */
    public List<OrganizationsResultExt> getChildren( String id) {
        List<OrganizationsResultExt> list = new ArrayList<>();
        // 使用当前数据的id当做父id来查询,这样获取到这个id下所有的子数据,在遍历每条数据,并且使用当前遍历
        // 出来的数据id作为id再次调用
        /**
        *使用当前数据的id当做父id来查询,这样获取到这个id下所有的子数据,在遍历每条数据,并且使用当前遍历出来的
        数据id再掉当前方法作为父id去查询。
        */
        List<OrganizationsResultExt> organizationsExtList = organizationsService.findByParentId(id);
        for (OrganizationsResultExt organizationsExtVo : organizationsExtList) {
            organizationsExtVo.setItems(getChildren(organizationsExtVo.getId()));
            list.add(organizationsExtVo);
        }
        return list;

Stream流形式,当是项目或者地块时就为他设置SpaceId

    * 获取组织结构树
     *
     * @param orgzId 组织机构ID
     * @return
     */
    @Override
    public RespResult selectTree(String orgzId) {
        RespResult respResult = new RespResult<>();

        String orgTreeListStr = redisUtils.get(OrganizationConstant.ORGANIZATION_TREE_LIST + orgzId);
        if (StringUtils.isNotEmpty(orgTreeListStr)) {
            respResult = JSON.parseObject(orgTreeListStr, RespResult.class);
        } else {
//            对组织进行全查
            List<OrganizationResultExt> organizationsResultExtList = this.findAll();
//            项目数据全查
            List<ProjectExt> projectsExtList = projectService.findAll();
//            地块数据全查
            List<BlockExt> blocksExtList = blockService.findAll();
//            根据传进来的id进行数据查询
            OrganizationResultExt organizationsResultExt = this.findOrganizationById(orgzId);
//            若当前数据的level值为3(地块)或者4(项目)时,为字段设置SpaceId值
            if (organizationsResultExt.getLevel() == OrganizationConstant.PROJECT ||
                    organizationsResultExt.getLevel() == OrganizationConstant.BLOCK) {
                addProjectAndBlock(organizationsResultExt, projectsExtList, blocksExtList, orgzId);
            }
            organizationsResultExt.setItems(getChildren(organizationsResultExtList, projectsExtList, blocksExtList, orgzId));
            respResult.setCode(ResultEnum.SUCCESS.getCode());
            respResult.setMsg(ResultEnum.SUCCESS.getMsg());
            respResult.setData(organizationsResultExt);

            String orgTeeStr = JSON.toJSONString(respResult);
            redisUtils.set(OrganizationConstant.ORGANIZATION_TREE_LIST + orgzId, orgTeeStr, OrganizationConstant.ORGANIZATION_CACHE_SECONDS);
        }
        return respResult;
    }

递归查询

 /**
     * 递归进行查询子部门方法
     *
     * @param organizationsResultExtList 组织的数据
     * @param projectsExtList            项目的数据集合
     * @param blocksExtList              地块的数据集合
     * @param id                         查询的id
     */
    private List<OrganizationResultExt> getChildren(List<OrganizationResultExt> organizationsResultExtList,
                                                    List<ProjectExt> projectsExtList,
                                                    List<BlockExt> blocksExtList,
                                                    String id) {
        List<OrganizationResultExt> list = new ArrayList<>();
        organizationsResultExtList.stream().filter(o -> id.equals(o.getParentId()))
                .forEach((organizationsExt) -> {
                    if (organizationsExt.getLevel() == OrganizationConstant.PROJECT || organizationsExt.getLevel() == OrganizationConstant.BLOCK) {
                        addProjectAndBlock(organizationsExt, projectsExtList, blocksExtList, organizationsExt.getId());
                    }
                    organizationsExt.setItems(getChildren(organizationsResultExtList, projectsExtList, blocksExtList, organizationsExt.getId()));
                    list.add(organizationsExt);
                });
        return list;
    }
  /**
     * 向组织的数据中设置SpaceId值
     *
     * @param organizationsResultExt 组织的数据
     * @param projectsExtList        项目的数据集合
     * @param blocksExtList          地块的数据集合
     * @param id                     查询的id
     */
    private void addProjectAndBlock(OrganizationResultExt organizationsResultExt,
                                    List<ProjectExt> projectsExtList,
                                    List<BlockExt> blocksExtList,
                                    String id) {
        Optional<ProjectExt> optionalProjectsExt = projectsExtList.stream().filter(o -> id.equals(o.getOgzId())).findFirst();
//        判断optionalProjectsExt里面是否有值
        if (optionalProjectsExt.isPresent()) {
            organizationsResultExt.setSpaceId(optionalProjectsExt.get().getOgzId());
        }
//        判断这个id是否与地块集合中的某一条数据的OgzId相同
        Optional<BlockExt> optionalBlocksExt = blocksExtList.stream().filter(o -> id.equals(o.getOgzId())).findFirst();
//        判断optionalProjectsExt里面是否有值
        if (optionalBlocksExt.isPresent()) {
            organizationsResultExt.setSpaceId(optionalBlocksExt.get().getId());
        }
    }

Stream流的使用三步

创建流:projectsExtList.stream(),

中间操作:.filter(o -> id.equals(o.getOgzId())),

结束操作:.findFirst()

返回的是一个Optional,这个是被处理过的,当没查询到数据时,自己添加一个对象防止空指针,
所以这个如果没查到数据不能用null来判断,需要使用.isPresent()方法来判断,这个对象里是否有值。然后再做后边操作。

你可能感兴趣的:(笔记,stream)