== vs equal vs hashCode vs contains

CollectionEqualsHashcodeContainsTest (updated)


class CollectionEqualsHashcodeContainsTest{
    // getReference 
    public static String getReference(Object o){
        return o.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(o));
    }

    public static void main(String[] args)  {

	// primitive type (== 연산자는 값이 같으면 true)
	int i = 1000;
	int j = 1000;
	int k = i;
	System.out.println("i == j " + (i == j));
	System.out.println("i == k " + (i == k));
	System.out.println();

	// reference type (reference가 같으면 true)
	// WARNING: JVM tries to save memory, when the Integer falls in a range (from -128 to 127). Integer v1 = 100, v2 = 100 v1 == v2
	Object o1 = i; // boxing
	Object o2 = j; // boxing
	Object o3 = o1;
	System.out.println(getReference(o1) + " o1=" + o1);
	System.out.println(getReference(o2) + " o2=" + o2);
	System.out.println(getReference(o3) + " o3=" + o3);
	System.out.println("o1 == o2 " + (o1 == o2));
	System.out.println("o1 == o3 " + (o1 == o3));
	System.out.println("o1 equals o2 " + o1.equals(o2));
	System.out.println("o1 equals o3 " + o1.equals(o3));
	System.out.println("o1.hashCode() == o2.hashCode() " + (o1.hashCode() == o2.hashCode()));
	System.out.println("o1.hashCode() == o3.hashCode() " + (o1.hashCode() == o3.hashCode()));
	System.out.println();

	// reference type (== 연산자는 reference가 같으면 true)
	Person p1 = new Person("P",10);
	Person p2 = new Person("P",10);
	Person p3 = p1;
	System.out.println(getReference(p1) + " p1=" + p1);
	System.out.println(getReference(p2) + " p2=" + p2);
	System.out.println(getReference(p3) + " p3=" + p3);
	System.out.println("p1 == p2 " + (p1 == p2));
	System.out.println("p1 == p3 " + (p1 == p3));
	System.out.println("p1 equals p2 " + p1.equals(p2));
	System.out.println("p1 equals p3 " + p1.equals(p3));
	System.out.println("p1.hashCode() == p2.hashCode() " + (p1.hashCode() == p2.hashCode()));
	System.out.println("p1.hashCode() == p3.hashCode() " + (p1.hashCode() == p3.hashCode()));
	System.out.println();

	// String type (== 연산자는 reference가 같으면 true)
	String s1 = "PP"; // String literal을 사용할 경우, pool에서 관리
	String s2 = "PP"; // String literal을 사용할 경우, pool에서 관리
	String s3 = s1;
	String s4 = "P" + "P"; // String literal을 사용할 경우, pool에서 관리
	String s5 = new String("PP");
	String s6 = "PP" + ""; // String literal을 사용할 경우, pool에서 관리
	String s7 = s1 + ""; // String + String literal이라서 새로 생성
	System.out.println(getReference(s1) + " s1=" + s1);
	System.out.println(getReference(s2) + " s2=" + s2);
	System.out.println(getReference(s3) + " s3=" + s3);
	System.out.println(getReference(s4) + " s4=" + s4);
	System.out.println(getReference(s5) + " s5=" + s5);
	System.out.println(getReference(s6) + " s6=" + s6);
	System.out.println(getReference(s7) + " s7=" + s7);

	System.out.println("s1 == s2 " + (s1 == s2));
	System.out.println("s1 == s3 " + (s1 == s3));
	System.out.println("s1 == s4 " + (s1 == s4));
	System.out.println("s1 == s5 " + (s1 == s5));
	System.out.println("s1 == s6 " + (s1 == s6));
	System.out.println("s1 == s7 " + (s1 == s7));
	System.out.println("s1 equals s2 " + s1.equals(s2));
	System.out.println("s1 equals s3 " + s1.equals(s3));
	System.out.println("s1 equals s4 " + s1.equals(s4));
	System.out.println("s1 equals s5 " + s1.equals(s5));
	System.out.println("s1 equals s6 " + s1.equals(s6));
	System.out.println("s1 equals s7 " + s1.equals(s7));
	System.out.println("s1.hashCode() == s2.hashCode() " + (s1.hashCode() == s2.hashCode()));
	System.out.println("s1.hashCode() == s3.hashCode() " + (s1.hashCode() == s3.hashCode()));
	System.out.println("s1.hashCode() == s4.hashCode() " + (s1.hashCode() == s4.hashCode()));
	System.out.println("s1.hashCode() == s5.hashCode() " + (s1.hashCode() == s5.hashCode()));
	System.out.println("s1.hashCode() == s6.hashCode() " + (s1.hashCode() == s6.hashCode()));
	System.out.println("s1.hashCode() == s7.hashCode() " + (s1.hashCode() == s7.hashCode()));
	System.out.println();

	// ArrayList
	System.out.println("pList");
	List<Person> pList = new ArrayList<Person>();
	pList.add(p1);
	pList.add(p2);
	pList.add(p3);
	pList.forEach((p) -> System.out.println(p));
	System.out.println("pList contains p1: " + pList.contains(p1));
	System.out.println("pList contains p2: " + pList.contains(p2));
	System.out.println("pList contains p3: " + pList.contains(p3));
	System.out.println("pList contains new Person: " + pList.contains(new Person("P",10)));
	System.out.println();

	// HashSet의 경우 hashCode가 일치하면 동일한 것으로 간주하여 replace함
	System.out.println("pSet");
	Set<Person> pSet = new HashSet();
	pSet.add(p1);
	pSet.add(p2);
	pSet.add(p3);
	pSet.forEach((p) -> System.out.println(p));
	System.out.println("pSet contains p1: " + pSet.contains(p1));
	System.out.println("pSet contains p2: " + pSet.contains(p2));
	System.out.println("pSet contains p3: " + pSet.contains(p3));
	System.out.println("pSet contains new Person: " + pSet.contains(new Person("P",10)));
	System.out.println();

	// HashMap의 경우 key 값은 hashCode가 일치하면 동일한 것으로 간주하여 replace함
	System.out.println("pMap");
	Map<Person, Integer> pMap = new HashMap<Person, Integer>();
	pMap.put(p1, 1);
	pMap.put(p2, 2);
	pMap.put(p3, 3);
	pMap.forEach((p, e) -> System.out.println(p + " " + e));
	System.out.println("pMap contains p1: " + pMap.containsKey(p1));
	System.out.println("pMap contains p2: " + pMap.containsKey(p2));
	System.out.println("pMap contains p3: " + pMap.containsKey(p3));
	System.out.println("pMap contains new Person: " + pMap.containsKey(new Person("P",10)));
	System.out.println();

	// Array
	System.out.println("pArray");
	Person[] pArray = new Person[3];
	pArray[0] = p1;
	pArray[1] = p2;
	pArray[2] = p3;
	Arrays.asList(pArray).forEach(p -> System.out.println(p));
	System.out.println("pArray contains p1: " + Arrays.asList(pArray).contains(p1));
	System.out.println("pArray contains p2: " + Arrays.asList(pArray).contains(p2));
	System.out.println("pArray contains p3: " + Arrays.asList(pArray).contains(p3));
	System.out.println("pArray contains new Person: " + Arrays.asList(pArray).contains(new Person("P",10)));
	System.out.println();
    }
}