我有一个哈希映射,其中包含Request类型的Keys对象和Integer类型的值。我使用以下代码迭代地图并获取所有最小值,然后将其键添加到列表中。我强调所有因为键是唯一的但值可以是重复的,因此可能有多个具有最小值的地图元素。
然而,这段代码只给了我一个这样的元素,也就是它通过迭代找到的第一个元素,即使我知道还有更多。例如,让我们说地图有以下请求 - 即密钥(我给出请求ID):3 | 5 | 2和它们各自的值是:8 | 4 |因此,在这个例子中,我们有两个最小元素,即两个共享最小值的元素,ID 5和ID 2,两者都是值4.代码将只向我的列表中添加ID为5的元素,即是,他们中的第一个。
我必须注意有一个类似的线程(Key for maximum value in Hashtable),但提供的解决方案在我的情况下不起作用。
以下是代码:
Entry<Request, Integer> min = null;
List<Request> minKeyList = new ArrayList<Request>();
for(Entry<Request, Integer> entry : this.map.entrySet()) {
if (min == null || min.getValue() > map.getValue()) {
min = entry;
minKeyList.add(entry.getKey());
}
任何建议或解释为什么会发生这种情况将不胜感激。
编辑:新方法
好吧,我找到了解决方案。它不优雅,但它的工作原理。这是代码。
// list for finding the min value
List<Integer> minValList = new ArrayList<Integer>();
// List for keeping the keys of the elements with the min value
List<Request> minKeyList = new ArrayList<Request>();
// scan the map and put the values to the value list
for(Entry<Request, Integer> entry : this.map.entrySet()) {
minValList.add(entry.getValue());
}
// scan the map
for(Entry<Request, Integer> entry: this.map.entrySet()) {
// find the min value
if(entry.getValue() == Collections.min(minValList)) {
// add the keys of the elements with the min value at the keyList
minKeyList.add(entry.getKey());
}
}
答案 0 :(得分:4)
我建议您进行两步流程:
min
min
以下是代码示例:
// find minimum first
int min = Integer.MIN_VALUE;
for(Entry<Request, Integer> entry : this.map.entrySet()) {
min = Math.min(min, map.getValue())
}
// add all elements that have a value equal to min
List<Request> minKeyList = new ArrayList<Request>();
for(Entry<Request, Integer> entry : this.map.entrySet()) {
if(min.getValue() == min) {
minKeyList.add(entry.getKey());
}
}
答案 1 :(得分:1)
Matthias Meid说,你必须使用>=
代替>
。
另外,如果认为你应该有这样的东西,或者你的minKeyList将包含min
已经拥有的所有值。
if(min == null || min.getValue() >= map.getValue()) {
if(min == null || min.getValue() > map.getValue()){
min = entry;
minKeyList.clear();
}
minKeyList.add(entry.getKey());
}
修改:经过测试的代码
我用一些示例代码测试了这个方法,它似乎正常工作。
以下是我用来测试它的代码:
public static void main(String[] args) {
HashMap<Integer, Integer> map = new HashMap<>();
map.put(7, 12);
map.put(3, 3);
map.put(1, 10);
map.put(4, 12);
map.put(6, 3);
map.put(8, 3);
map.put(9, 13);
Entry<Integer, Integer> min = null;
List<Integer> minKeyList = new ArrayList<Integer>();
for(Entry<Integer, Integer> entry : map.entrySet()) {
if (min == null || min.getValue() >= entry.getValue()) {
if(min == null || min.getValue() > entry.getValue()){
min = entry;
minKeyList.clear();
}
minKeyList.add(entry.getKey());
}
}
for (Integer integer : minKeyList) {
System.out.println(integer);
}
}
为了简化我的测试,键和值都是整数,但它不应该改变任何东西。
这不是我的输出:
3
6
8
对我来说似乎是对的。 如果这没有帮助,请尝试发布更多代码。
答案 2 :(得分:1)
您可以使用2个列表/集来避免多个循环,例如
在循环开始之前
Set setExisting = new HashSet();
Map keyMap = new HashMap();
// find minimum first
int min = Integer.MIN_VALUE;`enter code here`
for(Entry<Request, Integer> entry : this.map.entrySet()) {
Set newSet= new HashSet<String>();
min = Math.min(min, map.getValue());
newSet.add(map.getValue(min));
keyMap.put(min,newSet);
if (min==map.getValue()){
setExisting = (Set) keyMap.get(newSet);
setExisting.add(map.getValue(min));
keyMap.put(min,setExisting);
}
}
// We will NOT need the below loop in that case
// add all elements that have a value equal to min
List<Request> minKeyList = new ArrayList<Request>();
for(Entry<Request, Integer> entry : this.map.entrySet()) {
if(min.getValue() == min) {
minKeyList.add(entry.getKey());
}
}