001package intermediate;
002
003import com.sandwich.koan.Koan;
004
005import static com.sandwich.koan.constant.KoanConstants.__;
006import static com.sandwich.util.Assert.assertEquals;
007
008public class AboutEquality {
009    // This suite of Koans expands on the concepts introduced in beginner.AboutEquality
010
011    @Koan
012    public void sameObject() {
013        Object a = new Object();
014        Object b = a;
015        assertEquals(a == b, __);
016    }
017
018    @Koan
019    public void equalObject() {
020        Integer a = new Integer(1);
021        Integer b = new Integer(1);
022        assertEquals(a.equals(b), __);
023        assertEquals(b.equals(a), __);
024    }
025
026    @Koan
027    public void noObjectShouldBeEqualToNull() {
028        assertEquals(new Object().equals(null), __);
029    }
030
031    static class Car {
032        private String name = "";
033        private int horsepower = 0;
034
035        public Car(String s, int p) {
036            name = s;
037            horsepower = p;
038        }
039
040        @Override
041        public boolean equals(Object other) {
042            // Change this implementation to match the equals contract
043            // Car objects with same horsepower and name values should be considered equal
044            // http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#equals(java.lang.Object)
045            return false;
046        }
047
048        @Override
049        public int hashCode() {
050            // @see http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode()
051            return super.hashCode();
052        }
053    }
054
055    @Koan
056    public void equalForOwnObjects() {
057        Car car1 = new Car("Beetle", 50);
058        Car car2 = new Car("Beetle", 50);
059        // @see Car.equals (around line 45) for the place to solve this
060        assertEquals(car1.equals(car2), true);
061        assertEquals(car2.equals(car1), true);
062    }
063
064    @Koan
065    public void unequalForOwnObjects() {
066        Car car1 = new Car("Beetle", 50);
067        Car car2 = new Car("Porsche", 300);
068        // @see Car.equals (around line 45) for the place to solve this
069        assertEquals(car1.equals(car2), false);
070    }
071
072    @Koan
073    public void unequalForOwnObjectsWithDifferentType() {
074        Car car1 = new Car("Beetle", 50);
075        String s = "foo";
076        // @see Car.equals (around line 45) for the place to solve this
077        assertEquals(car1.equals(s), false);
078    }
079
080    @Koan
081    public void equalNullForOwnObjects() {
082        Car car1 = new Car("Beetle", 50);
083        // @see Car.equals (around line 45) for the place to solve this
084        assertEquals(car1.equals(null), false);
085    }
086
087    @Koan
088    public void ownHashCode() {
089        // As a general rule: When you override equals you should override
090        // hash code
091        // Read the hash code contract to figure out why
092        // http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode()
093
094        // Implement Car.hashCode around line 51 so that the following assertions pass
095        Car car1 = new Car("Beetle", 50);
096        Car car2 = new Car("Beetle", 50);
097        assertEquals(car1.equals(car2), true);
098        assertEquals(car1.hashCode() == car2.hashCode(), true);
099    }
100
101    static class Chicken {
102        String color = "green";
103
104        @Override
105        public int hashCode() {
106            return 4000;
107        }
108
109        @Override
110        public boolean equals(Object other) {
111            if (!(other instanceof Chicken))
112                return false;
113            return ((Chicken) other).color.equals(color);
114        }
115    }
116
117    @Koan
118    public void ownHashCodeImplementationPartTwo() {
119        Chicken chicken1 = new Chicken();
120        chicken1.color = "black";
121        Chicken chicken2 = new Chicken();
122        assertEquals(chicken1.equals(chicken2), __);
123        assertEquals(chicken1.hashCode() == chicken2.hashCode(), __);
124        // Does this still fit the hashCode contract? Why (not)?
125        // Fix the Chicken class to correct this.
126    }
127
128}