做题总结

Posted Rui_Jia

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了做题总结相关的知识,希望对你有一定的参考价值。

1.有以下代码:

class A{
    public A(String str){
         
    }
}
public class Test{
    public static void main(String[] args) {
        A classa=new A("he");
        A classb=new A("he");
        System.out.println(classa==classb);
    }
}

输出是什么?

答案:false

即便是System.out.println(classa.equals(classb));也是false。 因为equals这个方法没有重写。

##关于重写equals方法:

①为什么要重写equals方法:

  默认equals在比较两个对象时,是看他们是否指向同一个地址的。当一个类有自己特有的“逻辑相等”概念,比如一个People类,包含id和name两个属性,我们想只要id和name同时相等的时候就判定为equal,但是不重写equals方法是做不到的。
package test01;
class People{
    int id;
    String name;
    public People(int id,String name){
        this.id=id;
        this.name=name;
    }
}
public class t5 {
    public static void main(String[] args) {
        People people1=new People(123,"jia");
        People people2=new People(123,"jia");
        System.out.println(people1.equals(people2));
        
    }
}

这样输出为“false”

package test01;
class People{
    int id;
    String name;
    public People(int id,String name){
        this.id=id;
        this.name=name;
    }
    public boolean equals(Object obj){
        if(obj instanceof People){
            People p=(People)obj;
            return p.id==id&&p.name.equals(name);
        }
        if(this==obj){
            return true;
        }
        if(this==null)
            return false;
        return false;
    }
}
public class t5 {
    public static void main(String[] args) {
        People people1=new People(123,"jia");
        People people2=new People(123,"jia");
        System.out.println(people1.equals(people2));
        
    }
}

重写equals方法之后,这样的输出为true。

但是看看下面一段代码:

package test01;

import java.util.HashMap;
import java.util.Iterator;

class People{
    int id;
    String name;
    public int getId() {
        return id;
    }
    public String getName() {
        return name;
    }
    public People(int id,String name){
        this.id=id;
        this.name=name;
    }
    public boolean equals(Object obj){
        if(obj instanceof People){
            People p=(People)obj;
            return p.id==id&&p.name.equals(name);
        }
        if(this==obj){
            return true;
        }
        if(this==null)
            return false;
        return false;
    }
}
class Department{
    String DepartmentName;
    int DepartmentId;
    public Department(int DepartmentId,String DepartmentName){
        this.DepartmentId=DepartmentId;
        this.DepartmentName=DepartmentName;
    }
    public String getDepartmentName() {
        return DepartmentName;
    }
    public int getDepartmentId() {
        return DepartmentId;
    }
}
public class t5 {
    public static void main(String[] args) {
        HashMap<People,Department> map=new HashMap<People,Department>();
        People people1=new People(123,"jia");

        Department department1=new Department(11,"FinanceDepartment");
        map.put(people1,department1);
        People people2=new People(123,"jia");
        Department department2=new Department(12,"MarketingDepartment");

        map.put(people2,department2);
        People people3=null;
        System.out.println(people1.equals(people2));
        Iterator it=map.keySet().iterator();
        while(it.hasNext()){
            People tmp=(People)it.next();
            System.out.println(tmp.getName()+"  "+tmp.getId()+"  "+map.get            (tmp).getDepartmentName()
                    +"  "+map.get(tmp).getDepartmentId());
        }
    }
}

我将两个People和Department作为HashMap中的key和value的值,代码中可以看出来,people1和people2的内容是完全相同的,那么按照HashMap的性质,put数据进HashMap的时候当key值与map内的某一key值相同时,是将原来的value值覆盖掉的。但是,运行的结果是

QQ截图20160516191721

由此可见,key值完全相同,但是并没有把第一个的value值覆盖掉。

先来看看HashMap中的put方法:

public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

可以看到,在put中如果(其key的hashcod与map中key的hashcode相同,key值与map中key值相同(对于基础数据类型),key值equal map中的key值(String或者封装类型,引用类型))那么将覆盖其原有的value。

所以,原因找到了,是因为people1和people2的hashcode不相同,导致没有覆盖。

在key,也就是value类中添加对hashcode的重写。

public int hashCode() {
            int result = 17;
            result = 37 * result + name.hashCode();
            result = 37 * result + id;
            return result;
        }

或者简单的可以这样写:

public int hashCode(){
               return 50;
    }

添加完对hashcode的重写之后,运行结果:

image

所以,一般对equals进行重写的时候,也要把hashcode重写!

 

2.hashMap跟hashTable的区别?

答:

HashTable和HashMap区别

①继承不同。

public class Hashtable extends Dictionary implements Map public class HashMap extends AbstractMap implements Map

Hashtable 中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。

Hashtable中,key和value都不允许出现null值。

在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示 HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。

④两个遍历方式的内部实现上不同。

Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。

哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。

Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。 

以上是关于做题总结的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode与《代码随想录》数组篇:做题笔记与总结-JavaScript版

LeetCode与《代码随想录》链表篇:做题笔记与总结-JavaScript版

LeetCode与《代码随想录》栈与队列篇:做题笔记与总结-JavaScript版

LeetCode与《代码随想录》双指针篇:做题笔记与总结-JavaScript版

LeetCode与《代码随想录》哈希表篇:做题笔记与总结-JavaScript版

LeetCode与《代码随想录》字符串篇:做题笔记与总结-JavaScript版