Map 如何从POJO键获取映射的值

Map 如何从POJO键获取映射的值,map,equals,key-value,hashcode,pojo,Map,Equals,Key Value,Hashcode,Pojo,我得到了以下函数 Map<MyClass, String> someFunction() { Map<MyClass, String> result = new HashMap<>(); return result.put(new MyClass("someString"), "someOtherString")); } 在我的测试中,我做了以下几点: public class MyClass{ String string;

我得到了以下函数

Map<MyClass, String> someFunction() {
    Map<MyClass, String> result = new HashMap<>();
    return result.put(new MyClass("someString"), "someOtherString"));
}
在我的测试中,我做了以下几点:

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

这也失败了,告诉我,这是不同的想法。我甚至试着调试我的测试,但它从未达到equals方法。您能告诉我这里发生了什么吗?

在您的函数中,您将返回
null

从JavaDoc for HashMap:

公共V输入(K键,V值)

将指定值与此映射中的指定键相关联。如果映射以前包含键的映射,则替换旧值。
指定人:
输入接口图
覆盖:
放入类抽象映射
参数:
key—与指定值关联的键
value—与指定键关联的值
返回:
与键关联的上一个值,如果键没有映射,则为null。(null返回值也可以表示映射以前与null键关联。)

put()返回以前在那里的内容,而不是刚才放在那里的内容

您确定您的方法不会修改对象吗?我认为,
someFunction
取代了
MyClass
中的
string
。这会导致
MyClass
的对象返回另一个hashCode

HashMap
的工作原理如下:

付诸表决:

  • 计算键的
    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;
        }

    }
}

你用的是什么版本的junit?目前我用的是4.11版,实际上我不知道这个问题是从哪里来的。时间太长了,我甚至都不知道它的来龙去脉。我想你的答案很中肯,所以我把它标为解决方案。
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;
        }

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