请选择 进入手机版 | 继续访问电脑版
楼主: Nicolle
2511 6

Beginning Java 8 Fundamentals [推广有奖]

巨擘

0%

还不是VIP/贵宾

-

TA的文库  其他...

Python(Must-Read Books)

SAS Programming

Must-Read Books

威望
16
论坛币
12402323 个
通用积分
1620.8615
学术水平
3305 点
热心指数
3329 点
信用等级
3095 点
经验
477211 点
帖子
23879
精华
91
在线时间
9878 小时
注册时间
2005-4-23
最后登录
2022-3-6

Nicolle 学生认证  发表于 2015-5-16 09:46:46 |显示全部楼层 |坛友微信交流群
提示: 作者被禁止或删除 内容自动屏蔽

本帖被以下文库推荐

Lisrelchen 发表于 2015-5-31 05:49:20 |显示全部楼层 |坛友微信交流群
  1. Listing 7-1. A Book Class That Reimplements the hashCode() Method

  2. // Book.java
  3. package com.jdojo.object;

  4. public class Book {
  5.         private String title;
  6.         private String author;
  7.         private int pageCount;
  8.         private boolean hardCover;
  9.         private double price;

  10.         /* Other code goes here */

  11.         /* Must implement the equals() method too. */

  12.         public int hashCode() {
  13.                 int hash = 37;
  14.                 int code = 0;

  15.                 // Use title
  16.                 code = (title == null ? 0 : title.hashCode());
  17.                 hash = hash * 59 + code;
  18.          
  19.                 // Use author
  20.                 code = (author == null ? 0 : author.hashCode());
  21.                 hash = hash * 59 + code;

  22.                 // Use pageCount
  23.                 code = pageCount;
  24.                 hash = hash * 59 + code;

  25.                 // Use hardCover
  26.                 code = (hardCover ? 1 : 0);
  27.                 hash = hash * 59 + code;

  28.                 // Use price
  29.                 long priceBits = Double.doubleToLongBits(price);
  30.                 code = (int)(priceBits ^ (priceBits >>>32));
  31.                 hash = hash * 59 + code;

  32.                 return hash;
  33.         }
  34. }
复制代码

The class has five instance variables: title, author, pageCount, hardcover, and price. The implementation uses all five instance variables to compute the hash code for a Book object. You must also implement the equals() method for the Book class, which must use all the five instance variables to check if two Book objects are equal. You need to make sure that the equals() method and thehashCode() method use the same set of instance variables in their logic. Suppose you add one more instance variable to the Book class. Let’s call it ISBN. Because ISBN identifies a book uniquely, you might use only the ISBN instance variable to compute its hash code and to compare for equality with another Book object. In this case, it will be sufficient to use only one instance variable to compute the hash code and check for equality.

There are some misconceptions about the hash code of an object in Java. Developers think that the hash code uniquely identifies an object and it must be a positive integer. However, they are not true. The hash code does not identify an object uniquely. Two distinct objects may have the same hash codes. A hash code does not have to be only a positive number. It could be any integer value, positive as or negative. There is also confusion about the usage of hash codes. They are used solely for the purpose of efficient retrieval of data from a hash-based collection. If your objects are not used as keys in hash based collections and you do not override the equals() method in your class, you do not need to worry about reimplementing the hashCode() method in your class at all. Most likely, it will be overriding the equals() method that will prompt you to override the hashCode() method for your class. If you do not override and provide correct implementation of hashCode() and equals() methods in your class at the same time, the objects of your class would not behave properly in hash-based collections. The Java compiler or the Java runtime will never give you any warnings or errors about the incorrect implementations of these two methods in your class.

使用道具

Lisrelchen 发表于 2015-5-31 05:53:31 |显示全部楼层 |坛友微信交流群

  1. Listing 7-2. A SmartPoint Class That Reimplements equals() and hashCode() Methods

  2. // SmartPoint.java
  3. package com.jdojo.object;

  4. public class SmartPoint {
  5.         private int x;
  6.         private int y;
  7.      
  8.         public SmartPoint(int x, int y) {
  9.                 this.x = x;
  10.                 this.y = y;
  11.         }
  12.      
  13.         /* Reimplement the equals() method */
  14.         public boolean equals(Object otherObject) {
  15.                 // Are the same?
  16.                 if (this == otherObject) {
  17.                         return true;
  18.                 }
  19.          
  20.                 // Is otherObject a null reference?
  21.                 if (otherObject == null) {
  22.                         return false;
  23.                 }
  24.          
  25.                 // Do they belong to the same class?
  26.                 if (this.getClass() != otherObject.getClass()) {
  27.                         return false;
  28.                 }
  29.          
  30.                 // Get the reference of otherObject in a SmartPoint variable
  31.                 SmartPoint otherPoint = (SmartPoint)otherObject;
  32.          
  33.                 // Do they have the same x and y co-ordinates
  34.                 boolean isSamePoint = (this.x == otherPoint.x && this.y == otherPoint.y);
  35.          
  36.                 return isSamePoint;
  37.         }
  38.      
  39.         /* Reimplement hashCode() method of the Object class,
  40.            which is a requirement when you reimplement equals() method */
  41.         public int hashCode() {
  42.                 return (this.x + this.y);
  43.         }
  44. }
复制代码

You call your new class SmartPoint. Java advises to reimplement hashCode() and equals() methods together if any one of them is reimplemented in your class. The Java compiler would not complain if you reimplement the equals() method and not the hashCode() method. However, you will get unpredictable results when you use the objects of your class in hash-based collections.

The only requirement for a hashCode() method is that if the m.equals(n) method returns true, m.hashCode() must return the same value as n.hashCode(). Because your equals() method uses (x, y) coordinates to test for equality, you return the sum of x and y coordinates from the hashCode() method, which fulfills the technical requirement. Practically, you need to use a better hashing algorithm to compute the hash value.

You have written a few lines of codes in the equals() method of the SmartPoint class. Let’s go through the logic one by one. First, you need to check if the object passed is the same as the object on which the method is called. If two objects are the same, you consider them equal by retuning true. This is accomplished by the following code:

// Are they the same?
if (this == otherObject) {
        return true;
}
If the parameter being passed is null, the two objects cannot be the same. Note that the object on which the method is called can never be null because you cannot call a method on a null reference. Java runtime will throw runtime exception when an attempt is made to call a method on a null reference. The following code makes sure that you are comparing two non-null objects:

// Is otherObject a null reference?
if (otherObject == null) {
        return false;
}
The parameter type of the method is Object. This means that any type of object reference can be passed. For example, you can use apple.equals(orange), where apple and orange are references to an Apple object and an Orange object, respectively. In your case, you want to compare only a SmartPoint object to another SmartPoint object. To make sure that the objects being compared are of the same class, you need the following code. If someone calls the method with a parameter that is not a SmartPoint object, it returns false.

// Do they have the same class?
if (this.getClass() != otherObject.getClass()) {
        return false;
}
At this point, you are sure that someone is trying to compare two non-null SmartPoint objects that have different identity (references). Now you would like to compare the (x, y) coordinates of two objects. To access the x and y instance variables of the otherObject formal parameter, you must cast it to a SmartPoint object. The following statement does it:

// Get the reference of otherObject in a SmartPoint variable
SmartPoint otherPoint = (SmartPoint)otherObject;
At this point, it is just the matter of comparing the values of x and y instance variables of the two SmartPoint objects. If they are the same, you consider two objects equal by returning true. Otherwise, two objects are not equal and you return false. This is accomplished by the following code:

// Do they have the same x and y co-ordinates
boolean isSamePoint = (this.x == otherPoint.x && this.y == otherPoint.y);
return isSamePoint;
It is time to test your reimplementation of the equals() method in the SmartPoint class. Listing 7-3 is your test class. You can observe in the output that you have two ways of comparing two SmartPoint objects for equality. The equality operator (==) compares them based on identity and the equals() method compares them based on values of the (x, y) coordinates. Note that if (x, y) coordinates are the same for two SmartPoint objects, the equals() method returns true.

使用道具

Lisrelchen 发表于 2015-5-31 05:55:33 |显示全部楼层 |坛友微信交流群
  1. Listing 7-3. A Test Class to Demonstrate the Difference Between Identity and State Comparisons

  2. // SmartPointTest.java
  3. package com.jdojo.object;

  4. public class SmartPointTest {
  5.         public static void main(String[] args)  {
  6.                 SmartPoint pt1 = new SmartPoint(10, 10);
  7.                 SmartPoint pt2 = new SmartPoint(10, 10);
  8.                 SmartPoint pt3 = new SmartPoint(12, 19);
  9.                 SmartPoint pt4 = pt1;
  10.          
  11.                 System.out.println("pt1 == pt1: " + (pt1 == pt1));
  12.                 System.out.println("pt1.equals(pt1): " + pt1.equals(pt1));
  13.          
  14.                 System.out.println("pt1 == pt2: " + (pt1 == pt2));
  15.                 System.out.println("pt1.equals(pt2): " + pt1.equals(pt2));
  16.          
  17.                 System.out.println("pt1 == pt3: " + (pt1 == pt3));
  18.                 System.out.println("pt1.equals(pt3): " + pt1.equals(pt3));
  19.          
  20.                 System.out.println("pt1 == pt4: " + (pt1 == pt4));
  21.                 System.out.println("pt1.equals(pt4): " + pt1.equals(pt4));
  22.         }
  23. }
  24. pt1 == pt1: true
  25. pt1.equals(pt1): true
  26. pt1 == pt2: false
  27. pt1.equals(pt2): true
  28. pt1 == pt3: false
  29. pt1.equals(pt3): false
  30. pt1 == pt4: true
  31. pt1.equals(pt4): true
复制代码


There are some specifications for implementing the equals() method in your class, so your class will work correctly when used with other areas (e.g. hash-based collections) of Java. It is the responsibility of the class designer to enforce these specifications. If your class does not conform to these specifications, the Java compiler or Java runtime will not generate any errors. Rather, objects of your class will behave incorrectly. For example, you will add your object to a collection, but you may not be able to retrieve it. Here are specifications for the equals() method’s implementation. Assume that x, y, and z are non-null references of three objects.

Reflexivity: It should be reflexive. The expression x.equals(x) should return true. That is, an object must be equal to itself.
Symmetry: It should be symmetric. If x.equals(y) returns true, y.equals(x) must return true. That is, if x is equal to y, y must be equal to x.
Transitivity: It should be transitive. If x.equals(y) returns true and y.equals(z) returns true, x.equals(z) must return true. That is, if x is equal to y and y is equal to z, x must be equal to z.
Consistency: It should be consistent. If x.equals(y) returns true, it should keep returning true until the state of x or y is modified. If x.equals(y) returns false, it should keep returning false until the state of x or y is modified.
Comparison with null reference: An object of any class should not be equal to a null reference. The expression x.equals(null) should always return false.
Relationship with hashCode() method: If x.equals(y) returns true, x.hashCode() must return the same value as y.hashCode(). That is, if two objects are equal according to the equals() method, they must have the same hash code values returned from their hashCode() methods. However, the opposite may not be true. If two objects have the same hash codes, that does not imply that they must be equal according to the equals() method. That is, if x.hashCode() is equal to y.hashCode(), that does not imply that x.equals(y) will return true.
Your SmartPoint class satisfies all six rules for equals() and hashCode() methods. It was fairly easy to implement the equals() method for the SmartPoint class. It has two primitive type instance variables and you used both of them in comparison for equality.

There are no rules as to how many of instance variables should be used to compare for equality of two objects of a class. It all depends on the use of the class. For example, if you have an Account class, the account number itself may be sufficient in your case to compare for the equality of two Account objects. However, make sure you use the same instance variables in the equals() method to compare for equality and in the hashCode() method to compute hash code value. If your class has reference instance variables, you may call their equals() methods from inside the equals() method of your class. Listing 7-4 shows how to use a reference instance variable comparison inside the equals() method.

使用道具

Lisrelchen 发表于 2015-5-31 05:56:32 |显示全部楼层 |坛友微信交流群
  1. Listing 7-4. Overriding the equals() and hsshCode() Methods in a Class

  2. // SmartCat.java
  3. package com.jdojo.object;

  4. public class SmartCat {
  5.         private String name;

  6.         public SmartCat(String name) {
  7.                 this.name = name;
  8.         }

  9.         /* Reimplement the equals() method */
  10.         public boolean equals(Object otherObject) {
  11.                 // Are they the same?
  12.                 if (this == otherObject) {
  13.                         return true;
  14.                 }

  15.                 // Is otherObject a null reference?
  16.                 if (otherObject == null) {
  17.                         return false;
  18.                 }

  19.                 // Do they belong to the same class?
  20.                 if (this.getClass() != otherObject.getClass()) {
  21.                         return false;
  22.                 }

  23.                 // Get the reference of otherObject is a SmartCat variable
  24.                 SmartCat otherCat = (SmartCat)otherObject;

  25.                 // Do they have the same names
  26.                 boolean isSameName = (this.name == null? otherCat.name == null
  27.                                                    :this.name.equals(otherCat.name) );

  28.                 return isSameName;
  29.         }

  30.         /* Reimplement the hashCode() method, which is a requirement
  31.            when you reimplement equals() method */
  32.         public int hashCode() {
  33.                 return (this.name == null? 0 : this.name.hashCode());
  34.         }
  35. }
复制代码


The SmartCat class has a name instance variable, which is of the type String. The String class has its own version of the equals() method implementation that compares two strings character by character. The equals() method of the SmartCat class calls the equals() method on the name instance variables to check if two names are equal. Similarly, it makes use of the hashCode() method’s implementation in the String class in its hashCode() method.

使用道具

1039264611 发表于 2015-7-1 10:14:08 |显示全部楼层 |坛友微信交流群

[hide]

本帖隐藏的内容

Beginning Java 8 Fundamentals.pdf (9.02 MB, 需要: 20 个论坛币)

已有 1 人评分论坛币 收起 理由
Nicolle + 100 精彩帖子

总评分: 论坛币 + 100   查看全部评分

使用道具

jacksboy 发表于 2018-2-14 22:19:00 |显示全部楼层 |坛友微信交流群
thankthanks

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加JingGuanBbs
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-17 02:54