一、equals方法的作用
1、預設情況(沒有覆寫equals方法)下equals方法都是調用object類的equals方法,而object的equals方法主要用于判斷對象的記憶體位址引用是不是同一個位址(是不是同一個對象)。
2 、要是類中覆寫了equals方法,那麼就要根據具體的代碼來确定equals方法的作用了,覆寫後一般都是通過對象的内容是否相等來判斷對象是否相等。
沒有覆寫equals方法代碼如下:
[java] view plaincopyprint?
//學生類
public class student {
private int age;
private string name;
public student() {
}
public student(int age, string name) {
super();
this.age = age;
this.name = name;
public int getage() {
return age;
public string getname() {
return name;
public void setage(int age) {
public void setname(string name) {
}
java代碼
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5ichR3cf52bjl2LcNXZnFWbp9CXt92YuUWelRXau0GekhXbvw1LcpDc0RHaiojIsJye.png)
測試 代碼如下:
import java.util.hashset;
import java.util.linkedlist;
import java.util.set;
public class equalstest {
public static void main(string[] args) {
linkedlist<student> list = new linkedlist<student>();
set<student> set = new hashset<student>();
student stu1 = new student(3,"張三");
student stu2 = new student(3,"張三");
system.out.println("stu1 == stu2 : "+(stu1 == stu2));
system.out.println("stu1.equals(stu2) : "+stu1.equals(stu2));
list.add(stu1);
list.add(stu2);
system.out.println("list size:"+ list.size());
set.add(stu1);
set.add(stu2);
system.out.println("set size:"+ set.size());
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5ichR3cf52bjl2LcNXZnFWbp9CXt92YuUWelRXau0GekhXbvw1LcpDc0RHaiojIsJye.png)
運作結果:
stu1 == stu2 : false
stu1.equals(stu2) : false
list size:2
set size:2
結果分析:student類沒有覆寫equals方法,stu1調用equals方法實際上調用的是object的equals方法。是以采用對象記憶體位址是否相等來判斷對象是否相等。因為是兩個新對象是以對象的記憶體位址不相等,是以stu1.equals(stu2) 是false。
3、我們覆寫一下equals方法(age和name屬性),讓student類其通過判斷對象的内容是否相等來确定對象是否相等。
覆寫後的student類:
@override
public boolean equals(object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getclass() != obj.getclass())
student other = (student) obj;
if (age != other.age)
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return true;
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5ichR3cf52bjl2LcNXZnFWbp9CXt92YuUWelRXau0GekhXbvw1LcpDc0RHaiojIsJye.png)
stu1.equals(stu2) : true
結果分析:因為student兩個對象的age和name屬性相等,而且又是通過覆寫equals方法來判斷的,所示stu1.equals(stu2) 為true。注意以上幾次測試list和set的size都是2
二、hashcode
4、通過以上的代碼運作,我們知道equals方法已經生效。接下來我們在覆寫一下hashcode方法(通過age和name屬性來生成hashcode)并不覆寫equals方法,其中hash碼是通過age和name生成的。
覆寫hashcode後的student類:
public int hashcode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashcode());
return result;
}
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5ichR3cf52bjl2LcNXZnFWbp9CXt92YuUWelRXau0GekhXbvw1LcpDc0RHaiojIsJye.png)
hashcode :775943
結果分析:我們并沒有覆寫equals方法隻覆寫了hashcode方法,兩個對象雖然hashcode一樣,但在将stu1和stu2放入set集合時由于equals方法比較的兩個對象是false,是以就沒有在比較兩個對象的hashcode值。
5、我們覆寫一下equals方法和hashcode方法。
student代碼如下:
system.out.println("hashcode : "+ result);
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5ichR3cf52bjl2LcNXZnFWbp9CXt92YuUWelRXau0GekhXbvw1LcpDc0RHaiojIsJye.png)
stu1.equals(stu2) :true
set size:1
結果分析:stu1和stu2通過equals方法比較相等,而且傳回的hashcode值一樣,是以放入set集合中時隻放入了一個對象。
6、下面我們讓兩個對象equals方法比較相等,但hashcode值不相等試試。
student類的代碼如下:
<span style="color: rgb(255, 0, 0);">private static int index=5;</span>
result = prime * result + <span style="color: rgb(255, 0, 0);">(age+index++)</span>;
<span style="color: rgb(255, 0, 0);">system.out.println("result :"+result);</span>
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5ichR3cf52bjl2LcNXZnFWbp9CXt92YuUWelRXau0GekhXbvw1LcpDc0RHaiojIsJye.png)
<span style="color: #ff0000;">private static int index=5;</span>
result = prime * result + <span style="color: #ff0000;">(age+index++)</span>;
<span style="color: #ff0000;">system.out.println("result :"+result);</span>
hashcode :776098
hashcode :776129
結果分析:雖然stu1和stu2通過equals方法比較相等,但兩個對象的hashcode的值并不相等,是以在将stu1和stu2放入set集合中時認為是兩個不同的對象。
7、修改stu1的某個屬性值
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5ichR3cf52bjl2LcNXZnFWbp9CXt92YuUWelRXau0GekhXbvw1LcpDc0RHaiojIsJye.png)
測試代碼如下:
stu1.setage(34);
system.out.println("remove stu1 : "+set.remove(stu1));
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5ichR3cf52bjl2LcNXZnFWbp9CXt92YuUWelRXau0GekhXbvw1LcpDc0RHaiojIsJye.png)
stu1.equals(stu2) : true
hashcode : 775943
hashcode : 775943
hashcode : 776904
remove stu1 : false
結果分析:
當我們将某個對象存到set中時,如果該對象的屬性參與了hashcode的計算,那麼以後就不能修改該對象參與hashcode計算的那些屬性了,否則會引起意向不到的錯誤的。正如測試中,不能夠移除stu1對象。
總結:
1、equals方法用于比較對象的内容是否相等(覆寫以後)
2、hashcode方法隻有在集合中用到
3、當覆寫了equals方法時,比較對象是否相等将通過覆寫後的equals方法進行比較(判斷對象的内容是否相等)。
4、将對象放入到集合中時,首先判斷要放入對象的hashcode值與集合中的任意一個元素的hashcode值是否相等,如果不相等直接将該對象放入集合中。如果hashcode值相等,然後再通過equals方法判斷要放入對象與集合中的任意一個對象是否相等,如果equals判斷不相等,直接将該元素放入到集合中,否則不放入。
5、将元素放入集合的流程圖:
6、hashset中add方法源代碼:
public boolean add(e e) {
return map.put(e, present)==null;
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5ichR3cf52bjl2LcNXZnFWbp9CXt92YuUWelRXau0GekhXbvw1LcpDc0RHaiojIsJye.png)
map.put源代碼:
<pre class="java" name="code"> 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;
}</pre>
<pre></pre>
<pre></pre>
特别說明:尊重作者的勞動成果,轉載請注明出處哦~~~http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt277