포스트

2021-02-14-TIL

2021-02-14-TIL

java.lang.ClassCastException

1
2
List<Integer> waiting = new ArrayList(Arrays.asList(truck_weights));
int temp = waiting.get(0); // 참조할 때 예외발생

truck_weights가 int[]라면 이 코드는 컴파일은 되지만 실행 중에 예외가 난다. 원인은 두 가지가 겹친 것이다.

첫째, Arrays.asList(T... a)는 가변인자 메서드이고, 제네릭 타입 T에는 기본형이 들어갈 수 없다. 그래서 int[]를 넘기면 원소 하나하나가 T가 되는 것이 아니라, 배열 전체가 원소 하나(T = int[])로 취급된다. 결과는 List<Integer>가 아니라 원소가 하나뿐인 List<int[]>다.

둘째, new ArrayList(...)에 타입 인자(<>)를 빠뜨려 raw 타입으로 만들었다. raw 타입은 제네릭 검사를 건너뛰므로 List<int[]>가 List<Integer> 변수에 경고만 남기고 들어간다. 그 뒤 waiting.get(0)을 int에 담으려고 컴파일러가 넣어 둔 Integer 캐스팅이 실행되는 순간, 실제 객체가 int[]이므로 ClassCastException이 난다. Javadoc의 설명대로 이 예외는 객체를 그 객체가 인스턴스가 아닌 타입으로 캐스팅하려 할 때 던져진다.

1
2
3
4
// 기본형 배열을 List<Integer>로 바꾸는 방법
List<Integer> waiting = Arrays.stream(truck_weights)
        .boxed()
        .collect(Collectors.toList());

<>를 붙여 new ArrayList<>(Arrays.asList(truck_weights))로 썼다면 타입이 맞지 않는다는 컴파일 오류로 미리 알 수 있었다. raw 타입 경고를 무시하지 말아야 하는 이유다. 배열과 리스트의 차이는 Java에서 배열과 리스트를 어떻게 구분해야 하는가에 정리했다.


Permutaion using Java

순열은 n개 중 순서를 고려해 r개를 나열하는 경우다. 재귀로 구현할 때는 각 자리에 아직 쓰지 않은 원소를 하나씩 놓아 보고, 다음 자리로 넘어갔다가 돌아오면 원래대로 되돌린다(백트래킹). n개 전체를 나열하는 경우의 수는 n!이므로 n이 10을 넘으면 금방 느려진다. 자세한 내용은 순열(Permutation)에 있다.


Combinations using Java

조합은 순서를 고려하지 않고 n개 중 r개를 고르는 경우다. 순열과 달리 같은 원소 묶음을 한 번만 세야 하므로, 재귀할 때 “다음 원소는 지금 고른 원소보다 뒤에서만 고른다”는 시작 인덱스를 넘긴다. 이 조건 하나로 {1, 2}와 {2, 1}이 중복으로 나오지 않는다.

1
2
3
4
5
6
7
8
9
10
11
void combine(int[] arr, int start, int r, Deque<Integer> picked) {
    if (picked.size() == r) {
        System.out.println(picked);
        return;
    }
    for (int i = start; i < arr.length; i++) {
        picked.addLast(arr[i]);
        combine(arr, i + 1, r, picked);   // i 다음부터만 고른다
        picked.removeLast();
    }
}

Char to Int

char를 int에 그대로 대입하면 숫자 값이 아니라 문자 코드가 들어간다. '7'을 int로 바꾸면 7이 아니라 55다. 숫자 문자를 그 숫자로 바꾸려면 '7' - '0'처럼 '0'의 코드를 빼거나, Character.getNumericValue('7'), Character.digit('7', 10)을 쓴다. '0'부터 '9'까지의 문자 코드가 연속되어 있어서 빼기만으로 계산된다.

게임엔진 블랙북, 클럽하우스

참고한 자료외부 출처 3

외부 출처

이 글은 저작권자의 CC BY 4.0 라이선스를 따릅니다.

댓글

아직 댓글이 없습니다