如何使用流将地图转换为地图,即嵌套地图

时间:2020-05-14 05:24:30

标签: java-stream

我在下面输入了Map,并希望使用Java流将其转换为Map(即Map>),任何帮助都将适用于

Map<String, Object> objectmetainfo = new HashMap();
objectmetainfo.put("metainfo.id", "id");
objectmetainfo.put("metainfo.title", "title");
objectmetainfo.put("metainfo.description", "description");

objectmetainfo.put("metainfo.userDetails.user.id", "id");
objectmetainfo.put("metainfo.userDetails.user.firstName", "firstName");
objectmetainfo.put("metainfo.userDetails.user.lastName", "lastName");
objectmetainfo.put("metainfo.userDetails.user.email", "email");
objectmetainfo.put("metainfo.userDetails.user.phone", "phone");

objectmetainfo.put("metainfo.userDetails.userSupervisor.id", "id");
objectmetainfo.put("metainfo.userDetails.userSupervisor.firstName", "firstName");
objectmetainfo.put("metainfo.userDetails.userSupervisor.lastName", "lastName");
objectmetainfo.put("metainfo.userDetails.userSupervisor.email", "email");
objectmetainfo.put("metainfo.userDetails.userSupervisor.phone", "phone");

--------- many more ---------


objectmetainfo.put("metainfo.user_id", "id");
objectmetainfo.put("metainfo.user_name", "name");

我想将此地图转换为Map,如下所示:

  1. 那些包含前缀 metainfo.userDetails 的记录,例如“ metainfo.userDetails.user.id”,“ id”,我们必须删除前缀metainfo.userDetails,下一个单词将被视为地图的键,在上述情况下, user 将是地图和休息物作为内部地图的键值对 例如:-以下是包含 metainfo.userDetails 前缀
  2. 的所有记录的输出映射
{"user":{"id":"id", "firstName":"firstName", "lastName":"lastName", "email":"email", "phone":"phone"}, "userSupervisor":{"id":"id", "firstName":"firstName", "lastName":"lastName", "email":"email", "phone":"phone}}
  1. 不包含 metainfo.userDetails 且仅包含“ metainfo”的记录。给那些需要在地图中的“附加”键下添加前缀 例如:-
{"additional":{"user_id":"user_id", "user_name":"user_name"}} 

1 个答案:

答案 0 :(得分:1)

我已经使用Pair(导入javafx.util.Pair;)来获取Pair<String, Pair<String, Object>>

这个想法很简单,首先获取Map的entrySet,然后根据条件创建单个Pair。 使用GroupingBy合并结果(以获取Map>)并将其收集到Map中。

  Map<String, Map<String, Object>> answer =
            objectmetainfo.entrySet()
                    .stream()
                    .map(e-> makePair(e))
                    .collect(Collectors.groupingBy(e-> e.getKey(), Collectors.toMap(e-> e.getValue().getKey(), e-> e.getValue().getValue()) ));

配对功能:

    private static Pair<String, Pair<String, Object>> makePair(Map.Entry<String, Object> mapEntry){

    final String[] s = mapEntry.getKey().split("\\.");

  return
            mapEntry.getKey().contains("metainfo.userDetails.") ?  new Pair(s[2],
                    new Pair(s[3], mapEntry.getValue())) :
                    new Pair("additional",
                            new Pair(s[1], mapEntry.getValue()))
            ;
}

将键拆分为“。” (正则表达式“ //。”),然后根据条件进行配对。

PS:请给变量取有意义的名称。