'2015/09'에 해당되는 글 13건

  1. 2015.09.26 쉘 정렬
  2. 2015.09.26 퀵정렬
  3. 2015.09.26 삽입정렬
  4. 2015.09.26 선택정렬
  5. 2015.09.26 버블정렬
  6. 2015.09.24 HashTable과 HashMap 순회방법
  7. 2015.09.24 재귀호출 - Recursive Call
  8. 2015.09.23 원형 큐 - Circular Queue 2
  9. 2015.09.22 더블 체킹 락킹(Double Checking Locking)
  10. 2015.09.14 Call By Value vs Call By Reference

쉘 정렬

알고리즘 2015. 9. 26. 15:20

쉘정렬(Shell Sort)

쉘 정렬은 삽입정렬의 단점을 보완하기 위해 만든 정렬 방법이다.

 

삽입 정렬을 하기 전에 미리 정리를 해놓자!”

 

어떻게 정리를 한단 말인가?

삽입 정렬은 모든 원소에 대해서 검사를 하지만, 쉘 정렬의 경우, 앞에서 구한 어떠한 간격만큼 떨어진 원소에 대해서 삽입정렬을 먼저 수행하고, 그 간격을 점점 줄여 계속 삽입정렬을 하는 방법을 취한다.

간격은 결국 1이 될 것이며, 1이 되는 때는 곧, 삽입 정렬을 수행하는 것과 동일하다.

 

45, 39, 98, 15, 52, 44, 33, 28, 40, 38, 77, 68, 11, 43

위와 같은 수들이 있다. 간격을 5, 3, 1로 놓고 삽입 정렬을 시작할 것이다.

 

1) 간격이 5일 경우, 같은 묶음 끼리 같은 색으로 표시해보면

45, 39, 98, 15, 52, 44, 33, 28, 40, 38, 77, 68, 11, 43

위와 같다.

묶음 1 : 45, 44, 77 => 44, 45, 77

묶음 2 : 39, 33, 68 => 33, 39, 68

묶음 3 : 98, 28, 11 => 11, 28, 98

묶음 4 : 15, 40, 43 => 15, 40, 43

묶음 5 : 52, 38 => 38, 52

각 묶음으로 정렬을 수행 한다.

44, 33, 11, 15, 38, 45, 39, 28, 40, 52, 77, 68, 98, 43

 

2) 간격이 3일 경우, 같은 묶음 끼리 같은 색으로 표시해보면

44, 33, 11, 15, 38, 45, 39, 28, 40, 52, 77, 68, 98, 43

 

묶음1 : 44, 15, 39, 52, 98 => 15, 39, 44, 52, 98

묶음2 : 33, 38, 28, 77, 43 => 28, 33, 38, 43, 77

묶음3 : 11, 45, 40, 68 => 11, 40, 45, 68

 

각 묶음으로 정렬을 수행한다.

15, 28, 11, 39, 33, 40, 44, 38, 45, 52, 43, 68, 98, 77

 

3) 간격이 1일 경우

보통의 삽입 정렬을 수행한다.

 

그렇다면 간격은 어떻게 설정하나?

간격을 어떻게 설정하는지에 따라서 성능에 중요한 영향을 끼친다. 배열의 길이를 토대로 잡는다면

첫 번째 간격을 N/2, 두 번째 간격을 N/4 ... 등으로 잡는 방법이 있다.

 

시간 복잡도?

삽입정렬의 O(n^2)보다는 우수하지만 가장 효율적인 정렬 알고리즘의 O(nlogn)에는 미치지 못한다.

O(n^(4/3)) 정도이다. 또한 increments sequence를 어떻게 하느냐에 따라 성능이 좌우되는데 sequence가 좋지 않는 최악의 경우 복잡도는 O(n^2)가 되어 버린다.






'알고리즘' 카테고리의 다른 글

최소 비용 스패닝 트리 - Prim알고리즘  (0) 2015.11.20
이진탐색(Binary Search)  (0) 2015.10.16
퀵정렬  (0) 2015.09.26
삽입정렬  (0) 2015.09.26
선택정렬  (0) 2015.09.26
Posted by slender ankles
,

퀵정렬

알고리즘 2015. 9. 26. 15:19

퀵정렬(Quick Sort)

데이터 집합 내에서 한 피벗 값(pivot value)을 고른 다음 그걸 기준으로 두 개의 부분집합으로 나눈다.

한 쪽 부분집합에는 피벗 값보다 작은 것만, 다른 부분 집합에는 큰 것만 넣는다. 더 이상 쪼갤 부분집합이 없을 때

까지 각각의부분집합에 대해 피벗/쪼개기 작업을 재귀적으로 적용한다. 그렇게 하고 나면 최종적으로 정렬된 데이

터 집합이 만들어진다.


퀵정렬의 효율

퀵정렬은 어떤 피벗 값을 고르는지에 따라 성능이 결정된다. 가장 이상적인 피벗 값 은 전체 데이터를 절반씩으로

쪼갤 수 있는 값이다. 피벗 값을 고르고 배열을 쪼갤 때마다 각 원소에 대해 상수 시간 연산을 적용해야 한다. 각 

원소마다 이 작업을  몇 번씩 할까? 최선의 경우는 재귀호출이 이뤄질 때마다 부분 리스트의 크기가 절반씩으로 

줄고, 부분 리스트의 크기가 1이 되면 재귀호출이 끝난다.즉 각 원소에 대해 상수 시간 연산을 하는 횟수 n, n을 

1이 나올 때까지 반복해서 2로 나누는 횟수, 즉 log(n)이다. n개의 원소에 대해 log(n)번씩 연산을 수행하므로 최선

의 경우 복잡도는 O(n log(n))이다. 


하지만 피벗을 잘못 고르면 어떠게 되나?

최악의 경우라면 데이터 집합의 최소값을 피벗 값으로 고를 것이고, 그러면 한쪽 부분집합은 빈 집합이고 다른 집

합에는 n-1개 (피벗 값을 제외한 나머지)가 들어간다. 그러면 재귀호출 횟수가 O(n)이고(균형 전혀 잡히지 않은 

트리는 연결 리스트와 똑같아지는 것과 마찬가지), 최악의 경우 복잡도는 O(n^2)이 된다. 이는 선택 정렬이나 삽입 정렬과 마찬가지 속도다. 


어떻게 구현하나?

    public static void swap(int[] arr, int left, int right){
        int temp = arr[left];
        arr[left] = arr[right];
        arr[right] = temp;
    } 
    public static void quickSort(int[] arr, int left, int right){
        int index = partition(arr, left, right);
        if(left < index - 1){        // 왼쪽 파티션 정렬
            quickSort(arr, left, index - 1);
        }
        if(index < right){            // 오른쪽 파티션 정렬
            quickSort(arr, index, right);
        }
    }
    public static int partition(int[] arr, int left, int right){
        int pivot = arr[(left + right)/ 2];    // 분할 기준 원소 선정
        while(left <= right){
            // 왼쪽 파티션 원소 가운데 오른쪽 파티션으로 옮겨야 하는 원소 탐색
            while(arr[left] < pivot) left++;
            // 오른쪽 파티션 원소 가운데 왼쪽 파티션으로 옮겨야 하는 원소 탐색
            while(arr[right] > pivot) right--;
            
            // 원소들의 자리를 바꾸고 left와 right를 이동
            if(left <= right){
                swap(arr, left, right);
                left++;
                right--;
            }
        }
        return left;
    }
cs


퀵정렬 과정
다음과 같이 4,7,2,6,1,3,5라는 수들을 퀵 소트를 통해 정렬해보겠습니다.

우선, [0] ~ [6] 범위에서의 퀵소트를 합니다.

pivot을 선택하는 기준은 각자의 판단입니다. 맨 앞, 혹은 맨뒤, 중간을 선택해도 무방합니다.

저는 중간 값을 피봇으로 선택했습니다.

이제 6을 기준으로 6보다 작은 수는 6 왼쪽에, 6보다 큰 수는 6보다 오른쪽에 배치시킵니다.

코드를 따라가 보며 손으로 써보는 것이 중요합니다.



분할정복의 과정으로 6이라는 피봇을 기준으로 [0] ~ [5](이전 pivot) - 1까지의 범위를 소팅해줍니다. 

pivot은 값 2가 될 것이며, 2를 기준으로 왼쪽은 2보다 작은 수, 오른쪽은 2보다 큰 수가 되게 합니다.


마찬가지로 6의 인덱스인 [5] ~ [6] 까지도 소팅해줍니다.([5] ~ [6]은 정렬되어 있기 때문에 그림상에서는 표현하지 않았습니다.)



이제는 다시 [0] ~ [1] 인덱스 범위와 [2] ~ [4] 범위를 퀵 소트 해줍니다.

그 다음 [2]와 [3] ~ [4] 인덱스 범위를 퀵 소트 해줍니다.


후에 조금 더 쉽고 자세하게 퀵소트의 과정을 다시 설명하겠습니다.

코드를 기준으로 설명을 하자면, 

분할 정복할 범위에서 left, right를 양끝의 인덱스로 잡아 놓고

피봇값보다 크거나 같은 수를 만날 때까지 left를 증가시켜줍니다.

반대로 피봇값보다 작거나 같은 수를 만날 때까지 right를 감소시켜줍니다.

그리고 이 두 수를 바꾸어 주는 겁니다. 이 과정을 분할 정복하여 전체 array를 소팅해주는 것입니다.









'알고리즘' 카테고리의 다른 글

이진탐색(Binary Search)  (0) 2015.10.16
쉘 정렬  (0) 2015.09.26
삽입정렬  (0) 2015.09.26
선택정렬  (0) 2015.09.26
버블정렬  (0) 2015.09.26
Posted by slender ankles
,

삽입정렬

알고리즘 2015. 9. 26. 15:19

삽입정렬

한 번에 한 원소씩 이미 정렬된 다른 원소들과 비교하여 새 원소를 제 위치에 삽입하는 식으로 정렬된 배열을 

만든다.


삽입정렬의 효율

삽입 정렬은 최선의 경우, 즉 리스트가 이미 정렬돼 있을 때, O(n)이다.

이미 정렬된 리스트에 새 원소를 추가할 때는 삽입 정렬이 매우 효율적이다. 

그러나 평균 및 최악의 경우에는 O(n^2)이기 때문에 무작위로 정렬된 많은 데이터를 처리하기에는 좋은 알고리즘은 아니다.


    private static int[] insertion_sort(int[] arr){
        for(int i = 1;i<arr.length;i++){
            for(int j = 0;j<i;j++){
                if(arr[i] < arr[j]){
                    arr = swap(arr, i, j);
                }
            }
        }
        return arr;
    }
cs


'알고리즘' 카테고리의 다른 글

쉘 정렬  (0) 2015.09.26
퀵정렬  (0) 2015.09.26
선택정렬  (0) 2015.09.26
버블정렬  (0) 2015.09.26
재귀호출 - Recursive Call  (0) 2015.09.24
Posted by slender ankles
,

선택정렬

알고리즘 2015. 9. 26. 15:19

선택정렬

배열(또는 리스트)의 첫 번째 원소에서 시작하여 배열 전체를 훑으면서 가장 작은 키를 가지는 원소를 찾아서 첫 번째 원소와 맞바꾼다. 두 번째 원소로 넘어감녀서 마지막 원소에 이르기까지 같은 작업을 반복한다. 


선택정렬의 효율

비교 횟수를 따져보면 첫 번째 원소를 맞바꿀 때 (n-1)번의 비교, 그 다음 두 번째 원소에서 (n-2)번의 비교,

.... 1번의 비교가 수행되며, (n-1) + (n-2) + ... + 1 이므로 n(n+1)/2임을 알 수 있다. 

따라서 선택 정렬의 알고리즘의 최선, 평균, 최악 모두 O(n^2)이다. 


    private static int[] selection_sort(int[] arr){
        for(int i = 0;i<arr.length;i++){
            int min_value = arr[i];
            for(int j = i;j<arr.length;j++){
                if(arr[j] < min_value){
                    arr = swap(arr, i, j);
                }
            }
        }
        return arr;
    }
cs



'알고리즘' 카테고리의 다른 글

퀵정렬  (0) 2015.09.26
삽입정렬  (0) 2015.09.26
버블정렬  (0) 2015.09.26
재귀호출 - Recursive Call  (0) 2015.09.24
빅 오 분석법 O(n)  (0) 2015.07.23
Posted by slender ankles
,

버블정렬

알고리즘 2015. 9. 26. 14:46

버블정렬이란?

인접한 두 수의 크기를 비교해 뒤로 큰 수(오름차순) 또는 작은 수(내림차순)를 뒤로 보내는 정렬 방법입니다.


시간복잡도는?

시간복잡도는 O(N^2)입니다. 모든 수에 대해서 N번만큼 비교를 하기 때문입니다. 

최악의 경우? O(N^2) 

최선의 경우? O(N^2)

보통의 경우? O(N^2)


공간복잡도는?

정렬을 위해 입력받은 배열 이외에는 특별한 저장공간을 할당할 필요가 없습니다. 

그래서 기존의 입력되는 배열인 N개만 필요하므로 O(N)입니다.


어떻게 구현하나?

    private static int[] bubble_sort(int[] arr){
        for(int i = arr.length - 1; i > 0;i--){
            for(int j = 0;j<i;j++){
                if(arr[j] > arr[j + 1]){
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1= temp;
                }
            }
        }
        return arr;
    }
cs


<기준수>


<for문 분석하기! => i = 4, j = 0 ~ 3>


<for문 분석하기! => i = 3, j = 0 ~ 2>


<>



<>




'알고리즘' 카테고리의 다른 글

삽입정렬  (0) 2015.09.26
선택정렬  (0) 2015.09.26
재귀호출 - Recursive Call  (0) 2015.09.24
빅 오 분석법 O(n)  (0) 2015.07.23
조합알고리즘의 최적화  (0) 2015.04.30
Posted by slender ankles
,

HashTable 순회 방법

        Hashtable<StringString> hashtable = new Hashtable<StringString>();
        hashtable.put("1""a");
        hashtable.put("2""b");
        hashtable.put("3""c");
        hashtable.put("4""d");
        
        Enumeration<String> enumKey = hashtable.keys();
        
        while(enumKey.hasMoreElements()){
            String key = enumKey.nextElement();
            String value = hashtable.get(key);
            System.out.println(value);
        }    
cs


HashMap 순회방법
        HashMap<StringString> hashmap = new HashMap<StringString>();
        hashmap.put("1""a");
        hashmap.put("2""b");
        hashmap.put("3""c");
        hashmap.put("4""d");
        
        for(Entry<StringString> entry : hashmap.entrySet()){
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + " - " + value);
        }
cs


Posted by slender ankles
,

재귀호출이란 무엇인가?

자신 자신을 호출하는 형태의 함수를 말한다.

어디에 쓰이는가?

같은 로직을 반복적으로 호출하는 작업에 많이 쓰인다. 정렬이나, 검색, 그래프의 종주에 보통 쓰인다.

재귀 함수는 어떻게 구성되는가?

재귀 호출은 자기 자신을 호출하여 하위 작업을 수행하게 되는데, 재귀 함수를 분석하고 설계하다보면 자기 자신을 호출하지 않고도 답이 나오는 하위 작업이 있다. 이를 base case라고 한다

쉽게 설명하자면 "Factorial에서 n이 1일 때는 1을 리턴해준다."

재귀 알고리즘에는 재귀 케이스(recursive)와 기본 케이스(base case)로 나뉜다. 이 두 개를 어떻게 잘 설계할 수 있는지 생각해보면 된다.

재귀 함수의 장점은 무엇인가?

재귀 함수는 보통 코드를 간결하게 만들어준다.

예를 들어 보겠다. 

팩토리얼을 구현하는  재귀적인 방법과  반복적인 방법이다.

// recursive하게 구현
    public static int Factorial(int n){
        if(n == 1)
            return 1;
        else
            return n * Factorial(n - 1);
    }
    
    // iterative하게 구현
    public static int Factorial_Iterative(int n){
        int result = 1;
        for(int i = 1;i<=n;i++){
            result *= i;
        }
        return result;
    }
cs


재귀 함수의 단점은 무엇인가?

보통 팩토리얼과 같은 경우에 간단한 로직을 실행하는데 드는 비용보다 재귀함수를 스택에 쌓고 호출하는데 드는 시간적 비용이 더 많이 든다. 그래서 반복적인 루틴을 사용하는 코드보다 재귀적인 루틴을 사용하는 코드가 더 시간이 오래 걸린다.

보통 재귀함수로 실행 할 수 있는 로직은 반복적인 코드로도 만들 수 있다. 


재귀함수를 통해서 간결하게 코드를 만들 수 있는 예 - 이진 검색

) 1, 2, 3, 4, 5, 6, 7, 8, 9, 10이 있을 때 9를 몇 번만에 찾을 수 있을까?

public static int binary_search(int[] arr, int first, int last, int number, int target){
        int mid = (first + last) / 2;
        if(arr[mid] == target || arr[first] == target || arr[last] == target)
            return number;
        if(target < arr[mid]){
            return binary_search(arr, first, mid, number+1, target);
        }else{
            return binary_search(arr, mid + 1, last, number + 1, target);
        }
}
cs

이진 검색을 위와 같이 구현해봤다.

특정 범위의 시작과 끝, 또는 중간 값이 해당하는 값이면 탐색을 끝낸다. 

매번 인자에 재귀함수의 수행 횟수를 인자로 넘기는데, 답이 나오면 이 값을 리턴해주면 몇 번만에 검색 되었는지를 알 수 있다.


*참고 : 이진탐색의 시간복잡도와 특징*

이진 탐색(검색) 시간 복잡도 : Log(n)

특징 : 탐색 리스트가 정렬되어 있어야 된다는 점





'알고리즘' 카테고리의 다른 글

선택정렬  (0) 2015.09.26
버블정렬  (0) 2015.09.26
빅 오 분석법 O(n)  (0) 2015.07.23
조합알고리즘의 최적화  (0) 2015.04.30
2차원 배열의 경우의 수 구하기  (0) 2015.04.28
Posted by slender ankles
,

큐 자료구조의 특징은 First In First Out이라는 것이다. 

큐를 구현하기 위해 보통 선형 큐를 구현하는데 

배열의 메모리 공간에서 front 포인터와 rear포인터를 규칙에 맞게 이동하면서 구현하게 된다.

enqueue : rear + 1 , dequeue : front + 1

과 같이 포인터를 조정해준다. 


그렇다면 원형큐는 무엇인가?

선형 큐를 구현하면서 문제는 주기적으로 enqueue 되고 dequeue되면 인덱스를 조정하면서 front가 점차 뒤로 가게되면서 앞쪽 메모리 공간을 효율적으로 사용 할 수 없게 된다. 그래서 메모리 공간을 다 쓰면 다시 앞으로 돌아와서 메모리공간에 enqueue, dequeue할 수 있는 원형 큐가 필요하게 된 것이다. 


원형큐는 어떤식으로 구현하나?

우선 10의 크기를 가진 큐를 사용하기 위해서는 11만큼의 배열 사이즈를 할당해야 한다. 

큐의 첫 번째 인덱스는 항상 비워두어야 하기 때문이다. 첫 번째 인덱스를 비워놓음으로서 원형 큐가 공백상태인지 포화상태인지 판단 할 수 있게 된다.


공백 상태 : front == rear

포화 상태 : front % M == (rear + 1) % M


 

 초기상태

FRONT = 0

REAR = 0

 

 A, B가 차례로 삽입되면서 REAR의 포인터가 하나씩 상승했다.

FRONT = 0

REAR = 2 


 

 10개의 메모리 공간이 가득 찼다.

그러므로 큐에 더 이상 값을 삽입할 수 없는 상태다.

ISFULL상태

(REAR + 1) % SIZE == FRONT % SIZE

이 만족되므로 더 이상 푸시할 수 없다.


 

 DEQUEUE했다.

FRONT = (FRONT + 1) % SIZE

를 실행해준다. 이제 가득 차 있는 상태가 아니다.

 




 다시 하나 더 ENQUEUE해준다.

다시 가득 찬 상태가 되었다.


 


 모두 DEQUEUE해주면서 FRONT를 하나씩 증가시켜준다. 다시 제자리로 돌아온다.

FRONT == REAR 조건이므로 더 이상 큐를 DEQUEUE할 수 없다.




코드로 표현하면 다음과 같다. 

ISFULL상태와 ISEMPTY상태를 따로 빼지 않았다.

<CIRCULAR QUEUE 소스 코드>

public class CirCularQueue {
    final int ArraySize = 10;
    int front = 0, rear = 0;
    int[] arr = new int[ArraySize];
    public void Enqueue(int data){
        if((rear + 1) % ArraySize ==  front % ArraySize){
            System.out.println("CircularQueue Full!!");
        }
        else{
            rear = (rear + 1) % ArraySize;
            arr[rear] = data;
        }
    }
    public void Dequeue(){
        if(front == rear){
            System.out.println("CircularQueue Empty!!");
        }
        else{
            front = (front + 1) % ArraySize;
            System.out.println(arr[front]);
        }
    }
    public void showArray(){
        for(int i = 1;i<ArraySize;i++){
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }
    public int getFront(){
        return arr[front + 1];
    }
}
cs





'자료구조' 카테고리의 다른 글

해시(Hash)  (0) 2015.07.01
B-Tree  (0) 2015.07.01
우선순위 큐 - 힙(Heap)  (0) 2015.07.01
트리(Tree)  (0) 2015.07.01
위상정렬  (0) 2015.07.01
Posted by slender ankles
,

싱글톤 패턴의 심화판

[클래스 생성과 동시에 초기화하기]

public class Singleton {
    
    private static Singleton singleton = new Singleton();
    
    public static Singleton getInstance(){
        return singleton;
    }
    private Singleton(){}
 
}
cs

히 많이 쓰는 싱글톤 구현방법이다. 하지만 싱글톤이 정작 필요로 할 때 생성되는 편이 낫지 않을까?


[클래스의 메서드가 호출 될 때 생성하기]

public class Singleton {
    
    private static Singleton singleton;
    
    public static synchronized Singleton getInstance(){
        if(singleton == null){
            singleton = new Singleton();
        }
        return singleton;
    }
    private Singleton(){}
}
cs

좋은 코드라고 생각할 수 있겠다. 메소드 영역에 static 변수가 자리 잡는 시간은 최초 호출시라는 점을 잘 이용했다. 하지만 이 것은 좋지 않은 코드라고 한다. 매 getInstance()호출시마다 synchronized 동기화 문제로 비용을 치뤄야 하기 때문이다. 이러한 단점을 완화하기 위해 DCL이 고안되었다.


[더블 체크드 락킹(Double Checked Locking)]

DCL이 사용되는 궁극적인 이유는 늦은 초기화이다. 늦은 초기화가 필요한 때는 그럼 언제인가??

필드의 생성 비용(시간)이 큰 경우이거나, 필드의 값이 반드시 사용되지 않은 경우라고 한다. 뭐 이런 경우가 많지는 않다고 하는데...

public class Singleton {
 
    private volatile static Singleton singleton;
    
    public static Singleton getInstance(){
        if(singleton == null){
            synchronized (Singleton.class) {
                singleton = new Singleton();
            }
        }
        return singleton;
    }
    private Singleton(){}
}
cs

스레드 안정성에 대한 문제!!



[싱글톤 홀더 패턴(Singleton Holder Pattern)]








'DesignPattern' 카테고리의 다른 글

싱글톤 패턴 - (Singleton Pattern)  (0) 2015.07.01
Posted by slender ankles
,

자바의 call by value와 call by reference에 대해서 설명해보겠다.

흔히 C와 C++에서는 주소값을 저장하는 포인터 변수와 레퍼런스 변수를 사용하는데 자바에서는 이러한 개념이 없지 않은가?


결론은

원형 타입(primitive)타입일 때는 call by value가, 객체 타입(Object)타입일 때는 call by reference가 사용된다. 


객체가 넘어가면 Call By Reference로 동작한다고 했다.

그렇다면 다음은 어떻게 동작하겠는가??

public class Test4 {
 
    int a;
    public Test4(int a){
        this.a = a;
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Test4 t = new Test4(1);
        int i = 5;
        changeInt(i);
        System.out.println(i); // (1)       
        changeTest(t);
        System.out.println(t.a);    // (2)
        changeTestInt(t);
        System.out.println(t.a); // (3)
    }
    public static void changeInt(int a){
        a = 10;
    }
    public static void changeTest(Test4 t){
        t = new Test4(100);
    }
    public static void changeTestInt(Test4 t){
        t.a = 10;
    }
}
 
cs


(1) 5

=> int 형은 primitive 타입이기 때문에 call by value다. 그래서 함수를 지나면 지역변수가 사라지게 된다.

(2) 1

=> 메서드 안에서 new로 객체가 할당되었다. 그리고 외부 변수에 대입해주었다. 

그렇다면 new로 생성한 값 100으로 연결되어 되지 않은가? 하지만 아니다. new로 할당된 객체도 지역이 종료되면 없어진다.

(3) 10

외부에서 주입된 t에 대해서 값을 변경시켜주는 메서드를 실행했다. 값이 바뀐다. 


아무래도 난해했던 것은 (2)이 아닐까 싶다. 










'JAVA' 카테고리의 다른 글

자바 classpath  (0) 2015.11.03
Java finalize  (0) 2015.10.26
List, Map, Set - Collection  (0) 2015.08.29
자바 8 특징  (0) 2015.08.29
volatile 키워드 vs synchronized 키워드  (0) 2015.08.29
Posted by slender ankles
,