我应该什么时候对 Java 中的地图元素进行排序?

When should I sort Map elements in Java?

我有一个 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<Integer, List<UUID>>,如下所示:

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 不保证排序顺序,TreeMap 按键排序(在这种情况下为 UserRole),此外,UUID 列表可以排序(如果需要) .

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

使用 Java Stream API Collectors.groupingBy with Supplier<Map> and 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)));
}