关于Java中的List容器的remove注意细节

第一次发布地址:http://258516630.ddjava.com/blog/blog.html?blogId=437


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



下面进入主餐:


我整理下这位提问人的问题:
就是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]
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值