我需要转换以下内容:
Map<Long,Map<String,String>> mapOfMaps
至
List<List<String>> listOflists
其中外部映射(mapOfMaps
(的键是冗余的(对于该操作(。所以基本上,我可以从mapOfMaps.values().stream()
开始。
对于每个地图对象,例如:
{"苹果":"1","橙色":"2"}
我需要将其转换为列表:
{"苹果"、"1"、"橙色"、"2"}
最有效的方法是什么?
完整示例:
{"1L":{"key1":"value1","key2":"value2"},"2L":{"key3":"value3","key4":"value4"}}
预期:
[[key1,value1,key2,value2],[key3,value3,key4,value4]]
类似这样的东西:
List<List<String>> listOflists =
mapOfMaps.values()
.stream()
.map(m -> m.entrySet()
.stream()
.flatMap(e->Stream.of(e.getKey(),e.getValue()))
.collect(Collectors.toList()))
.collect(Collectors.toList());
对于每个内部Map
,您可以在entrySet()
上进行流式传输,并创建一个包含所有键和值的流,将这些键和值收集到List
中。
例如,如果使用初始化Map
Map<Long,Map<String,String>> mapOfMaps = new HashMap<>();
mapOfMaps.put(1L,new HashMap());
mapOfMaps.put(2L,new HashMap());
mapOfMaps.get(1L).put("key1","value1");
mapOfMaps.get(1L).put("key2","value2");
mapOfMaps.get(2L).put("key3","value3");
mapOfMaps.get(2L).put("key4","value4");
您将获得以下List
:
[[key1, value1, key2, value2], [key3, value3, key4, value4]]
下面是我的解决方案版本。您可以对条目进行迭代,并相应地将值添加到所需的列表中。
List<List<String>> list = map.
values()
.stream()
.map(value -> {
List<String> list1 = new ArrayList<>();
for (Map.Entry<String, String> entry : value.entrySet()) {
list1.add(entry.getKey());
list1.add(entry.getValue());
}
return list1;
})
.collect(Collectors.toList());
测试输入:
Map<Long, Map<String, String>> map = new HashMap<>();
Map<String, String> submap1 = new HashMap<>();
submap1.put("test", "test2");
Map<String, String> submap2 = new HashMap<>();
submap2.put("test6", "6");
map.put(1l, submap1);
map.put(2l, submap2);
这里有一个解决方案,它比嵌套的lambdas稍微不那么酷,但可读性更强:
public static void main(String[] args) {
// create a result list
List<List<String>> resultList = new ArrayList<>();
// create some try-out values
// a source map
Map<Long,Map<String,String>> mapOfMaps = new HashMap<>();
// some sub maps
Map<String, String> subMapOne = new HashMap<>();
subMapOne.put("One", "1");
subMapOne.put("Two", "2");
subMapOne.put("Three", "3");
Map<String, String> subMapTwo = new HashMap<>();
subMapTwo.put("Two", "2");
Map<String, String> subMapThree = new HashMap<>();
subMapThree.put("One", "1");
subMapThree.put("Three", "3");
mapOfMaps.put(1l, subMapOne);
mapOfMaps.put(2l, subMapTwo);
mapOfMaps.put(3L, subMapThree);
// just nest two forEach-calls
mapOfMaps.forEach((key, value) -> {
// create a new list for each submap
List<String> subList = new ArrayList<>();
value.forEach((subKey, subValue) -> {
// and add each entry of the submap to it
subList.add(subKey);
subList.add(subValue);
});
// finally add the list to the result list
resultList.add(subList);
});
resultList.forEach(System.out::println);
}
输出为
[One, 1, Two, 2, Three, 3]
[Two, 2]
[One, 1, Three, 3]
如果您对使用第三方库持开放态度,那么以下内容将使用Eclipse集合:
@Test
public void mapOfMapsToListOfLists()
{
MutableMap<Long, MutableSortedMap<String, String>> map = Maps.mutable.with(
1L, SortedMaps.mutable.with("key1", "value1", "key2", "value2"),
2L, SortedMaps.mutable.with("key3", "value3", "key4", "value4"));
MutableList<MutableList<String>> listOfLists = map.valuesView()
.collect(innerMap -> innerMap.keyValuesView()
.flatCollect(this::pairToList).toList())
.toList();
List<List<String>> expected = Lists.mutable.with(
Lists.mutable.with("key1", "value1", "key2", "value2"),
Lists.mutable.with("key3", "value3", "key4", "value4"));
Assert.assertEquals(expected, listOfLists);
}
public ImmutableList<String> pairToList(Pair<String, String> pair)
{
return Lists.immutable.with(pair.getOne(), pair.getTwo());
}
我将内部映射初始化为SortedMap
s,以保证测试中调用Assert.assertEquals
时密钥的顺序。我上面使用的接口类型来自Eclipse Collections,并扩展了JDK接口类型(例如MutableMap扩展了Map,MutableList扩展了List(,但您也可以使用带有静态实用程序的JDK类型,如下所示:
@Test
public void jdkMapOfMapsToListOfLists()
{
Map<Long, Map<String, String>> map = Maps.mutable.with(
1L, SortedMaps.mutable.with("key1", "value1", "key2", "value2"),
2L, SortedMaps.mutable.with("key3", "value3", "key4", "value4"));
List<List<String>> listOfLists = MapIterate.collect(map,
innerMap -> Iterate.flatCollect(
innerMap.entrySet(),
this::entryToList,
new ArrayList<>()));
List<List<String>> expected = Arrays.asList(
Arrays.asList("key1", "value1", "key2", "value2"),
Arrays.asList("key3", "value3", "key4", "value4"));
Assert.assertEquals(expected, listOfLists);
}
public List<String> entryToList(Map.Entry<String, String> entry)
{
return Arrays.asList(entry.getKey(), entry.getValue());
}
注意:我是Eclipse Collections 的提交人