It Study/POWER JAVA(기본서)

POWER JAVA 4장 안전한 배열 - 응용(해설)

prlkt5200 2022. 10. 2. 04:34
반응형

멤버(필드, 메소드) 그리고 생성자 및 설정자와 접근자 간의 상호작용이 어떻게 되는지

한번 의식의 흐름대로 일단 써봤습니다.

보기 많이 불편하시겠지만, 참고하실 분들은 읽어보셔요!!~

 

그리고 아마 끝까지 보시면 알겠지만 치명적인 문제점이 있습니다.

이 코드는 의도적으로 끊어주지 않으면 계속해서 반복합니다.

append() 메소드를 통해 배열 길이를 계속해서 늘려주고 따라서, 차이는 계속해서 -1이 되다보니 

결과적으로 무한 반복이 되는 경우인 것 같습니다.

 

다음에는 이런 경우를 어찌 해결하는 게 좋을지 잘 고민해봐야겠습니다. 

 

새벽까지 고생하긴 했지만 접근자와 설정자를 어떤 식으로 활용하면 좋을지 고민할 수 있어 좋은 경험이었습니다.

아래 해설은 보기 힘드니 코드만 보시면서 한번 고민해보시는 것도 추천해드립니다.

 

1. 코드 part(응용ver)

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
31
32
33
34
35
36
37
38
package test;
 
public class SafeArray {
 
    private int a[];
    public int length;
 
    public SafeArray(int size) {
        a = new int[size];
        length = size;
    }
 
    public int get(int index) {
        if (index >= 0 && index < length) {
            return a[index];
        }
        return (length - 1- index;
    }
 
    public void put(int index, int value) {
        if (index >= 0 && index < length) {
            a[index] = value;
 
        } else {
            System.out.println("잘못된 인덱스는 " + index + "입니다.");
        }
    }
 
    public void append(int num, int item) {
        length += num;
        a = new int[length];
        for (int i = 1; i <= num; i++) {
            a[(length - num - 1+ i] = item;
 
        }
 
    }
}
cs

 

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
package test;
 
public class SafeArrayTest {
    public static void main(String[] args) {
        SafeArray array = new SafeArray(3);
 
        for (int i = 0; i < (array.length + 1); i++) {
 
            if (array.get(i) >= 0) {
                array.put(i, i * 10);
                System.out.printf("배열%d의 값은 ", i);
                System.out.print(array.get(i) + "입니다.\n");
                System.out.println("======================");
 
            } else if (array.get(i) < 0 && i<10) {
                array.put(i, i * 10);
                System.out.println("차이가 " + array.get(i) + "입니다.");
 
                int differ = -(array.get(i));
                array.append(differ, i * 10);
                System.out.println("새로 생긴 인덱스는 " + i + "이며, 배정받은 값은 " + array.get(i) + "입니다.");
 
                System.out.println("======================");
            }
        }
    }
 
}
 
cs

 

 

2.해설 part

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package test;
 
public class SafeArray {
 
    private int a[];
    // 배열을 클래스에 감싸줬다. 길이는 아직 미정
    public int length;
    // 길이를 지정할 변수이다.
 
    public SafeArray(int size) {
        // 매개변수를 받는 생성자를 통해서 배열의 길이와
        // 길이를 의미하는 변수의 값을 지정한다.
        a = new int[size];
        length = size;
    }
 
    public int get(int index) {
        // 접근자 메소드이며 index값을 매개변수로 받는다.
        // index 값이 0이상 길이보다 작으면 메소드를 종료하고 리턴한다.
        // 그리고 비정상값이면 (length - 1)-index의 값을 리턴한다.
        // 그래서 차이가 어느 정도 나는지를 알린다.
        if (index >= 0 && index < length) {
            return a[index];
        }
        return (length - 1- index;
    }
 
    // 여기서 put은 설정자이며 index 값과 value 값을 매개변수로 받는다.
    // 이 메소드를 통해서 index 값이 다음 조건을 만족하면 value 값을 통해
    // 각 배열의 index에 value가 지정된다.
    public void put(int index, int value) {
        if (index >= 0 && index < length) {
            a[index] = value;
 
            // 만약 index 값이 위 조건을 만족 못하면 오류 문자와 index가 출력된다.
        } else {
            System.out.println("잘못된 인덱스는 " + index + "입니다.");
        }
    }
 
    // 이것은 응용인데 만약 배열의 길이가 부족할 시 이 메소드를 사용하여 배열의 길이를 추가시키고
    // 원하는 값을 추가하는 기능이다.
    // num은 추가하려는 길이 수, item은 추가하려는 값으로 하겠다.
    public void append(int num, int item) {
        length += num;
        // 늘어난 최종길이가 된다.
        a = new int[length];
        // 최종길이로 배열을 만들어준다.
        // 따라서 다른 멤버의 값도 전부 새롭게 변한다.
        for (int i = 1; i <= num; i++) {
            a[(length - num - 1+ i] = item;
            // (새로 초기화한)length - num;은 기존의 길이며, 여기에 -1을 해야 기존 인덱스이다.
            // 여기에 for문을 활용하여 i를 순차적으로 더해주면 기존 인덱스에서 새로 늘어난 인덱스의 끝 부분까지
            // 값을 지정해줄 수 있다.
 
        }
 
    }
}
cs

 

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package test;
 
public class SafeArrayTest {
    // SafeArray class를 이용해보면 아래와 같다
    public static void main(String[] args) {
        SafeArray array = new SafeArray(3);
 
        // array 참조변수명에 SafeArray class를 토대로 한 객체를 묶어준다.
        // 그리고 class에서 만들어낸 매개변수를 받는 생성자를
        // 가지고 있기에 매개 변수 3을 적용해 객체의 필드 값을 초기화 한다.
 
        // a = new int[3];
        // length = 3; 으로 값이 초기화되며, 따라서 아래에
        // for문에서도 array.4+1 즉 array.5가 된다.
        // 그럼 0부터 4까지 반복하면서
        // put() 설정자 내부에 값을 지정해준다.
 
        // 그리고 SafeArray class에 있는(객체도 동일하게 가지고 있는) put() 설정자에 따라서
        // index와 value 값이 반복문으로 인해
        // 0,0 1,10 2,20 3,30 4,40으로 값을 지정해주려 한다.
        // 하지만 앞에서 배열의 길이는 3, 그렇기에 index는 0부터 2까지 밖에 없다.
        // 그리고 그것을 감안하여 짠 put() 설정자의 내부 조건문에 따라서 값의 설정도
        // 0부터 2까지 밖에 안되고 배열의 길이를 초과한 index에 값을 지정하려 할 시 오류구문이 뜬다.
 
        // get 접근자를 통해서 배열의 값을 출력한다.
        // 설정한 배열의 길이를 초과해서 get()에서 음수 값이 리턴되면 얼마만큼 차이 있는지도 출력된다.
 
        for (int i = 0; i < (array.length + 1); i++) {
 
            if (array.get(i) >= 0) {
                array.put(i, i * 10);
                System.out.printf("배열%d의 값은 ", i);
                System.out.print(array.get(i) + "입니다.\n");
                System.out.println("======================");
 
            } else if (array.get(i) < 0 && i<10) {
                //과하게 반복이 안되게 i값을 10으로 제한했다.
                array.put(i, i * 10);
                System.out.println("차이가 " + array.get(i) + "입니다.");
 
                int differ = -(array.get(i));
                array.append(differ, i * 10);
                System.out.println("새로 생긴 인덱스는 " + i + "이며, 배정받은 값은 " + array.get(i) + "입니다.");
 
                System.out.println("======================");
            }
        }
    }
 
}
 
    }
}
cs
반응형