亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

java equals 和 hashcode

HollisChuang / 2869人閱讀

摘要:簡單的一句話結(jié)論就是保證你定義的的對(duì)象擁有相同的。方法實(shí)現(xiàn)等價(jià)關(guān)系自反性。即一個(gè)對(duì)象必須等于其自身。對(duì)于任意引用值和返回真時(shí),也一定為真?zhèn)鬟f性。發(fā)現(xiàn)一樣,調(diào)用方法繼續(xù)比較,發(fā)現(xiàn)個(gè)對(duì)象一樣。

簡單的一句話結(jié)論就是:保證你定義的“equal”的對(duì)象擁有相同的hash code。
1)兩個(gè)對(duì)象equals()為真,則它們的hashCode() 一定相同
2)兩個(gè)對(duì)象hashCode()相同,equals()不一定為真這兩個(gè)Object方法如果沒有很好的定義,可能會(huì)產(chǎn)生使用者不希望看到的效果。
2)實(shí)現(xiàn)hashCode(),原則如本答案第一句話所示,并盡量使用對(duì)象自有特性作為生成因子以減小沖突的概率。

equals方法實(shí)現(xiàn)等價(jià)關(guān)系
1、自反性。
對(duì)應(yīng)任意引用值x,x.equals(x),一定為真。
即一個(gè)對(duì)象必須等于其自身。
2、對(duì)稱性。
對(duì)于任意引用值x和y,x.equals(y)返回真時(shí),y.equals(x)也一定為真
3、傳遞性。
對(duì)于任意引用值x、y和z,x.equals(y)返回真,且y.equals(z)返回真,則x.equals(z)一定返回真。
4、一致性。
對(duì)于任意引用值x和y,如果用于equals比較對(duì)象的信息沒有被修改的話,那么多次調(diào)用x.equals(y)要么都是true,要么都是false
5、對(duì)于任意的非空引用值x,x.equals(null) 一定返回false

下面的例子違反了對(duì)稱性

package equals;

import java.util.ArrayList;
import java.util.List;

public final class CaseInsensitive {

    private String s;

    public CaseInsensitive(String s) {
        if(s == null) {
            throw new UnsupportedOperationException();
        }
        this.s = s;
    }

    @Override
    public boolean equals(Object o) {
        if(o instanceof CaseInsensitive) {
            return s.equalsIgnoreCase(((CaseInsensitive) o).s);
        }
        // 如果傳進(jìn)來的是String對(duì)象
        if(o instanceof  String) {
            return s.equalsIgnoreCase(((String)o)) ;
        }
        return false;
    }

    public static void main(String[] args) {
        CaseInsensitive o = new CaseInsensitive("CSP");
        String s = "csp";
        System.out.println(o.equals(s));// 返回true
        System.out.println(s.equals(o));;// 返回 false
        
        // 根據(jù)對(duì)稱性,o 與 s 返回true,那么 s 與 o 也應(yīng)該返回true,而這里卻返回false,違反了對(duì)稱性。原因是String的equals方法,不知道要忽略大小寫
       
       //如果將o加入集合中,則返回false,而我們的原意是想讓他返回true
        List list = new ArrayList();
        list.add(o);
        System.out.println(list.contains(s)); // 返回false 
    }
}

下面例子違反傳遞性

package equals;

/**
 * Created by Administrator on 2017/9/23.
 */
public class Point {
    private int x;
    private int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public boolean equals(Object o) {
        if(!(o instanceof Point)) {
            return false;
        }
        Point p = (Point) o;
        return p.x == x && p.y == y;
    }
}
package equals;

public class ColorPoint extends Point {

    private String color;

    public ColorPoint(int x, int y,String color) {
        super(x, y);
        this.color = color
    }

    public boolean equals(Object o) {
        if(!(o instanceof ColorPoint)) {
            return false;
        }
        ColorPoint p = (ColorPoint) o;
        return super.equals(o) && p.color.equals(color);
    }

    public static void main(String[] args) {
        ColorPoint cp = new ColorPoint(1,1,"red");
        Point p = new Point(1,1);
        System.out.println(cp.equals(p)); //false
        System.out.println(p.equals(cp)); //true
        // 違反了對(duì)稱性。因?yàn)镃olorPoint 與 Point 比較時(shí),多了個(gè)color屬性
    }
}

我們可以對(duì)ColorPoint進(jìn)行修改,讓其滿足對(duì)稱性,在混合比較時(shí),忽略顏色信息

....
public boolean equals(Object o) {
        if(!(o instanceof Point)) {
            return false;
        }
        //對(duì)象是Point類型,不是ColorPoint,進(jìn)行父類級(jí)別的比較
        if(!(o instanceof ColorPoint)) {
            return o.equals(this);
        }
        ColorPoint p = (ColorPoint) o;
        return super.equals(o) && p.color.equals(color);
    }
    ....
public static void main(String[] args) {
        ColorPoint cp = new ColorPoint(1,1,"red");
        Point p = new Point(1,1);
        ColorPoint cp1 = new ColorPoint(1,1,"black");
        System.out.println(cp.equals(p)); //true
        System.out.println(p.equals(cp1)); //true
        System.out.println(cp.equals(cp1)); //false
        // 違反了傳遞性
    }

以上代碼雖然符合對(duì)稱性,但是卻違反了傳遞性

想要解決以上問題,只能使用復(fù)合來代替繼承

public class ColorPoint {

private String color;
private Point p;
public ColorPoint(String color,Point p) {
    this.color = color;
    this.p = p;
}

public Point getP() {
    return p;
}

@Override
public boolean equals(Object o) {
    if(!(o instanceof ColorPoint)) {
        return false;
    }
    ColorPoint cp = (ColorPoint) o;
    return  cp.p.equals(p) && cp.color.equals(color);
}

}

當(dāng)你重寫了equals()時(shí),也應(yīng)該重寫hashcode();

來看當(dāng)一個(gè)類重寫了equals()方法時(shí),沒有重寫hashCode方法,并將其放入Map中

import java.util.HashMap;
import java.util.Map;

public final class CaseInsensitive {

private int x;
private int y;
private String s;

public CaseInsensitive(int x,int y,String s) {
    this.s = s;
    this.x = x;
    this.y = y;
}

@Override
public boolean equals(Object o) {
    if(o == this) {
        return true;
    }
    if(!(o instanceof CaseInsensitive) || o == null) {
        return false;
    }
    CaseInsensitive cp = (CaseInsensitive) o;
    return cp.s.equals(s) && cp.x == x && cp.y == y;
}

public static void main(String[] args) {
    CaseInsensitive c = new CaseInsensitive(1,1,"cc");
    CaseInsensitive c1 = new CaseInsensitive(1,1,"cc");
    Map m = new HashMap();
    m.put(c,"c");
    System.out.println(m.get(new CaseInsensitive(1,1,"cc"))); // null
}

}

按照我們的意思,應(yīng)該是返回 c 的,但是實(shí)際上返回的是 null

原因在于,沒有重寫hashCode()方法,Map在放入元素時(shí),是先根據(jù)對(duì)象的散列值進(jìn)行存放,如果散列值一樣,那么則繼續(xù)比較equals方法。此處默認(rèn)是Object的hashCode方法。所有2個(gè)對(duì)象不一樣。

讓我們重寫hashCode方法試下

....
@Override

public boolean equals(Object o) {
    if(o == this) {
        return true;
    }
    if(!(o instanceof CaseInsensitive) || o == null) {
        return false;
    }
    CaseInsensitive cp = (CaseInsensitive) o;
    return cp.s.equals(s) && cp.x == x && cp.y == y;
}

//此處使用IDEA 默認(rèn)生成的hashCode
@Override 
public int hashCode() {
    int result = x;
    result = 31 * result + y;
    result = 31 * result + (s != null ? s.hashCode() : 0);
    return result;
}

public static void main(String[] args) {
    CaseInsensitive c = new CaseInsensitive(1,1,"cc");
    CaseInsensitive c1 = new CaseInsensitive(1,1,"cc");
    Map m = new HashMap();
    m.put(c,"c");
    System.out.println(m.get(new CaseInsensitive(1,1,"cc"))); //返回c
}

此時(shí)就可以獲取到c了。因?yàn)槲覀冎貙懥薶ashCode()方法,比較2個(gè)對(duì)象的hashCode。發(fā)現(xiàn)hashCode一樣,調(diào)用equals()方法繼續(xù)比較,發(fā)現(xiàn)2個(gè)對(duì)象一樣。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/70517.html

相關(guān)文章

  • Java Object類方法分析

    摘要:類方法分析聲明文章均為本人技術(shù)筆記,轉(zhuǎn)載請(qǐng)注明出處類簡介類是所有類的父類,在中只有基本數(shù)據(jù)類型不是對(duì)象。對(duì)于所有數(shù)組類型對(duì)象類型基本數(shù)據(jù)類型數(shù)組都繼承于類方法類中通過判斷兩個(gè)對(duì)象是否具有相同引用,從而判斷兩個(gè)對(duì)象是否相同子類只要重寫方法,就 Java Object類方法分析 聲明 文章均為本人技術(shù)筆記,轉(zhuǎn)載請(qǐng)注明出處https://segmentfault.com/u/yzwall ...

    zhisheng 評(píng)論0 收藏0
  • 【碼藝雜談】Java中的相同與不同

    摘要:如果根據(jù)方法得到兩個(gè)對(duì)象不相同,那么兩個(gè)對(duì)象的方法的結(jié)果不一定不相同,我們可以利用這一點(diǎn)來提高散列表的性能。最后回到文章開頭的問題,如何判斷兩個(gè)對(duì)象或值是否相同這個(gè)問題其實(shí)有兩方面的含義,一方面是判斷的方法,另一方面是判斷的效率。 Java中有很多場景需要判斷兩個(gè)對(duì)象或者兩個(gè)值,那么 判斷是否相同的依據(jù)是什么? 如何判斷是否相同呢? 為了解釋這個(gè)問題,我們從Java語言的根說起,那...

    xingqiba 評(píng)論0 收藏0
  • Java equals == 完全解析

    摘要:所以在對(duì)象沒有重寫這個(gè)方法時(shí),默認(rèn)使用此方法,即比較對(duì)象的內(nèi)存地址值。結(jié)果為可以發(fā)現(xiàn)不管對(duì)象的內(nèi)存地址是否相同并不影響其結(jié)果,所以類型比較的是數(shù)據(jù)值而不是內(nèi)存地址值。 showImg(https://segmentfault.com/img/bVbqpku?w=800&h=344); 今天朋友突然問到一個(gè)問題: 兩個(gè)對(duì)象使用x.equals(y)判斷結(jié)果為true時(shí),兩個(gè)對(duì)象的hash...

    mikasa 評(píng)論0 收藏0
  • Java Object對(duì)象的hashcodeequals方法

    摘要:在中對(duì)象是一切對(duì)象都會(huì)自動(dòng)繼承的一個(gè)類,在這個(gè)類中定義的屬性和方法可以說是每個(gè)類都必須的。這里有必要說說這里對(duì)象里面的幾個(gè)方法返回該對(duì)象的哈希碼值。這些基于表的集合,只能要求被存放的對(duì)象實(shí)現(xiàn)自己的方法,保證的均勻性。 Object 在Java中Object對(duì)象是一切對(duì)象都會(huì)自動(dòng)繼承的一個(gè)類,在這個(gè)類中定義的屬性和方法可以說是每個(gè)類都必須的。 這里有必要說說這里對(duì)象里面的幾個(gè)方法 has...

    chnmagnus 評(píng)論0 收藏0
  • java中的hashCode

    摘要:相關(guān)的文章網(wǎng)上很多了寫這個(gè)主要是按自己的思路進(jìn)行記錄是什么中的實(shí)現(xiàn)是一個(gè)本地方法生成一個(gè)表征當(dāng)前對(duì)象實(shí)例的特征值具體的實(shí)現(xiàn)根據(jù)的實(shí)現(xiàn)可能會(huì)不同中實(shí)際計(jì)算的函數(shù)的實(shí)現(xiàn)如下為時(shí)是直接使用的內(nèi)存地址但默認(rèn)使用的是的隨 hashcode相關(guān)的文章網(wǎng)上很多了, 寫這個(gè)主要是按自己的思路進(jìn)行記錄 hashCode是什么 Object中的hashCode實(shí)現(xiàn)是一個(gè)本地方法, 生成一個(gè)表征當(dāng)前對(duì)象實(shí)例...

    cnTomato 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<