Java 在Hashmap中查找最大值并返回最小值键
我有一个整数数组,我想知道哪个数的重复次数比其他数多。如果我们有两个重复次数相同的数,我的程序应该返回带有最小索引的数 例如:我有一个数组列表,它保存在nums下面Java 在Hashmap中查找最大值并返回最小值键,java,hashmap,Java,Hashmap,我有一个整数数组,我想知道哪个数的重复次数比其他数多。如果我们有两个重复次数相同的数,我的程序应该返回带有最小索引的数 例如:我有一个数组列表,它保存在nums下面 ArrayList<Integer> list = new ArrayList<>(); list.add(9); list.add(0); list.add(1); list.add(1); list.add(9); ArrayList list=new ArrayList(); 增加(9); 列表。添加
ArrayList<Integer> list = new ArrayList<>();
list.add(9);
list.add(0);
list.add(1);
list.add(1);
list.add(9);
ArrayList list=new ArrayList();
增加(9);
列表。添加(0);
增加第(1)款;
增加第(1)款;
增加(9);
所以我创建了Hashmap,将数字保存为键,将频率保存为值
HashMap<Integer, Integer> list1 = new HashMap<>();
for (int i = 0; i < list.size(); i++) {
list1.put(list.get(i), Collections.frequency(list, list.get(i)));
}
HashMap list1=newhashmap();
对于(int i=0;i
因为我有两个数字“1,9”,它们彼此重复“2次”
我的程序应该返回1,因为有最小索引。
那么,我如何在hashmap中定义最大值并返回最小索引呢?您需要使用
LinkedHashMap
来维护Map
中的插入顺序,然后您可以使用lambda对索引中的最大值进行索引,该值位于索引的第一位,如下所示:
List<Integer> list = new ArrayList<>();
list.add(9);
list.add(0);
list.add(1);
list.add(1);
list.add(9);
Map<Integer, Integer> map = new LinkedHashMap<>();
for (int i = 0; i < list.size(); i++) {
map.put(list.get(i), Collections.frequency(list, list.get(i)));
}
System.out.println(map);
System.out.println(Collections.max(map.entrySet(),
Comparator.comparingInt(entry -> entry.getValue())).getKey());
它将提供
1
作为输出。我建议使用groupingBy
收集器而不是frequency
,然后利用流API应用进一步的操作来优化查询
Optional<Integer> key = list.stream() // Stream<Integer>
.collect(groupingBy(Function.identity(), counting())) // Map<Integer, Long>
.entrySet().stream() //Stream<Entry<Integer, Long>>
.max(Comparator.comparingLong((ToLongFunction<Map.Entry<Integer, Long>>) Map.Entry::getValue)
.thenComparingInt(s -> -s.getKey())) // Optional<Entry<Integer, Long>> // Optional<Entry<Integer, Long>>
.map(Map.Entry::getKey); //Optional<Integer>
Optional key=list.stream()//流
.collect(groupingBy(Function.identity(),counting())//Map
.entrySet().stream()//流
.max(Comparator.comparingLong((ToLongFunction)Map.Entry::getValue)
.ThenComparingit(s->-s.getKey())//可选//可选
.map(map.Entry::getKey)//可选择的
- 将
收集器提供给groupingBy
方法,允许我们对源collect
列表中的每个元素进行分组,从而得到一个
映射,其中每个条目表示元素及其在源
列表中出现的次数
- 然后在Hashmap中找到最大值并返回最小键
- 最后,我们有一个
包含键,否则是空的Optional李>Optional
1
既然您提到列表中的数字代表索引,这就足够了
如果您不熟悉
可选的API,那么我建议您浏览文档。“因为我有两个数字“1,9”,它们彼此重复了“2次”,我的程序应该返回1,因为其中一个有最小索引”嗯?在索引0处有9个。没有比这更多的最低要求了。:-)通常,列表中的数字表示某种索引。您可以使用树集,因为我们可以按键的自然顺序遍历键。您的代码效率非常低-它在O(n^2)
时间内运行<代码>O(n)
是完全可能的stream()
List
然后groupingBy
使用counting()
。最后是stream()
映射.entries()和maxBy
Entry.getValue
然后是Entry.getKey
。您当前使用的哈希映射完全没有用,使事情变得更加困难。提示:不要使用Collections.frequency
。我想用户的意思是“索引”中的最低键。否则这个问题就没有意义了。@Boristespider是的,如果我们使用LinkedHashMap
,那么9
将是映射中的第一个键。因此,结果如下。是的。“我的程序应该返回1”9
不是1
@Boristespider那么它没有任何意义。无论如何,在这种情况下,我们需要使用SortedMap
而不是LinkedHashMap
同意。但我担心,通过假设问题是错误的来回答问题不是一种有效的方法。这个答案是错误的。
Optional<Integer> key = list.stream() // Stream<Integer>
.collect(groupingBy(Function.identity(), counting())) // Map<Integer, Long>
.entrySet().stream() //Stream<Entry<Integer, Long>>
.max(Comparator.comparingLong((ToLongFunction<Map.Entry<Integer, Long>>) Map.Entry::getValue)
.thenComparingInt(s -> -s.getKey())) // Optional<Entry<Integer, Long>> // Optional<Entry<Integer, Long>>
.map(Map.Entry::getKey); //Optional<Integer>