// Examples and commentary on $.equals$ and Strings

public class Equals {

    public static void main(String[] args) {
	
    	A a1 = new A(1);
	A a2 = new A(2);
	A a3 = new A(2);
	
	// Test if $a1$ and $a2$ refer to same object: You will see
	// 'no' because the references point to different objects.
	// The $==$ checks for the equality of the references, as in
	// "Are these references pointing to the same object?"
	if (a1 == a2) System.out.println("Test 1: yes");
	else System.out.println("Test 1: no");
	
	// Test if $a1$ and $a2$ have the same contents: You will see
	// 'no' because the references still point to different objects:
	if (a1.equals(a2)) System.out.println("Test 2: yes");
	else System.out.println("Test 2: no");
	
	// Test if $a2$ and $a3$ have the same contents: Yes, you
	// STILL see 'no' because Java defaults to $==$ when you do
	// NOT override $Object$'s $equals$ method:
	if (a3.equals(a2)) System.out.println("Test 3: yes");
	else  System.out.println("Test 3: no");
	
	// To use $equals$ to test contents, investigate the
	// implementation in Class B. You will see 'yes' this time
	// because the objects have equal contents as defined by the $equals$
	// method that's written in Class B:
	B b1 = new B(1);
	B b2 = new B(1);
	if (b1.equals(b2)) System.out.println("Test 4: yes");
	else  System.out.println("Test 4: no");
	
	// Strings in Java are objects. Strings have $equals$ 
	// defined as equality of contents (each character),
	// so you will get 'yes' again:
	String s1 = new String("hi");
	String s2 = new String("hi");
	if (s1.equals(s2)) System.out.println("Test 5: yes");
	else  System.out.println("Test 5: no");
	
	// Strings literals are trickier. You CAN use $==$ when comparing
	// literals. When you assign a string literal, Java "remembers" that
	// literal. So, if you reuse the literal in the current scope, Java will
	// reuse the same literal! 
	String s3 = "hello";
	String s4 = "hello";
	if (s3==s4) System.out.println("Test 6: yes");
	else System.out.println("Test 6: no");
	
	// Arrays do NOT have $equals$ defined as equality of contents:
	int[] x1 = {1,2,3};
	int[] x2 = {1,2,3};
	if (x1.equals(x2)) System.out.println("Test 7: yes");
	else  System.out.println("Test 7: no");
	// But, there is an $equals$ defined for arrays in java.util.arrays!
    }
}

class A {
    public int k;
    public A(int k) { this.k = k; }
}

class B extends A{
    public B(int k) { super(k); }

    public boolean equals(Object b) {
	if (k==((B)b).k) return true;
	return false;
    }
}

/* Output:
Test 1: no
Test 2: no
Test 3: no
Test 4: yes
Test 5: yes
Test 6: yes
Test 7: no
*/
