2014-09-24 98 views
1

我得到了下面的函數獲取地圖的價值如何從一個關鍵這是一個POJO

Map<MyClass, String> someFunction() { 
    Map<MyClass, String> result = new HashMap<>(); 
    return result.put(new MyClass("someString"), "someOtherString")); 
} 

的MyClass實現如下所示:

public class MyClass{ 

    String string; 

    public MyClass(String string) { 
     this.string = string; 
    } 

    public void setString(String string) { 
     this.string = string; 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((string== null) ? 0 : string.hashCode()); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
      return true; 
     } 
     if (obj == null) { 
      return false; 
     } 
     if (getClass() != obj.getClass()) { 
      return false; 
     } 
     MyClass other = (MyClass) obj; 
     if (string== null) { 
      if (other.string!= null) { 
       return false; 
      } 
     } else if (!string.equals(other.string)) { 
      return false; 
     } 
     return true; 
    } 

} 

在我的測試我我正在做以下操作:

@Test 
public void test() { 
    Map<MyClass, String> outcome = classUnderTest.someFunction(); 

    assertThat(outcome.get(new MyClass("someString")), is("someOtherString")); 
} 

但是,此測試失敗,因爲實際爲空。 如果我嘗試以下方法:

assertThat(outcome.keySet(), hasItem(MY_CLASS)); 

這也失敗了,告訴我,這些是不同的intantiations。我甚至試圖調試我的測試,但它永遠不會達到equals方法。你能告訴我這裏發生了什麼嗎?

+0

你使用的是什麼版本的junit? – Eben 2014-09-24 10:48:39

+0

目前我使用的版本是4.11 – Chris311 2014-09-24 13:55:31

回答

0

你確定,你的方法不修改對象嗎?我認爲someFunction取代MyClass中的string。這會導致MyClass的對象返回另一個hashCode。

一個HashMap作品那樣:

地說:

  • 計算的關鍵hashCode。關鍵的

    • 計算hashCode:是的hashCode

    下得儲值。用該hashCode搜索一個值。如果有價值,那麼可以致電equals

所以:從不使用可變值作爲鍵!否則,你可能會失去你的數據(或使其難以解決)

只是嘗試執行這個測試中,它應該是綠色的

import static org.hamcrest.Matchers.is; 
import static org.junit.Assert.assertThat; 

import java.util.HashMap; 
import java.util.Map; 

import org.junit.Test; 

public class SomeTest { 

    Map<MyClass, String> someFunction() { 
     Map<MyClass, String> result = new HashMap<>(); 
     result.put(new MyClass("someString"), "someOtherString"); 
     return result; 
    } 

    @Test 
    public void test() { 
     Map<MyClass, String> outcome = someFunction(); 

     assertThat(outcome.get(new MyClass("someString")), is("someOtherString")); 
    } 

    public static class MyClass { 

     String string; 

     public MyClass(String string) { 
      this.string = string; 
     } 

     public void setString(String string) { 
      this.string = string; 
     } 

     @Override 
     public int hashCode() { 
      final int prime = 31; 
      int result = 1; 
      result = prime * result + ((string == null) ? 0 : string.hashCode()); 
      return result; 
     } 

     @Override 
     public boolean equals(Object obj) { 
      if (this == obj) { 
       return true; 
      } 
      if (obj == null) { 
       return false; 
      } 
      if (getClass() != obj.getClass()) { 
       return false; 
      } 
      MyClass other = (MyClass) obj; 
      if (string == null) { 
       if (other.string != null) { 
        return false; 
       } 
      } else if (!string.equals(other.string)) { 
       return false; 
      } 
      return true; 
     } 

    } 
} 

,但如果你修改MyClass對象時,它被添加到Map後,測試變爲紅色:

Map<MyClass, String> someFunction() { 
    Map<MyClass, String> result = new HashMap<>(); 
    MyClass key = new MyClass("someOldString"); 
    result.put(key, "someOtherString"); 
    key.setString("someString"); 
    return result; 
} 
+0

其實我不知道這個問題來自哪裏。它太長了,我甚至不知道上下文了。我猜你的答案會打回家,所以我將其標記爲解決方案。 – Chris311 2016-12-08 10:39:03

0

在你的函數要返回null

從JavaDoc中的HashMap:

公共五世說(K鍵,V值)

Associates the specified value with the specified key in this map. If the map previously contained a mapping for the key, the old value is replaced. 

Specified by: 
    put in interface Map<K,V> 
Overrides: 
    put in class AbstractMap<K,V> 
Parameters: 
    key - key with which the specified value is to be associated 
    value - value to be associated with the specified key 
Returns: 
    the previous value associated with key, or null if there was no mapping for key. (A null return can also indicate that the map previously associated null with key.) 

的put()返回曾經在那裏,不是你剛剛放在那裏