马士兵Java课堂笔记-6-容器Collection接口remove方法中判断是否相等并删除问题

容器Collection接口下面可以实现HashSet类,
在HashSet类中有add、remove等方法,
其中,
add方法可以往容器中添加元素,
而remove(“example”)可以从容器中删除内容为”example”的元素,
例如:
我们首先定义一个HashSet的对象,赋给Collection接口 c

Collection<Object> c = new HashSet<Object>();

这个语句需要说明一下,为什么要把HashSet的对象赋给Collection呢?
这是为了以后修改方便,
当我们需要把HashSet换成LinkedList的时候,
我们只需要将这条语句修改为下面这样就可以了:

Collection<Object> c = new LinkedList<Object>();

而不需要改后面的程序,因为这两种对象都属于Collection接口。

当定义完HashSet类后,
我们定义一个Name类,方便一会儿进行remove的方法比较,

class Name {
    private String firstName,lastName;
    public Name(String firstName,String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    /*
    public boolean equals(Object obj) {
        if(obj instanceof Name) {
            Name name = (Name)obj;
            return (firstName.equals(name.firstName)) 
            && lastName.equals(name.lastName);
        }
        return super.equals(obj);
    }

    public int hashCode() {
        return firstName.hashCode();
    }
    */
    public String getFirstName() {      return firstName;   }
    public String getLastName() {       return lastName;    }
    public String toString() {      return firstName +" "+ lastName;    }
}

我们可以通过add方法为 c 这个对象添加元素:

c.add("hello");
c.add(new Integer(100));
c.add(new Name("wang","gang"));

也可以使用remove方法来删除 c 这个对象中的对应元素:

c.remove("hello");
c.remove(new Integer(100));
c.remove(new Name("wang","gang"));

当我们用remove方法删除元素时,
程序会通过判断remove中的参数是否equals 对象 c 中的元素,
若有值相等的元素,则将其删除,
所以这三个remove语句中,
前两个会找到对应的元素并进行删除,
但是第三个语句则会返回false,

这是因为程序进行判断的时候会调用equals方法来查找相同的元素,
所以”hello”.equals(“hello”) 和 new Integer.equals(new Integer) 会找到对应的元素,

但是object的equals方法来判断new Name(“wang”,”gang”)时,
判断的不是这个对象中的”wang”和”gang”这两个String变量的具体的值,
是new Name()这个对象的引用地址,
而两次new出来的对象肯定具有不同的引用地址,
所以程序会返回一个false的判断,认为 c 这个容器中没有相应的元素,
所以第三条remove语句就不会删除相应的Name(“wang”,”gang”)这个元素,

那现在问题来了,如果我想要通过remove也可以删除new出来的Name对象怎么办?

那就需要重写Name类中的equals方法,
将上面Name类中我注释 /* */ 的equals() 和hashCode()方法放开即可:

public boolean equals(Object obj) {
    if(obj instanceof Name) {
        Name name = (Name)obj;
        return (firstName.equals(name.firstName)) 
        && lastName.equals(name.lastName);
    }
    return super.equals(obj);
}

public int hashCode() {
    return firstName.hashCode();
}

现在又有一个问题,
说好的重写equals方法,
为什么会多出来一个hashCode方法?

jdk文档中关于object类的equals方法描述中有这么一句话:

注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。

因为有的时候,判断两个对象的值相等的时候,
还会判断他们的HashCode是否也相同,
所以就需要同时重写hashCode方法。

上面就是我今天学到的关于容器Collection接口的具体应用中需要注意的问题,
刚接触容器,
对我来说是一个新的东西,
感觉现在认识到的还很肤浅。。
等我把容器这章学完以后,再来看这个问题,
可能就有不一样的理解了吧 ^_^
晚安,The World!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值