当使用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)
答案 0 :(得分:3)
执行此操作时:
integ=2;
strng="Bye";
您只更改了对象的引用而不是对象本身。
Integer
和String
您无法更改对象immutable
所以如果你想改变地图中的值,那么解决方案就是:
答案 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中。
我希望它有所帮助。