首页 > 其他分享 >jdk8 StreamAPI 的使用

jdk8 StreamAPI 的使用

时间:2024-04-03 20:12:03浏览次数:22  
标签:map 菜单 Stream menu List jdk8 使用 StreamAPI menuList

本文将以UmsMenu对象为例来介绍Stream API的常用操作。UmsMenu是一个菜单对象,具有树形结构,对象定义如下

Stream对象的创建

Stream对象分为两种,一种串行的流对象,一种并行的流对象。

1 // menuList指所有菜单列表
2 // 为集合创建串行流对象
3 Stream<UmsMenu> stream = menuList.stream();
4 // 为集合创建并行流对象
5 Stream<UmsMenu> parallelStream = menuList.parallelStream();

filter

对Stream中的元素进行过滤操作,当设置条件返回true时返回相应元素。

1 @Test
2 public void filterTest(){
3     //filter操作:获取所有一级菜单
4     List<UmsMenu> oneLevelList = menuList.stream()
5     .filter(menu -> menu.getParentId() == 0L)
6     .collect(Collectors.toList());
7     LOGGER.info("filter操作:{}",oneLevelList);
8 }

map

对Stream中的元素进行转换处理后获取,比如可以将UmsMenu对象转换成Long对象。我们经常会有这样的需求:需要把某些对象的id提取出来,然后根据这些id去查询其他对象,这时可以使用此方法。

1 @Test
2 public void mapTest(){
3     //map操作:获取所有菜单的id
4     List<Long> idList = menuList.stream()
5     .map(menu -> menu.getId())
6     .collect(Collectors.toList());
7     LOGGER.info("map操作:{}",idList);
8 }

limit

从Stream中获取指定数量的元素。

1 @Test
2 public void limitTest(){
3     //limit操作:获取前5个菜单
4     List<UmsMenu> firstFiveList = menuList.stream()
5             .limit(5)
6             .collect(Collectors.toList());
7     LOGGER.info("limit操作:{}",firstFiveList);
8 }

count

仅获取Stream中元素的个数。

1 @Test
2 public void countTest(){
3     //count操作:获取所有一级菜单的个数
4     long count = menuList.stream()
5     .filter(menu -> menu.getParentId() == 0L)
6     .count();
7     LOGGER.info("count操作:{}",count);
8 }

sorted

对Stream中元素按指定规则进行排序。

1 @Test
2 public void sortedTest(){
3     //sorted操作:将所有菜单按照sort字段进行排序
4     List<UmsMenu> sortedList = menuList.stream()
5             .sorted((menu1,menu2)->{return menu2.getSort().compareTo(menu1.getSort());})
6             .collect(Collectors.toList());
7     LOGGER.info("sorted操作:{}",sortedList);
8 }

skip

跳过指定个数的Stream中元素,获取后面的元素。

1 @Test
2 public void skipTest(){
3     //skip操作:跳过前5个元素,返回后面的
4     List<UmsMenu> skipList = menuList.stream()
5             .skip(5)
6             .collect(Collectors.toList());
7     LOGGER.info("skip操作:{}",skipList);
8 }

用collect方法将List转成map

有时候我们需要反复对List中的对象根据id进行查询,我们可以先把该List转换为以id为key的map结构,然后再通过map.get(id)来获取对象,这样比较方便。

1 @Test
2 public void collect2mapTest(){
3     //collect转map操作:将菜单列表以id为key,以菜单对象为值转换成map
4     Map<Long, UmsMenu> menuMap = menuList.stream()
5             .collect(Collectors.toMap(menu -> menu.getId(), menu -> menu));
6     LOGGER.info("collect转map操作:{}",menuMap);
7 }

应用

我们经常会有返回树形结构数据的需求。比如这里的菜单,具有一级菜单、二级菜单、三级菜单这样的结构。如果我们要返回一个集合,包含菜单以及菜单下面嵌套的子菜单,使用Stream API可以很方便的解决这个问题。

注意:这里我们的菜单上下级之间以parentId来关联,parentId是指上一级菜单的id,顶级菜单的parentId为0。

定义获取树形结构的方法

我们先过滤出parentId为0的顶级菜单,然后给每个顶级菜单设置其子级菜单,covertMenuNode方法的主要用途就是从所有菜单中找出相应子级菜单。

1 @Override
2 public List<UmsMenuNode> treeList() {
3     List<UmsMenu> menuList = menuMapper.selectByExample(new UmsMenuExample());
4     List<UmsMenuNode> result = menuList.stream()
5     .filter(menu -> menu.getParentId().equals(0L))
6     .map(menu -> covertMenuNode(menu, menuList)).collect(Collectors.toList());
7     return result;
8 }

为每个菜单设置子级菜单

这里我们使用filter操作来过滤出每个菜单的子级菜单,由于子级菜单下面可能还会有子级菜单,这里我们使用递归来解决。但是递归操作什么时候停止,这里把递归调用方法放到了map操作中去,当没有子级菜单时filter下的map操作便不会再执行,从而停止递归。

/**
 * 将UmsMenu转化为UmsMenuNode并设置children属性
 */
private UmsMenuNode covertMenuNode(UmsMenu menu, List<UmsMenu> menuList) {
    UmsMenuNode node = new UmsMenuNode();
    BeanUtils.copyProperties(menu, node);
    List<UmsMenuNode> children = menuList.stream()
            .filter(subMenu -> subMenu.getParentId().equals(menu.getId()))
            .map(subMenu -> covertMenuNode(subMenu, menuList)).collect(Collectors.toList());
    node.setChildren(children);
    return node;
}

 

 

 

标签:map,菜单,Stream,menu,List,jdk8,使用,StreamAPI,menuList
From: https://www.cnblogs.com/hnzj/p/18113427

相关文章

  • AI绘画:使用Stable Diffusion ComfyUI进行换脸:IPAdapter FaceID全面教程
        在数字艺术和媒体编辑领域,换脸技术已经成为一种流行且强大的工具。它允许创作者将一个人物的面部特征无缝地转移到另一个人物上,创造出令人信服的视觉作品。StableDiffusionComfyUI提供了一个高效的平台,让用户能够轻松地实现换脸。本文将详细介绍如何使用ComfyUI......
  • 使用 Validation
    使用Validation要使用验证,请使用class-validator。示例如何在TypeORM中使用class-validator:import{Entity,PrimaryGeneratedColumn,Column}from"typeorm";import{Contains,IsInt,Length,IsEmail,IsFQDN,IsDate,Min,Max}from"class-validator";......
  • win11使用cython将py文件打包成pyd文件
    准备工作:安装VisualStudioC编译器未安装C编译器时,编译pyd会出现报错。你可以使用VisualStudio的C编译器,或MinGW编译器。由于VisualStudio的C编译器安装方便,而MinGW较复杂,这里介绍安装VisualStudio的方法。所需文件链接:https://pan.baidu.com/s/1lLKdY0o--pAxe2jCs......
  • 在 PowerShell 中,您可以使用以下命令来管理 DNS 相关的任务以及 DNS 缓存
    在PowerShell中,您可以使用以下命令来管理DNS相关的任务以及DNS缓存:获取当前计算机的DNS客户端配置信息powershellCopyCodeGet-DnsClientGet-DnsClientInterfaceAlias       InterfaceConnectionSpecificSuffixConnectionSpecificSuffixRegi......
  • GPT4不限制使用次数了!GPT5即将推出了!
    今天登录到ChatGPTPlus账户,出现了如下提示:已经没有了数量和时间限制的提示。更改前:每3小时限制40次(团队计划为100次);更改后:可能会应用使用限制。GPT-4放开限制身边订阅了ChatGPTPlus的朋友也发现了有ChatGPT里的GPT-4,也变成了上面的情况。网络上也有人很多人反......
  • MybatisPlus分页插件的使用
    目录......
  • Python函数(一):函数的声明、调用以及参数的使用
    目录为何要用到函数函数的定义和调用函数的参数参数的传递参数的类型 return语句为何要用到函数通常我们编写一段代码是为了实现特定的功能,比如想得到一段数字序列中的最大值、最小值和平均值并输出一个字典,编写一段代码如下:num=[96,85,69,82,52,99,72]m......
  • 从基础到高级,带你深入了解和使用curl命令(一)
    前言在网络通信和数据传输中,curl命令是一个功能强大且广泛使用的工具。它可以与各种协议进行通信,如HTTP、HTTPS、FTP等,并支持各种操作,如下载文件、发送请求、测试API等。本文将从基础开始,介绍curl命令的基本用法,然后深入探讨其高级功能和实用技巧。curl简介curl是常用的命令......
  • FlowableAPI的使用
    //它涉及启动流程定义的新流程实例。RuntimeServiceruntimeService=processEngine.getRuntimeService();//RepositoryService可能是使用Flowable引擎时需要的第一个服务。RepositoryServicerepositoryService=processEngine.getRepositoryService();//围绕任务......
  • 从基础到高级,带你深入了解和使用curl命令(二)
    前言之前我们介绍了curl命令的请求网络,设置代理等操作,本文我们继续来介绍curl命令的操作,本文我们将会介绍curl命令中有关cookie的操作。获取cookie要获取服务器发送的Cookie,可以使用curl命令的-c选项,将Cookie保存到文件中。例如:curl-ccookiec.txthttp://www.baidu.com......