Java 列表在地图中给出<;关键,价值观>;作为值,如何找到一个或多个具有最大列表大小的键
我已经编写了一个返回映射的方法。 地图的结构如下:Java 列表在地图中给出<;关键,价值观>;作为值,如何找到一个或多个具有最大列表大小的键,java,performance,dictionary,iteration,java-streams,Java,Performance,Dictionary,Iteration,Java Streams,我已经编写了一个返回映射的方法。 地图的结构如下: Map<String, List<String>> map; Map; 地图可以包含1000多个键,每个键可以包含10000多个大小的列表。 我想得到那些具有最大列表大小的键。如果可能的话,有什么方法可以在最短的时间内得到结果吗?如果性能是一个优先事项,请忘记性能,使用本地方法,使用简单的for循环迭代 String maxKey; int maxSize = -1; for (Entry<String, L
Map<String, List<String>> map;
Map;
地图可以包含1000多个键,每个键可以包含10000多个大小的列表。
我想得到那些具有最大列表大小的键。如果可能的话,有什么方法可以在最短的时间内得到结果吗?如果性能是一个优先事项,请忘记性能,使用本地方法,使用简单的
for循环
迭代
String maxKey;
int maxSize = -1;
for (Entry<String, List<String>> list: map.entrySet()) {
int size = list.getValue().size();
if (size > maxSize) {
maxKey = list.getKey();
maxSize = size;
}
}
使用streams,您可以组合一个解决方案,迭代地图的所有条目,获取每个列表的大小,以最终提供具有“max”大小列表的键。或者你按照尼古拉斯回答中的建议,实施“老派”方法 问题是:如果您需要经常这样做,它仍然可能会变成一个性能问题。从这个角度来看,您应该问问自己,数据的这种“布局”是否真的是您所需要的 意思:你可以使用树形图,并给它一个特殊的比较器,而不是使用地图。然后,根据这些列表的长度对地图条目进行排序。然后你只需选择“第一个”条目,你就获得了赢家。这里的缺点是比较器只对进入映射的键起作用,因此您可能需要一些特殊的“包装类”,其中键知道列表大小。这很难看 或者,您可以创建一个特殊的“包装贴图”,该贴图内部包含两个贴图:
- 将列表大小映射到“真实”映射键的
TreeMap
- 保存实际数据的真实地图
Map <String, List<String>> map = new HashMap<>();
Map <String, List<String>> filteredMap = map.entrySet().stream()
.filter(stringListEntry -> stringListEntry.getValue().size() > 100)
.limit(10)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Map Map=newhashmap();
Map filteredMap=Map.entrySet().stream()
.filter(stringListEntry->stringListEntry.getValue().size()>100)
.限额(10)
.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
`按照值列表的大小对条目进行分组,数据结构可帮助您找到最大的键:
TreeMap<Integer, List<Entry<String, List<String>>>> collect =
map.entrySet().stream()
.collect(groupingBy(e -> e.getValue().size(), TreeMap::new, toList()));
当然,您也可以在不使用流的情况下执行此操作,并且不保留所有小于最大值的条目:
List<Map.Entry<String, List<String>>> largestEntries = new ArrayList<>();
// Don't need both this and largestEntries;
// just adding to show how you'd only get keys.
List<String> largestKeys = new ArrayList<>();
int largestSize = Integer.MIN_VALUE;
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
if (entry.getValue().size() > largestSize) {
largestEntries.clear();
largestEntries.add(entry);
largestKeys.add(entry.getKey());
largestSize = entry.getValue().size();
} else if (entry.getValue().size() == largestSize) {
largestEntries.add(entry);
largestKeys.add(entry.getKey());
}
}
List largestEntries=new ArrayList();
//不需要这个和最大的条目;
//只是增加一点来说明你是如何得到钥匙的。
List largestKeys=new ArrayList();
int largestSize=Integer.MIN_值;
对于(Map.Entry:Map.entrySet()){
if(entry.getValue().size()>largestSize){
最大的条目。清除();
最大条目。添加(条目);
添加(entry.getKey());
largestSize=entry.getValue().size();
}else if(entry.getValue().size()==largestSize){
最大条目。添加(条目);
添加(entry.getKey());
}
}
您仍然可以使用JavaSteam
API:
Map<String, List<Integer>> map = Map.of(
"a",List.of(1,2),
"b",List.of(3,4,5,6),
"c",List.of(7,8,9)
);
Map Map=Map.of(
“a”,第(1,2)项清单,
“b”,第(3,4,5,6)项清单,
“c”,第(7、8、9)项清单
);
具有最大列表大小的条目:
Optional<Map.Entry<String, List<Integer>>> max = map.entrySet()
.stream()
.max(Comparator.comparingInt(value -> value.getValue().size()));
Integer maxSize = max.get().getValue().size();
Map<String, List<Integer>> maxMap = map
.entrySet()
.stream()
.filter(entry -> entry.getValue().size() == maxSize)
.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
Optional max=map.entrySet()
.stream()
.max(Comparator.comparingit(value->value.getValue().size());
具有最大列表大小的条目的映射:
Optional<Map.Entry<String, List<Integer>>> max = map.entrySet()
.stream()
.max(Comparator.comparingInt(value -> value.getValue().size()));
Integer maxSize = max.get().getValue().size();
Map<String, List<Integer>> maxMap = map
.entrySet()
.stream()
.filter(entry -> entry.getValue().size() == maxSize)
.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
Integer maxSize=max.get().getValue().size();
maxMap=Map
.entrySet()
.stream()
.filter(条目->条目.getValue().size()==maxSize)
.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
最后,您可以在LinkedHashMap中对结果进行排序和存储:
LinkedHashMap<String, List<Integer>> sortedMap = map
.entrySet()
.stream()
.sorted(Comparator.comparingInt(value -> value.getValue().size()))
.collect(
Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(u, v) -> {
throw new IllegalStateException(String.format("Duplicate key %s", u));
},
LinkedHashMap::new
)
);
LinkedHashMap sortedMap=map
.entrySet()
.stream()
.sorted(Comparator.comparingit(value->value.getValue().size())
.收集(
汤姆(
Map.Entry::getKey,
Map.Entry::getValue,
(u,v)->{
抛出新的IllegalStateException(String.format(“重复键%s”,u));
},
LinkedHashMap::新建
)
);
要获取指向最大列表的一个键吗?是什么阻碍了您迭代映射并调用列表的.size()方法?只要比较一下这些,就可以了。如果性能是最重要的,那么就应该使用不同的数据结构。。。尽管如此,你还是得到了我的投票,因为我花了时间写下了一些代码。请注意,OP要求所有匹配列表最大的密钥。可能有多个键具有大小列表,例如15000。@GhostCat:这是一个很好的观点!我希望数据已经映射到Map
结构,所以我使用了它。当然,数据的来源很重要。“然后根据这些列表的长度对地图条目进行排序”树形图比较器对键进行排序,而不是条目或值。我不认为OP要求10个条目的地图大小大于100。OP要求所有匹配值最大的键。它足够接近,您可以使用上面的键来实现所需。您可以用maxSize替换100,这可以用类似的方法轻松计算,您也可以用fintFirst替换limit,这样您将经历两次。性能方面不是很好。大多数时候,你应该首先考虑可读性,如果没有问题,就不要担心性能