【问题标题】:how to collect to LinkedHashMap in java 8 [duplicate]如何在java 8中收集到LinkedHashMap [重复]
【发布时间】:2020-10-06 08:39:35
【问题描述】:

目前我们正在通过以下方式将repository.findAll() 返回的列表转换为地图:

Map<Long, FooDto> fooMap=fooRepository.findAll()
                .stream()
                .map(fooDomainToDtoMapper::mapDomainToDto)
                .collect(Collectors.toMap(fooDto::getfooId, foo -> foo));

但我们想保留repository.findAll() 返回的顺序。我们希望按降序返回记录,然后通过执行以下操作将其收集到LinkedHashmap

Map<Long, FooDto> fooMap= fooRepository.findAll(Sort.by(Sort.Direction.DESC, "name"))
                .stream()
                .map(fooDomainToDtoMapper::mapDomainToDto)
                //trying to do something like:
                .collect(Collectors.toMap(fooDto::getfooId, foo -> foo,LinkedHashMap::new));

如果我们尝试在正常的Collectors.toMap 中收集上述降序结果,那么排序查询完全没有效果,在最终结果中看起来就像正常的选择。

【问题讨论】:

  • 看看the documentation,你会发现toMap没有接受地图供应商的三参数版本,只有四参数重载。所以你必须在地图供应商之前插入一个合并函数。

标签: java spring-boot collections java-8 spring-data-jpa


【解决方案1】:

如果你想为Map 传递一个供应商,你也必须传递一个合并函数:

Map<Long, FooDto> fooRepository.findAll(Sort.by(Sort.Direction.DESC, "name"))
            .stream()
            .map(fooDomainToDtoMapper::mapDomainToDto)
            .collect(Collectors.toMap(fooDto::getfooId,
                                      Function.identity(),
                                      (v1,v2)->v1,
                                      LinkedHashMap::new));

【讨论】:

  • 当你假设键是唯一的,你应该使用(v1,v2)-&gt;{ throw new AssertionError(); }作为合并函数,而不是在断言不成立时默默地覆盖值。
  • @Holger 我不确定AssertionError 在这里是否明智。通常它表示逻辑上不应该发生的情况,而这是对输入数据的断言,并且不能在逻辑上排除。错误不会被catch(Exception e) 捕获,并且通常被视为致命错误,这在这里似乎也不合适。 (v1,v2)-&gt;{ throw new IllegalStateException("Unexpected duplicate values:" + Arrays.asList(v1, v2)); } 似乎更合适。
  • @MikeFHay 这取决于存储库的 ID 是否算作输入数据。结果相差不大。 RuntimeExceptionError 都未经检查,通常不会被捕获(catch(Exception e) 被认为是代码异味,几乎所有审计工具都会对其进行标记)。用于异步执行的工具会捕获所有的 throwable。
【解决方案2】:

试试这个:

 .stream()
 .map(fooDomainToDtoMapper::mapDomainToDto)
 .collect(LinkedHashMap::new, 
          (map, fooDto) -> map.put(fooDto.getfooId(), fooDto),
          Map::putAll);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-07
    • 2016-08-19
    • 2019-02-17
    • 2019-03-29
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多