[추천] Set of Set 문제 및 Set.hashCode()고찰
문제
출력결과는 무엇일까요?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<Set<Integer>> sets = new HashSet<>();
Set<Integer> set1 = new HashSet<>();
set1.add(1);
set1.add(11);
sets.add(set1);
System.out.println(sets.size());
set1.add(111);
sets.remove(set1);
System.out.println(sets.size());
}
}
|
cs |
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
정답
해설
HashSet.remove() 소스코드를 계속 따라가보면 HashMap.removeEntryForKey() 까지 이어지고,
여기서 코드를 잘보면 hashCode() 값 비교를 통해 remove를 시도하고 있습니다.
그런데 현재 Set 의 멤버도 Set 이므로 HashSet.hashCode() 를 살펴봐야합니다.
해당 소스코드를 보면 충격적이게도,
반복문을 돌며 멤버 전체의 hashCode() 를 더해 리턴하고 있습니다.
따라서 Set 의 내용물(멤버)이 바뀌면 hashCode() 값도 바뀌게 됩니다.
문제로 돌아가보면,
16라인에서 set1 의 내용물이 바뀜과 동시에 set1 의 hashCode() 값도 변해버려서
17라인에서 remove() 가 set1 을 찾지못해 지우는데 실패하게된 것입니다.
'뿌리튼튼 CS > Java' 카테고리의 다른 글
심심풀이 문제6 - 상속과 오버라이딩 (Heritage & Overriding) (0) | 2016.10.04 |
---|---|
심심풀이 문제5 - 예외 처리 흐름 (Exception handling flow) (0) | 2016.10.04 |
심심풀이 문제4 - Object Assign (객체 대입) (0) | 2016.10.04 |
심심풀이 문제3 - Call by Value vs Call by Reference (0) | 2016.10.04 |
심심풀이 문제2 - String (0) | 2016.08.02 |
심심풀이 문제6 - 상속과 오버라이딩 (Heritage & Overriding)
문제
출력 결과는 무엇일까요?
1 2 3 4 5 6 7 8 9 10 11 | public class Person { public String name = "CGun"; public String getName() { return name; } public int getAge() { return 29; } } | cs |
1 2 3 4 5 6 7 | public class Man extends Person { public String name = "CGun2"; public int getAge() { return 30; } } | cs |
1 2 3 4 5 6 7 | public class Test { public static void main(String[] args) { Man m = new Man(); System.out.println(m.getName() + ", " + m.getAge()); } } | cs |
정답
해설
틀린 분 많으시죠?
상속시, 함수 오버라이딩은 많이들 아시겠지만 변수 오버라이딩에 대해서는 모르는 분이 많으실 겁니다.
변수는 오버라이딩되지 않습니다. (자식에 의해 덮어써지지 않고 계속 살아있습니다)
재미있는 결과를 더 알려드리겠습니다.
1 2 3 4 | Man m = new Man(); System.out.println(m.name); // CGun2 System.out.println(((Person) m).name); // CGun | cs |
3라인은 Man 의 name 값인 "CGun2" 가 출력되며,
4라인은 Person 의 name 값인 "CGun" 이 출력됩니다.
'뿌리튼튼 CS > Java' 카테고리의 다른 글
[추천] Set of Set 문제 및 Set.hashCode()고찰 (0) | 2019.04.18 |
---|---|
심심풀이 문제5 - 예외 처리 흐름 (Exception handling flow) (0) | 2016.10.04 |
심심풀이 문제4 - Object Assign (객체 대입) (0) | 2016.10.04 |
심심풀이 문제3 - Call by Value vs Call by Reference (0) | 2016.10.04 |
심심풀이 문제2 - String (0) | 2016.08.02 |
심심풀이 문제5 - 예외 처리 흐름 (Exception handling flow)
문제
출력 결과는 무엇일까요?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public class Test { public static void main(String[] args) { int[] arr = new int[2]; try { arr[0] = 0; System.out.println(arr[0]); arr[1] = 1; System.out.println(arr[1]); arr[2] = 2; System.out.println(arr[2]); } catch (NullPointerException e) { System.out.println(3); } catch (ArrayIndexOutOfBoundsException e) { System.out.println(4); } catch (Exception e) { System.out.println(5); } finally { System.out.println(6); } System.out.println(7); } } | cs |
정답
해설
1. Exception 발생 즉시 try 문은 건너뛰고 catch 문으로 간다.
2. catch 가 여러개이면 맨 위부터 현재 Exception 을 잡아줄 수 있는지 체크하며,
잡아줄 수 있는 최초의 catch 문만 수행하고 finally 로 간다.
3. finally 문이 있다면 수행 후 빠져나가고 프로그램은 아래로 계속 진행된다.
'뿌리튼튼 CS > Java' 카테고리의 다른 글
[추천] Set of Set 문제 및 Set.hashCode()고찰 (0) | 2019.04.18 |
---|---|
심심풀이 문제6 - 상속과 오버라이딩 (Heritage & Overriding) (0) | 2016.10.04 |
심심풀이 문제4 - Object Assign (객체 대입) (0) | 2016.10.04 |
심심풀이 문제3 - Call by Value vs Call by Reference (0) | 2016.10.04 |
심심풀이 문제2 - String (0) | 2016.08.02 |
심심풀이 문제4 - Object Assign (객체 대입)
문제
출력 결과는 무엇일까요?
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public int getAge() { return age; } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 | public class Test { public static void main(String[] args) { Person p1 = new Person("CGun", 29); Person p2 = p1; p1.age = 30; p2.name = "CGun2"; System.out.println(p1.name + ", " + p1.age); System.out.println(p2.name + ", " + p2.age); } } | cs |
정답
해설
Person p2 = p1; 실행시에 일어나는 동작을 아는 것이 중요하다.
p1 객체를 복사하여 p2 에 할당하는 것이 아니라,
p1 객체와 같은 곳을 p2 가 가리키게 하는 구문이다.
즉, reference 값만 복사된다는 뜻이며 결국 p1 과 p2 가 같은 객체를 가리키고 있다는 뜻이다.
'뿌리튼튼 CS > Java' 카테고리의 다른 글
심심풀이 문제6 - 상속과 오버라이딩 (Heritage & Overriding) (0) | 2016.10.04 |
---|---|
심심풀이 문제5 - 예외 처리 흐름 (Exception handling flow) (0) | 2016.10.04 |
심심풀이 문제3 - Call by Value vs Call by Reference (0) | 2016.10.04 |
심심풀이 문제2 - String (0) | 2016.08.02 |
생성자를 쓰는 이유. 생성자의 필요성 (Why use constructors) (0) | 2016.08.02 |
심심풀이 문제3 - Call by Value vs Call by Reference
문제
출력 결과는 무엇일까요?
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public int getAge() { return age; } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class Test { static void increase(Person p, int weight) { p.age = 30; weight = 70; } public static void main(String[] args) { Person p = new Person("CGun", 29); int weight = 60; increase(p, weight); System.out.println(p.age + ", " + weight); } } | cs |
정답
해설
객체 변수는 Call by Reference 로 동작하므로 의도대로 값이 들어갔지만,
일반 변수는 Call by Value 로 동작하므로 increase 함수 내부 변수만 값이 증가하며
해당 함수가 종료되면 내부 변수는 증발한다.
'뿌리튼튼 CS > Java' 카테고리의 다른 글
심심풀이 문제5 - 예외 처리 흐름 (Exception handling flow) (0) | 2016.10.04 |
---|---|
심심풀이 문제4 - Object Assign (객체 대입) (0) | 2016.10.04 |
심심풀이 문제2 - String (0) | 2016.08.02 |
생성자를 쓰는 이유. 생성자의 필요성 (Why use constructors) (0) | 2016.08.02 |
심심풀이 문제1 - Object.equals() (0) | 2016.07.16 |
심심풀이 문제2 - String
문제
출력 결과는 무엇일까요?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class Test { public static void main(String[] args) { String a = "CGun"; String b = new String("CGun"); String c = a; String d = b; a += " Good"; b += " Good"; System.out.println(c); System.out.println(d); } } | cs |
정답
해설
"java string immutable" 혹은 "java string 불변"
으로 검색해보시면 많은 정보를 얻으실 수 있습니다.
'뿌리튼튼 CS > Java' 카테고리의 다른 글
심심풀이 문제4 - Object Assign (객체 대입) (0) | 2016.10.04 |
---|---|
심심풀이 문제3 - Call by Value vs Call by Reference (0) | 2016.10.04 |
생성자를 쓰는 이유. 생성자의 필요성 (Why use constructors) (0) | 2016.08.02 |
심심풀이 문제1 - Object.equals() (0) | 2016.07.16 |
[Collection] ArrayList vs Vector (0) | 2016.02.01 |
생성자를 쓰는 이유. 생성자의 필요성 (Why use constructors)
이유1: 객체 생성시 초기화 작업
일반 변수들의 경우, 생성자 없이 전역에서 바로 초기화를 해줘도 됩니다.
하지만 불가능해서 꼭 생성자에서 초기화를 해줘야하는 경우도 있습니다.
1 2 3 4 5 | import java.io.FileInputStream; public class FileHandler { private FileInputStream fis = new FileInputStream("\tmpFile"); } | cs |
위 코드는 컴파일에러가 발생하며, 아래와 같이 수정해야 합니다.
1 2 3 4 5 6 7 8 9 10 | import java.io.FileInputStream; import java.io.FileNotFoundException; public class FileHandler { private FileInputStream fis; public FileHandler() throws FileNotFoundException { fis = new FileInputStream("\tmpFile"); } } | cs |
new FileInputStream() 에서 FileNotFoundException 을 throw 하므로 받아줘야 하기 때문입니다.
이유2: 객체 생성시 필수입력값을 강제하기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public class Human { private String name; private String nickName; private int age; public Human(String name) { this.name = name; } public void setNickName(String nickName) { this.nickName = nickName; } public void setAge(int age) { this.age = age; } } | cs |
사람 객체를 생성시 name 을 필수입력 항목으로 강제하는 코드입니다.
그외 nickName 과 age 는 원하는 경우에 한해 set 함수로 입력할 수 있습니다.
'뿌리튼튼 CS > Java' 카테고리의 다른 글
심심풀이 문제3 - Call by Value vs Call by Reference (0) | 2016.10.04 |
---|---|
심심풀이 문제2 - String (0) | 2016.08.02 |
심심풀이 문제1 - Object.equals() (0) | 2016.07.16 |
[Collection] ArrayList vs Vector (0) | 2016.02.01 |
String vs StringBuilder vs StringBuffer (2) | 2016.01.28 |
심심풀이 문제1 - Object.equals()
문제
출력 결과는 무엇일까요?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public class Test { public static void main(String[] args) { User a = new User("CGun", 29); User b = new User("CGun", 29); User c = a; System.out.println(a == b); System.out.println(a == c); System.out.println(a.equals(b)); } public static class User { private String name; private int age; public User(String name, int age) { this.name = name; this.age = age; } } } | cs |
정답
해설
위 소스코드를 자세히 보시면 User 클래스 안에 equals() 메서드가 없습니다.
근데 왜 컴파일 에러가 안날까요?
Java 에서 모든 클래스들은 기본적으로 Object 클래스를 상속받습니다.
extends Object 가 생략되었을 뿐입니다.
그리고 이 Object 클래스 안에 equals() 메서드가 존재하고 있으며, 소스코드는 아래와 같습니다.
네. 따라서 a.equals(b) 는 a == b 와 완전히 같습니다.
String.equals() 문제에 익숙한 분들을 향한 함정 문제였습니다.
참고
출처
'뿌리튼튼 CS > Java' 카테고리의 다른 글
심심풀이 문제2 - String (0) | 2016.08.02 |
---|---|
생성자를 쓰는 이유. 생성자의 필요성 (Why use constructors) (0) | 2016.08.02 |
[Collection] ArrayList vs Vector (0) | 2016.02.01 |
String vs StringBuilder vs StringBuffer (2) | 2016.01.28 |
Array size in Loops (0) | 2015.07.31 |