保留顺序收集到 Multimap 中
Collect into Multimap with order preserved
我有一个属性列表,如 attr1
、attr2
等。我还有一个函数接受一个属性和 returns 一个前缀列表。
private List<String> getAttributePrefixes(String attribute) {
//get prefix for attribute
}
我想创建一个映射,其键是前缀,值是属性。由于前缀可以重复,所以我想将结果输出为multimap。
因此,对于上面的示例,输出 Multimap 将如下所示:
{
a = [attr1, attr2],
at = [attr1, attr2],
att = [attr1, attr2],
attr = [attr1, attr2],
attr1 = [attr1],
attr2 = [attr2]
}
我的代码存在的问题是没有保留顺序。例如,我的地图中的条目如下所示:
a = attr2, attr1 (I call getAttributePrefixes function first for attr1 and then attr2)
我要 attr1
先到,然后 attr2
。这是我的代码:
Multimap<String, String> multimap = attributes.stream()
.map(attribute -> new AbstractMap.SimpleEntry<>(attribute, getAttributePrefixes(attribute)))
.flatMap(entry -> entry.getValue()
.stream()
.map(prefix -> new AbstractMap.SimpleEntry<>(prefix, entry.getKey())))
.collect(ImmutableListMultimap.toImmutableListMultimap(Map.Entry::getKey, Map.Entry::getValue));
主要问题是 stream
通常不提供或很少提供顺序保证,因为它是在考虑并行执行的情况下创建的。一个简单的选择是尝试 jOOλ
作为为单线程执行而实现的直接替换。它还为您的用例提供了一个不错的 groupBy
方法。
如果这不是 option/working,您必须手动执行分组才能获得排序。
Map<String, List<String>> multimap = attributes.stream()
.map(attribute -> new AbstractMap.SimpleEntry<>(attribute, getAttributePrefixes(attribute)))
.flatMap(entry -> entry.getValue()
.stream()
.map(prefix -> new AbstractMap.SimpleEntry<>(prefix, entry.getKey())))
.collect(Collectors.groupingBy(Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
groupingBy
是一个非并行收集器,所以它应该可以工作。不过,您需要将给定的地图包装成多重地图。
我有一个属性列表,如 attr1
、attr2
等。我还有一个函数接受一个属性和 returns 一个前缀列表。
private List<String> getAttributePrefixes(String attribute) {
//get prefix for attribute
}
我想创建一个映射,其键是前缀,值是属性。由于前缀可以重复,所以我想将结果输出为multimap。
因此,对于上面的示例,输出 Multimap 将如下所示:
{
a = [attr1, attr2],
at = [attr1, attr2],
att = [attr1, attr2],
attr = [attr1, attr2],
attr1 = [attr1],
attr2 = [attr2]
}
我的代码存在的问题是没有保留顺序。例如,我的地图中的条目如下所示:
a = attr2, attr1 (I call getAttributePrefixes function first for attr1 and then attr2)
我要 attr1
先到,然后 attr2
。这是我的代码:
Multimap<String, String> multimap = attributes.stream()
.map(attribute -> new AbstractMap.SimpleEntry<>(attribute, getAttributePrefixes(attribute)))
.flatMap(entry -> entry.getValue()
.stream()
.map(prefix -> new AbstractMap.SimpleEntry<>(prefix, entry.getKey())))
.collect(ImmutableListMultimap.toImmutableListMultimap(Map.Entry::getKey, Map.Entry::getValue));
主要问题是 stream
通常不提供或很少提供顺序保证,因为它是在考虑并行执行的情况下创建的。一个简单的选择是尝试 jOOλ
作为为单线程执行而实现的直接替换。它还为您的用例提供了一个不错的 groupBy
方法。
如果这不是 option/working,您必须手动执行分组才能获得排序。
Map<String, List<String>> multimap = attributes.stream()
.map(attribute -> new AbstractMap.SimpleEntry<>(attribute, getAttributePrefixes(attribute)))
.flatMap(entry -> entry.getValue()
.stream()
.map(prefix -> new AbstractMap.SimpleEntry<>(prefix, entry.getKey())))
.collect(Collectors.groupingBy(Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
groupingBy
是一个非并行收集器,所以它应该可以工作。不过,您需要将给定的地图包装成多重地图。