做题总结
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值覆盖掉的。但是,运行的结果是
由此可见,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的重写之后,运行结果:
所以,一般对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版