集合中涉及到Hash的时候,怎么办?关于==与equals 重写

      杂记

      凡是涉及到hash的集合,在添加和判断集合中是否有相同对象时,要考虑可能要从写父类Object中的hashCode()方法,equals方法。

      所有的包装类和String类,都重写了hashCode 和 equals ,所有,在hashMap和hashSet中,如果以这些类型作为key的类型,那么就不需要考虑重写的问题,否则,如果是以自定义的类的类型作为key的类型,那么就必须要重写hashCode和equals方法。(看源码)

示例代码:

public class ForTest {

      public static void main(String[] args) {

            Map<MyKey,Cat> map=new HashMap<MyKey,Cat>();

            MyKey k1=new MyKey("tom-1");

            map.put(new MyKey("cat1"),new Cat("cat1"));

            Cat c=map.get(new MyKey("cat1"));

            System.out.println(c); 
         //这里Map的key值是自定义的类型,如果没重写hashCode 和equals的时候,会输出null,
        //也就是map中不存在new MyKey("cat1")对象,重写了才能判断存在该对象,
        //原理就是hash集合中的put操作,自己去看代码。

            }

      }

class Cat{

      private String name;

      public Cat(String name){

            this.name=name;

      }

}

class MyKey{

      private String name;

      private Integer age;

      public String getName(){

            return name;

      }

      public void setName(String name){

            this.name=name;

      }

      public MyKey(String name){

            super();

            this.name=name;

      }

//由于集合中的key是自定义类型,因此必须重写这两个方法
//才能得到想要的结果,如果是基本类型的包装类类型,那么就不需要重写,这个是需要看底层代码的。

      public int hashCode(){

            int nameHash=name==null?0:name.hashCode();

            int agehash=age==null ?0 : age.intValue();

            return nameHash + agehash;

      }

      public boolean equals(Object obj){

            MyKey key0 =(MyKey)obj;

            return name.equals(key0.name) && age == key0.age;

      }

}

二  equals 和== 以及list集合中的contains

        equals: 比较的是两个对象的内容,(仅对String类型的对象,因为String类型的对象重写了父类的equals方法)。

        ==:对于基本数据类型,比较的是保存的内容,对于引用数据类型,比较的是对象的地址

        (笔记Day190622)

举例1:String st1="abc";

     String st2="abc";

    st1==st2;//输出是true.

    String st3=new String "abc";

    String st4=new String "abc"

       System.out.println(st3==st4);    

       System.out.println(st3.equals(st4));

举例2: 

public class ForTest {

      public static void main(String[] args) {

            Person p1=new Person("gtl",2);

            Person p2=new Person("gtl",2);

            System.out.println(p1==p2);

            System.out.println(p1.equals(p2));  //输出false, equals 不是说是指向对象保存内容的吗,那这里为什么跟例1中的equals输出的结果不一样呢,不应该也是true吗??

      }

}

class Person{

      private String name;

      private int age;

      public Person(){}

      public Person(String name ,int age)

      {

            this.name=name;

            this.age=age;

      }

 

//      public boolean equals(Object obj){

//          //1 空值判断,如果obj是空的,返回false

//          if(obj==null){

//                return false;

//          }

//          //2是不是同一个对象呢,看内存地址是不是相等的,如果是相等的,则一定相等

//          if(this==obj){

//                return true;

//          }

//          //判断两个对象是否相等,首先判断是不是同一个类

//          //3 用instanceof判断对象是不是某种类型,如果是则执行条件中内容

//          if(obj instanceof Person){

//                //将对象obj强转成Person类

//                Person p=(Person)obj;

//                //设置一个标签flag,存放名称是否相等

//                boolean nameEqu=false;

//                if(p.name==null  ){

//                      if(p.name==null){

//                            nameEqu=true;

//                      }else{

//                            nameEqu=false;

//                      }

//                }else{

//                      nameEqu=name.equals(p.name);

//                }

//

//                //age是否相同

//                boolean ageEqu=this.age == p.age;

//                return nameEqu && ageEqu;

//          }

//          return false;

//    }

回答:千万不要死记硬背说equals比较的是两个对象的内容是否相同,这里仅指的是String类型的对象,那为什么String类型的对象比较的就是对象的内容,而其他类对象调用equals方法就不能比较对象内容了呢??? 通过观察源码可以看到,String类对象重写了父类Object中的equals方法,而我们自己新建的类对象并没有实现这个方法,因此就不能比较。所以,例2中看到,结果输出的两个都为false,因此,要想也实现equals方法,应该重写该方法。

重写部分见上面Person类的注释。

 

扩展:如果ArrayList中保存的是自己定义的类对象,那么就要注意了,要是判断其中有没有已经保存了一个类对象,这个时候就要重写equals方法。原因解释:ArrayList类对象中有个contains方法,通过看源码就知道,判断一个对象有没有在对象中,就取决于equals,所以对于列表的contains方法,可能要重写equals方法,才能得到正确答案。而hashMap类对象中,键是不会重复的,通过看键存不存在就可以判断键所指的值对象有没有存在。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值