跳到主要內容

Java HashCode and Equals

Equals

在實現 equals 這個方法之前, 應該先想的是怎樣才算是相等?

先看個例子

http://openhome.cc/Gossip/JavaEssence/ObjectEquality.html

String s1 = new String("Java");
String s2 = new String("Java");
System.out.println(s1 == s2);       // 顯示 false
System.out.println(s1.equals(s2));  // 顯示 true

使用 Apache commons 可以協助更快的定義 entity 的差異, 比如說 Item(商品),
用商品的 uId 來定義是否相等。

文章建議, 在定義 equals() 的同時, 最好也定義 hashCode(),
這是兩件不同的事情, hashCode() 就像物件的身分證, 會更嚴格的處理物件身份的問題,
在 Collection 類的操作會常用到。

隨便的例子

package entitys;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

/**
 * Created by jerry on 2017/9/22.
 */
@Data
@AllArgsConstructor
public class Apple {
    private String name;
    private String type;
    private String price;

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Apple)) {
            return false;
        }

        if(obj == this) {
            return true;
        }

        Apple other = (Apple) obj;
        return new EqualsBuilder()
                .append(this.getName(), other.getName())
                .isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 31)  // two randomly chosen prime numbers
                .append(this.getName()) // if deriving: appendSuper(super.hashCode()).
                .append(this.getPrice())
                .toHashCode();
    }
}



    @Test
    public void test1() {
        Apple item1 = new Apple("apple", "fruit", "10");
        Apple item2 = new Apple("apple", "fruit", "15");
        Apple item3 = new Apple("pear", "fruit", "10");

        // 只要 name 屬性一樣, 就是 equal
        Assert.assertEquals(item1, item2);

        // 奧萊仔假朋個, 就不 equal
        Assert.assertFalse(item1.equals(item3));
    }


    @Test
    public void test2() {
        Set items = new HashSet<>();

        Apple item1 = new Apple("apple", "fruit-a", "10");
        Apple item2 = new Apple("apple", "fruit-b", "10");

        // 在購物車裡面放兩個, 不同 type 屬性的蘋果
        items.add(item1);
        items.add(item2);

        // 結果只有一顆, [Apple(name=apple, type=fruit-a, price=10)]
        System.out.println(items);
    }

留言

這個網誌中的熱門文章

Google Compute Engine‎ - AccessDeniedExceptions 403

原因 打算從 instance 打包 logs 到 google cloud storage 發生了 AccessDeniedException: 403 Insufficient OAuth2 scope to perform this operation. , 看起來是 instance 沒有 storage 權限 解決 Reference: https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances#changeserviceaccountandscopes 重新設定 service account 權限 instance 上內建有 gcloud , 就直接用現有的工具查詢一下 instance 的 account. $ gsutil info 或者在本機直接 gcloud compute instances describe INSTANCE_NAMES Account: [alpha-number-compute@developer.gserviceaccount.com] Project: [our-project-name] 會看到 instance 的一些狀態, 接下來就簡單多了, 按照下列的說明, 要先 stop instance, 更改 storage scope 再重新 start 。 To change an instance's service account and access scopes, the instance must be temporarily stopped. To stop your instance, read the documentation for Stopping an instance. After changing the service account or access scopes, remember to restart the instance. # Stop Instance gcloud compute instances stop INSTANCE_NAMES # 設定 storage scope 為 full (Read, Write) gcloud co...

Spring boot Https 設定

1. 產生 SSL certificate keytool -genkey -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650 Enter keystore password: Re-enter new password: What is your first and last name? [Unknown]: jerry What is the name of your organizational unit? [Unknown]: td What is the name of your organization? [Unknown]: com What is the name of your City or Locality? [Unknown]: taipei What is the name of your State or Province? [Unknown]: taiwan What is the two-letter country code for this unit? [Unknown]: tw Is CN=jarvis, OU=td, O=urad, L=taipei, ST=taiwan, C=tw correct? [no]: yes 這個 certificate 是 self-signed certificate 沒有經過第三方認證, 所以沒有公信力, 正式上線會在瀏覽器看到 連線不被信任 要有公信力的 certificate 最簡單的是 Lets Encrypt , 其他就是花一些錢找簽發 certificate 的組織 2. Enable HTTPS in Spring Boot Spring Boot 內建的 tomcat 預設 http 是 8080, Spring Boot 可以設定 http 跟 https, 但沒辦法同時存在這兩個設定, 如果要同時存在兩種 connection, 建議依照 文件 建議設定 https, 再透過 programmatically 去設定 http 會比較容易。 相關範例可以參考 : https://...

Spring-boot Thymeleaf Html5 SAXParseException 解析錯誤

thymeleaf 解析 html5 出錯 <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>SB Admin - Start Bootstrap Template</title> <!-- Bootstrap core CSS--> <link href="../static/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- Custom fonts for this template--> <link href="../static/vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css"> <!-- Page level plugin CSS--> <link href="../static/vendor/datatables/dataTables.bootstrap4.css" rel="stylesheet"> <!-- Custom styles for this template--> <li...