基于密钥类型中字段的相等性从Java HashMap中提取条目

时间:2012-08-17 19:07:58

标签: java hashmap

我有一个类型为<MyType,Double>的Java HashMap。 MyType类有两个字段foo(String类型)和bar(Double类型)。 MyType的等号和哈希码方法仅使用foo。现在给定类型为A的对象MyType,我需要从Hashmap获取匹配条目。这意味着什么

MyType A = new MyType();
A.foo = "foo";
A.bar = 0.0;

MyType B = new MyType();
B.foo = "foo";
B.bar = 1.0;

Map<MyType,Double> myMap = new HashMap<MyType,Double>();
myMap.put(B,5.0)

我需要从B中提取密钥myMap(最终是其条形值),因为它与A相等(因为它们的foo值相同)即形式的功能

Double getBar(MyType type,  Map<MyType,Double> map)

这样

getBar(A,myMap) returns 1.0 

最好的方法是什么?我不太确定这个东西是如何设计的,但我正在寻找一种有效的方法,因为myMap预计会非常庞大​​。

更新:这里有一个稍微大一点的背景。我有一组MyType对象(比方说S)。外部函数对其起作用并创建一个名为myMap的HashMap,它计算并将一个Double类型的数量与集合中的每个对象相关联。它还会更新集合中每个对象的bar字段。我得到的是myMap。现在我需要更新原始集合S中的每个元素,以便每个元素的条形值被返回的myMap中相应条目的条形值替换。因此,对于S中的每个A,我需要在myMap中读取相应的B,得到它的条,然后将A的条设置为与B的条相同。

3 个答案:

答案 0 :(得分:2)

如果您需要按Whatever查找Foo,则必须使用Map<Foo, Whatever>。其他任何东西,充其量都是试图将Map之内的东西推入Map的黑客攻击。

但问题是,Map界面的设计并非按照您尝试使用它的方式使用。这意味着仅根据您输入的查找。您可以强制它以这种方式工作,但最多你最终会有一个难以维护的,笨拙的黑客,这可能比开始正确做事更困难。

对于包含Map<String, MyTypeAndDouble>MyType的自定义类,您看起来应该使用Double

答案 1 :(得分:0)

如果您根据hashCode(这表明您正在做的事情)执行equalsfoo,那么在您的示例中A和{{1}最终会在hashmap的同一个桶中结束 因此,B会返回getBar(A,myMap);,因为这是您在地图中添加的内容 - 5.0。 我的意思是您可以使用B搜索B,但之后每个A都会替换之前的put,我不确定您的实际需求是什么

更新:

Double getBar(MyType type,  Map<MyType,Double> map){  
    if(map.containsKey(type)){   
         for(MyType k:map.keySet()){  
              if(k.equals(type)){  
                 return k.bar;  
              }
         }
    }
    return -1.0;
}

更新2:
您似乎需要一种直接访问Map中密钥的方法。您可以使用以下操作:
定义:

class Holder{  
    MyType type;  
    Double value;  
}

并改为HashMap<MyType,Holder>。因此,在进行计算的方法中,您更新地图以将结果添加到Holder对象中,同时存储type。即而不是myMap.put(B,5.0);myMap.put(B,new Holder(B,5.0));

所以你会:

Double getBar(MyType type,  Map<MyType,Holder> map){   
     return map.get(type).type.bar;    
}    

您还需要额外的空间来存储type作为地图值的一部分,但是您将摆脱实际找到type的循环,因为它现在

答案 2 :(得分:0)

嗯,这不是很漂亮,需要迭代Map,但它应该让你在你描述的场景中达到bar的值。 (这假设你的equals()方法与你描述的一样,仅查看foo的值以确定对象相等性。)

public Double getBar(MyType type,  Map<MyType,Double> map) {
  for (MyType entry : map.keySet()) {  
    if (entry.equals(type)) {
      return entry.getBar(); // or whatever your accessor is for bar
    } 
  }
  return null;  // or whatever value you want to return if it doesn't find a key
}