Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中从哈希映射中获取所有最小值_Java_Hashmap - Fatal编程技术网

如何在Java中从哈希映射中获取所有最小值

如何在Java中从哈希映射中获取所有最小值,java,hashmap,Java,Hashmap,我有一个哈希映射,其中包含Request类型的key对象和Integer类型的值。我使用下面的代码遍历映射,获得所有最小值,然后将它们的键添加到列表中。我向所有人强调,因为键是唯一的,但值可以重复,因此可能有多个具有最小值的贴图元素 然而,这段代码只给了我一个这样的元素,即它通过迭代找到的第一个元素,尽管我知道还有更多。例如,让我们假设map有以下请求-即key(我给出请求id):3 | 5 | 2,它们各自的值是:8 | 4 | 4。因此,在本例中,我们有两个最小元素,即共享最小值的两个元素,

我有一个哈希映射,其中包含Request类型的key对象和Integer类型的值。我使用下面的代码遍历映射,获得所有最小值,然后将它们的键添加到列表中。我向所有人强调,因为键是唯一的,但值可以重复,因此可能有多个具有最小值的贴图元素

然而,这段代码只给了我一个这样的元素,即它通过迭代找到的第一个元素,尽管我知道还有更多。例如,让我们假设map有以下请求-即key(我给出请求id):3 | 5 | 2,它们各自的值是:8 | 4 | 4。因此,在本例中,我们有两个最小元素,即共享最小值的两个元素,ID5和ID2,两者的值均为4。代码将只向我的列表中添加ID为5的元素,即第一个元素

我必须注意,有一个类似的线程(),但提供的解决方案在我的情况下不起作用

代码如下:

 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());

      }
Entry min=null;
List minKeyList=new ArrayList();
for(条目:this.map.entrySet()){
如果(min==null | | min.getValue()>map.getValue()){
最小值=输入;
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());

       }

    }
//查找最小值的列表
List minValList=new ArrayList();
//用于保留具有最小值的元素键的列表
List minKeyList=new ArrayList();
//扫描地图并将值放入值列表
for(条目:this.map.entrySet()){
添加(entry.getValue());
}
//浏览地图
for(条目:this.map.entrySet()){
//找到最小值
if(entry.getValue()==Collections.min(minValList)){
//在键列表中添加具有最小值的元素键
add(entry.getKey());
}
}
我建议您采用两步流程:

  • 找到最小值,存储在
    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());
        }
    }
    
    //首先查找最小值
    int min=Integer.min\u值;
    for(条目:this.map.entrySet()){
    min=Math.min(min,map.getValue())
    }
    //添加值等于min的所有元素
    List minKeyList=new ArrayList();
    for(条目:this.map.entrySet()){
    if(min.getValue()==min){
    add(entry.getKey());
    }
    }
    
    正如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);
        }
    }
    
    对我来说似乎是对的。
    如果这没有帮助,请尝试发布更多的代码。

    您可以通过使用两个列表/集合来避免多个循环,例如

    循环开始前

        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());
        }
    }
    
    Set setExisting=new HashSet();
    Map keyMap=newhashmap();
    //先找到最小值
    int min=Integer.min_VALUE;`在这里输入代码`
    for(条目:this.map.entrySet()){
    Set newSet=newhashset();
    min=Math.min(min,map.getValue());
    newSet.add(map.getValue(min));
    关键字映射。put(min,newSet);
    if(min==map.getValue()){
    setExisting=(Set)keyMap.get(newSet);
    setExisting.add(map.getValue(min));
    keyMap.put(最小值,设置现有值);
    }
    }
    //在这种情况下,我们不需要下面的循环
    //添加值等于min的所有元素
    List minKeyList=new ArrayList();
    for(条目:this.map.entrySet()){
    if(min.getValue()==min){
    add(entry.getKey());
    }
    }
    
    @MatthiasMeid:从>到>=的更改很有效!非常感谢!!!请参阅我的更新答案和我对Padrus答案的评论;我的第一个方法有一个错误-请记住在问题解决后立即将答案标记为可接受的答案。@MatthiasMeid:感谢您的更新。我测试了两个建议的解决方案,但是t我仍然有一些问题。我将对代码进行更多的测试,并发布更新,或者是解决方案(希望如此)或者与代码的结果行为有关。我的第一种方法不够好,我将其改为两步过程,我认为这是避免由于局部极小值而得到错误结果所必需的。假设您有一个类似
    5,5,4,4
    的列表。我首先发布的代码将使用
    5
    4
    作为最小值m、 更新了我的答案。事实上,这就是为什么我添加了
    if(min.getValue()>map.getValue()){minKeyList.clear();}
    是的,我只是想强调使用
    =
    而不是像我第一次那样使用
    是不够好的,没有批评你的代码。@Padrus:谢谢你的回答。我使用了你的方法,但它没有如预期的那样起作用。下面是一个结果示例:我在映射中有以下元素:7 | 3 | 1,值为12 | 12 | 10列表包含所有三个元素,但它应该添加前两个元素,然后在发现第三个元素的值较低时,删除它们并添加第三个元素。也就是说,在最后,列表应该只包含元素1,因为它具有最小值(10)。我必须说,在外部if语句块结束后,我打印元素的值以及列表。@Padrus:如果我使用LinkedList代替ArrayList,我可以删除值为12的键,只保留值为10的键,参考前面的示例,对吗?我想是这样,但我不确定(我在ge编程方面是新手)
        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());
        }
    }