在HashMap中存储多个类型对象并检索它们

时间:2015-10-01 11:19:50

标签: java dictionary hashmap

当使用Object作为类型时,我很难理解HashMap。

这里我创建了两个对象,一个字符串和一个整数,我为其赋值。然后我将这些对象添加到HashMap中。然后更改字符串和整数对象的值。但是当尝试使用HashMap.get()引用它们时,它会显示原始值。

我假设以某种方式将值放在HashMap上创建一个新的未更改对象是在HashMap实例中创建的,而不是链接底​​层原始对象?

以下是代码:

import java.util.HashMap;
import java.util.Map;
public class Test1 {
    //Create objects
    static int integ=1;
    static String strng="Hi";
    //Create HashMap
    static Map<String, Object> objMap = new HashMap(); //Map of shipments
    public static void main(String[] args) {
        //Insert objects in HashMap
        objMap.put("integer", integ);
        objMap.put("string", strng);
        //Check the values
        System.out.println(objMap.get("integer"));
        System.out.println(objMap.get("string"));
        //Change values of underlying object
        integ=2;
        strng="Bye";
        //Check values again
        System.out.println(objMap.get("integer"));
        System.out.println(objMap.get("string"));
    }
}

输出:

debug:
1
Hi
BUILD SUCCESSFUL (total time: 8 seconds)

6 个答案:

答案 0 :(得分:3)

执行此操作时:

    integ=2;
    strng="Bye";

您只更改了对象的引用而不是对象本身。

IntegerString您无法更改对象immutable

所以如果你想改变地图中的值,那么解决方案就是:

  1. 从地图中删除以前的值。
  2. 更改值
  3. 将它们添加到您的地图

答案 1 :(得分:2)

您已修改了这些值,但尚未将它们放回HashMap。

    integ=2;
    strng="Bye";
    objMap.put("integer", integ);
    objMap.put("string", strng);

我认为,您假设哈希映射将引用修改后的值。但它不会那样工作,在这种情况下,因为你正在存储基元。如果你将灵长类动物包裹在物体内,你的假设将会很好。

即。

  public class MyClass{
     int integ;
  }

答案 2 :(得分:2)

您需要再次输入值,以便在重新从地图获取之前覆盖现有值。

SELECT customer_no
     , SUM(`balance_due`)
     , MONTH(`transaction_date`) 
  FROM customers 
 WHERE customer_no = 'DCD017'
   AND `transaction_date` BETWEEN ( DATE_FORMAT(NOW() ,'%Y-%m-01') -interval 1 month) AND LAST_DAY(NOW() )  
 GROUP 
    BY MONTH(`transaction_date`)

答案 3 :(得分:2)

我认为您需要检查Java基础知识,因为参数碰巧在Java中“按值传递”。

这意味着objMap.put("integer", integ);将存储在地图中,在关键字“整数”下的值为integ

在此操作之后更改积分值将不会影响地图中存储的内容,因为地图在.put()操作时包含对象的精确副本。

这种方法与“按引用传递”相反,其中地图将包含“指向”变量integ的“指针”。

答案 4 :(得分:2)

你正在做一些混乱。看看这段代码:

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

import org.junit.Before;
import org.junit.Test;

// Comment 0)
public class Test1 {
    Map<String, Object> objMap = new HashMap<>();

    private Integer integ = 1;
    private String strng = "Hi";

    // Comment 1)
    // private final Integer integ = 1;
    // private final String strng = "Hi";

    // Comment 2)
    final AtomicInteger integMutable = new AtomicInteger(1);
    final AtomicReference<String> strngMutable = new AtomicReference<>("Hi");

    @Before
    public void setup() {
        objMap.put("integer", integ);
        objMap.put("string", strng);
        objMap.put("integer2", integMutable);
        objMap.put("string2", strngMutable);
    }

    @Test
    public void test32886291() {
        // Comment 1: error raised if fields were final
        integ = 2;
        strng = "Bye";
        assertNotEquals(2, objMap.get("integer"));
        assertNotEquals("Bye", objMap.get("string"));

        integMutable.set(2);
        strngMutable.set("Bye");
        assertEquals(2, ((AtomicInteger) objMap.get("integer2")).intValue());
        assertEquals("Bye", objMap.get("string2").toString());
    }
}

评论0)首先,我转过你的&#34;测试&#34;使用JUnit将类转换为真正的测试类。

评论1)你似乎对&#34; field&#34;,&#34; reference&#34;,&#34; value&#34;和&#34; autoboxing&#34;概念。在地图中,您通过引用存储对象(这是您想要的)。 这就是为什么我第一次用int(一个对象)替换你的Integer(原始类型)。

执行integ = 2时,您不会更改该对象的值:您正在重新分配名为&#34; integ&#34;的字段。添加&#34; final&#34;关键字会引发错误(&#34;最终字段Test1.integ无法分配&#34;)并突出显示该点。 因此,更改字段值(为其指定另一个对象)对存储在地图中的对象没有影响。这是由两个assertNotEquals句子证实的。

注释2)无法更改Integer和String的值,它们是&#34; immutable&#34;。我用&#34; mutable&#34;替换了它们。对象分别包装一个int值和一个String。预期的行为由两个assertEquals句子确认。

答案 5 :(得分:1)

Java在此示例中使用call-by-value,因此它仅存储HashMap中的实际值而不是引用。因此,如果您更改了值,则应将其重新放入HashMap中。

我希望它有所帮助。