这个问题,自己在平时中并未遇见,但是有人问了这个问题后,自己加以思考,整理出来自己的思路来解答,并看了底层的代码加以证明。现在和大家分享下,本人只是抛砖引玉,希望能和更多热爱技术的猿猿一起思考探索下技术。欢迎拍砖,发表不同的想法,也欢迎有猿猿对底层这些实现思维交流交流。如果是我们自己设计这些东西,我们会不会有更好的逻辑去实现,如果没有,它这种底层实现为什么好?

下面进入主餐:

我整理下这位提问人的问题:

就是List容器中添加一个new出来的对象,然后为什么在remove点一个新构造出来的一摸一样的对象,总是不能成功remove掉它。

具体问题代码如下:

[code] 
 package javaFile;  
 public class Name {  
 private String fistName ,lastName;//fiseName姓 lastName名  
 Name(String fistName ,String lastName){  
 this.fistName =fistName;  
 this.lastName=lastName;  
 }  
 public String getfistName(){  
 return fistName;  
 }  
 public String getlastName(){  
 return lastName;  
 }  
 public String getToString(){  
 return fistName + lastName;  
 }  
 //重写equals的方法  
 public boolean equalse(Object obj){  
 if(obj instanceof Name){//如果这个boj输入这个Name对象  
 Name name =(Name)obj ;  
 return (fistName.equals(name.fistName))  
 && (lastName.equals(name.lastName));  
 }  
 return super.equals(obj);  
 }  
 public int hashCoed(){  
 return fistName.hashCode();  
 }  
 package javaFile;  
 import java.rmi.Naming;  
 import java.util.*;  
 public class Testconllenction {  
 public static void main(String[] args) {  
 Collection c = new HashSet();//new 一个ArrayListd对象其实是父类指向子类对象  
 //想list里面放东西  
 //Name a = new Name("f","ff");  
 c.add("Hello");  
 c.add(new String("fafas"));  
 c.add(new Name("f1" ,"f2"));  
 c.add(new Integer(100));  
 c.remove(new String("fafas"));//除非是内部类才可以删除否则要进行equals对比  
 c.remove(new Name("f1" ,"f2"));//问题在这里啊看清粗啊运行的时候?????????????????????????  
 c.remove(new Integer(100) );  
 c.remove("Hello");//remove 是删除的意思  
 System.out.println(c.remove(new Name("f1","f2")));//false 去不掉  
 //原因 :没有重写equals 方法 比较两个对像是否相等是要重写equals的方法  
 // 在用到Map 里面进行对比会用hashCored进行对比原因是效率更高  
 System.out.println(c.size());  
 System.out.println(c);  
 //System.out.println(a.toString());  
 }  
 }  
 [/code]

我看到这个问题后的理解是:

1.list容器中add方法中的对象的内存地址是为aaaa(假定,可以是任意的内存地址值),但是remove方法中的对象,虽然是和add方法中的对象值是一样的,看起来是一个同一个对象,但其实它们是不同的对象。

举个通俗易懂的现实例子来说明吧。

一、在一个小区里,2号楼202室的房间布局、家具以及住的人是和3号楼202室一模一样的,但是这两个房屋的地址是不一样,所以它们是不同的房子。

二、当你聘请拆迁队要拆迁掉你在2号楼202室的房子,你带他去3号楼202室的房屋,它肯定不会拆的,它会给你报提示,这不是你要求我们要拆的房子。

三、因为名单上的地址和带到拆除房屋的地址不相同。

类比:

①拆迁队==List容器

②2号楼202室 == add方法里new出来的对对象

③add(new Objeact()) == 给它2号楼202室的地址的房子

④3号楼202室 == remove方法里new出来的对象

⑤remove(new Object()) == 带它去的3号楼202室的地址的房子

这是我能最快想到一个能用类似的实际例子说明的。可能,现实中拆迁队不会这么迂腐,但是机器就是这么忠贞不二的去执行既定的规则。如果非要和我争论拆迁队肯定二话不说拆除3号楼202室的房子的同学轻绕道,谢谢。

以下是我看java提供的底层代码,来佐证我的理解:

1. java.util.HashSet 

HashSet.remove(Object o)  
 [code] 
 public boolean remove(Object obj)   
     {   
         return map.remove(obj) == PRESENT;//这里的map.remove指向2的remove   
     }  
 [/code]

2. java.util.HashMap

[code] 
 public Object remove(Object obj)   
     {   
         Entry entry = removeEntryForKey(obj);//这里的removeEntryForKey方法来源于3   
         return entry != null ? entry.value : null;   
     }  
 [/code]

3.java.util.HashMap

[code] 
 final Entry removeEntryForKey(Object obj)   
     {   
         int i = obj != null ? hash(obj.hashCode()) : 0;//关键地方   
         int j = indexFor(i, table.length);   
         Entry entry = table[j];   
         Entry entry1;   
         Entry entry2;   
         for(entry1 = entry; entry1 != null; entry1 = entry2)   
         {   
             entry2 = entry1.next;   
             Object obj1;   
             if(entry1.hash == i && ((obj1 = entry1.key) == obj || obj != null && obj.equals(obj1)))   
             {   
                 modCount++;   
                 size--;   
                 if(entry == entry1)   
                     table[j] = entry2;   
                 else   
                     entry.next = entry2;   
                 entry1.recordRemoval(this);   
                 return entry1;   
             }   
             entry = entry1;   
         }   
    
         return entry1;   
     }   
 [/code]