【问题标题】:When should I sort Map elements in Java? [closed]什么时候应该在 Java 中对 Map 元素进行排序? [关闭]
【发布时间】:2021-12-01 17:44:13
【问题描述】:

我有一个保存用户角色和权限的 excel 文件,如下所示(为简洁起见,省略了一些字段):

User Role | Permission Uuid    
----------|----------------                     
0         | a465433f... 
0         | 43db5a33...
1         | 610e9040... 
0         | 94e85bef... 
1         | 34e85f32...

我正在逐行读取一个excel文件,需要通过如下所示的请求来创建导入数据:

public class PermissionRequest {
    private UserRole userRole;
    private List<UUID> permissionUuidList;
}

我认为我需要按用户角色映射每个权限 Uuid,因此我尝试使用Map&lt;Integer, List&lt;UUID&gt;&gt;,如下所示:

Map<Integer, List<UUID>> userRolePermissionMap = new HashMap<>();
userRolePermissionMap.put(Integer.parseInt(cellList.get(USER_ROLE)),
    Collections.singletonList(UUID.fromString(cellList.get(PERMISSON_UUID))));

但我认为它不正确。那么,由于用户角色未在 excel 文件中排序,我是否需要按用户角色进行排序或分组,然后循环发送PermissionRequest 到存储库以进行创建操作?或者我应该为此使用TreeMap 吗?如果可以,我该如何使用?

【问题讨论】:

  • HashMap 未排序。不清楚你在问什么。
  • 不清楚您的要求 - 您不需要对输入进行排序以创建具有正确映射的哈希图,即使您要添加 0 然后 1 然后 0 然后 1 和以此类推,一切都会进入正确的存储桶。但是,如果您需要对列表中的 uuid 进行排序,那么您需要自己提供排序
  • @m.antkowicz 我也尝试过this 方法,但它不按用户角色排序。有什么想法吗?

标签: java list collections hashmap treemap


【解决方案1】:

HashMap 不保证排序顺序,TreeMap 按键排序(在本例中为UserRole),另外,UUID 列表可以排序(如果需要)。

但是,上面的代码使用了Collections.singletonList,这是不正确的,因为这样的列表是不可变的,并且只能包含一个 UUID。

使用 Java Stream API Collectors.groupingBy with Supplier&lt;Map&gt;Collectors.mapping 的简洁实现可能如下所示,假设有一个表示行的 cellList 对象列表:

Map<Integer, List<UUID>> userRolePermissionMap =
        rowsList.stream() // Stream<Row> 
                .collect(Collectors.groupingBy(
                    cellList -> Integer.parseInt(cellList.get(USER_ROLE)),
                    TreeMap::new, // supplier of sorted map
                    Collectors.mapping(
                        cellList -> UUID.fromString(cellList.get(PERMISSON_UUID)),
                        Collectors.toList())
                ));

使用Map::computeIfAbsent的基于循环的实现可能如下(如果缺少roleId键并将UUID添加到UUID列表中,则会创建一个空列表):

Map<Integer, List<UUID>> userRolePermissionMap = new TreeMap<>();

for (List<Cell> cellList : rowList) {
    userRolePermissionMap.computeIfAbsent(
        Integer.parseInt(cellList.get(USER_ROLE)),
        k -> new ArrayList<UUID>()
    )  // mutable List<UUID> is returned
    .add(UUID.fromString(cellList.get(PERMISSON_UUID)));
}

【讨论】:

  • 完美!...非常感谢。
猜你喜欢
  • 2014-01-16
  • 1970-01-01
  • 1970-01-01
  • 2011-02-04
  • 2017-09-11
  • 1970-01-01
  • 2020-10-20
  • 1970-01-01
  • 2016-05-14
相关资源
最近更新 更多