午夜java男说的对,
java 中引用的概念一直贯穿他的核心,在java中实例化的类我们称作对象或是对象实例,虽说是实例但是用起来却不简单,因为我们无法直接操作他的值,而要通过“引用”也就是我们声明的变量(或是字段)来操作具体的实例。而这个引用不是一个抽象的概念他是实实在在的值存于内存中(虚拟机栈中)。在现实的操作中其实是对这些栈中的引用值得使用。
Collection等的集合记录的值也不例外。
c.add(new Name("f1","l1"));中的new Name("f1","l1")对象我们记做s1 .
c.remove(new Name("f1","l1"))中的new Name("f1","l1")对象我im记做s2
此时System.out.println(s1==s2)
或是
System.out.println(new Name("f1","l1")==new Name("f1","l1"))
的输出结果都为为false.
因为s1与s2是不同的引用,也就是说他们是不同的,而他们间相同的只是他们中字段的值。
故建议使用午夜java男说的方法
//***********************改动************************//
楼主很厉害啊(没有贬义)。。呵呵。。
覆写了Name类的hashCode() 或是equals()方法,结果就大不一样了。
public int hashCode() {
return firstName.hashCode();
}
之所以说楼主厉害在于
上面的问题本来是没有问题的。而且我在这承认这不能直接用引用的概念解决这个题,(我对刚才的草率回答表示歉意)。
在java中HashSet()、HashMap()、Hashtable()等调用remove()方法不是简单的引用而是要通过一定的计算来判断要remove的值s是否在集合中。这里就要调用s的hashCode() 和equals()方法,
如果集合中的某个记录值hashCode() 方法后返回的值与s调用hashCode()后返回值相同则可以删除 或是调用equals()返回值相同也可以删除。
你这里都是两个新的对象。
c.add(new Name("f1","l1"));
c.remove(new Name("f1","l1"))
你只是分别实例化了两个不同但是属性相同的对象而已,所以去不掉的,你可以试试看
Name name1 = new Name("f1","l1");
c.add(name1);
c.remove(name1);
看看可不可以;
###################改动#######################
经过我运行之后发现确实是去除了的,原因应该是虫子异族说的那样在java中HashSet()、HashMap()、Hashtable()等调用remove()方法会调用equals方法来比较两个对象是否相等。由于楼主已经重写了eq方法了使用firstName来作为对象是否相同的的条件,所以这样写应该是正确的!
真心感谢虫子让我对这个方法有了更深的认识!!!
你好,我运行了你的程序,发现你说的(new Name("f1","l1"))已经去掉
一看就知道不错,对象和对象的值,以及引用的核心机制(你可以想象成对象以及值存在于内存中的那种模式),这些都是Java处理各种变量和值传递的麻烦地方啊,特别是在各种List或者对象之间的来回传递。
楼主例子不错!
根据上面几位,我就补充一点点,弄懂堆栈问题 就明白了
都用new的话,就分别是两个新对象了,指向的地址不是同一个,所以删除不掉