자바 알고리즘 공부 3일차(1)

홍석진·2021년 9월 7일
0
post-thumbnail

👉오늘의 정리(System.arraycopy)

ArrayList의 add 메소드를 구현할 때 System.arraycopy를 사용해서 배열을 복사해서 array.length만큼 자릅니다.
실습코드를 구성한 코드는 아래와 같습니다.

public class MyArrayList<T> implements List<T> {
	int size;                    
	private T[] array;          
    
@Override
	public boolean add(T element) { //1번

		if(size >= array.length) {
			T[] bigger = (T[]) new Object[array.length * 2];
			System.arraycopy(array, 0, bigger, 0, array.length);//A
			array = bigger;
		}
		array[size] = element;
		size++;

		return true;
	}
    
    @Override
	public void add(int index, T element) { //2번
		if (index < 0 || index > size) {
			throw new IndexOutOfBoundsException();
		}
		// add the element to get the resizing
		add(element);

		// shift the elements
		for (int i=size-1; i>index; i--) {
			array[i] = array[i-1];
		}
		// put the new one in the right place
		array[index] = element;
	}
    }

생각해보면 지금까지 자바를 공부하면서 배열을 복사해본 적은 없었던 것 같습니다. 처음에 공부할 때 책을 꼼꼼히 읽으면서 이것저것 읽어보고 구현해 봤어야 했는데 그러지를 못했네요.. 그래도 이렇게 알고리즘 공부를 하면서 컬랙션프레임워크같이 공식처럼 대충알고 사용하고 원리에 대해서는 부족했던 부분을 채워갈 수 있는 것이 뜻 깊은 것 같습니다. 그래요.. 수학도 증명이 제일 중요하죠 백날 공식을 외워도 증명할 줄 모른다면 흔들릴 수 밖에 없다는 것을 잘 알기 때문에 만들 줄만 아는 것을 넘어 이해해야겠습니다. 이야기가 너무 길어졌는데 이제 1번 소스코드의 A주석 부분을 봅시다. A주석 부분은 제가 앞에서 이야기 한 System.arraycopy 부분입니다.

System.arraycopy의 파라미터 요소를 살펴보죠.
System.arraycopy(src, srcPos, dest, destPos, length) 총 5개의 요소가 있습니다.
Object src : 복사하려는 소스 (원본 소스)
int srcPos : src에서 어느 부분부터 읽어올지 위치를 지정하는 부분입니다. 만약 처음부터 읽어오고 싶다면 0을 넣어주면 됩니다.
Object dest : 복사할 소스 (복사할 대상)
int destPos : 복사 본에서 자료를 받을 때 읽어올 위치를 지정하는 부분입니다. srcPos 처럼 처음부터 읽어오고 싶으시면 0을 넣어주시면 됩니다.
int length : 원본에서 복사본으로 데이터를 읽어서 쓸 데이터 길이입니다.
이제 위에 소스코드를 예를 들어서 설명해 드릴게요.

일단 위에 array의 크기가 설정되어 있지 않기 때문에 array의 크기를 10이라고 가정하고 1~10의 숫자가 들어있다고 한다면,

array = (T[]) new Object[10]; 
size = 10;

(앞에 array와 add에 bigger는 타입파라미터로 캐스팅을 하고 Object 배열로 초기화를 했는데 타입파라미터로는 배열을 초기화 할 수 없기 때문이다.)
객체 배열 bigger의 length는 20의 크기를 갖겠죠?
이제 bigger에 array가 array.length인 10 만큼 복사됩니다. 그러고 bigger를 출력하면 1,2,3,4,5,6,7,8,9,10,null,null,null,null,null,null,null,null,null,null 1~10이 array.length만큼 복사되고 빈공간인 10만큼 null이 표기됩니다. 이런식으로 복사가 됩니다.
그래서 1번 소스코드에서는 index가 9까지 있는 array[]에 size가 10이니 늘어난 배열속 array[10]안에 element가 추가됩니다. 그리고 소스가 왜 boolean 타입인지는 링크를 참고하시면 됩니다. 이 1번 메서드는 2번 메서드인 add(int index, T element)에서 호출되어서 우리가 평소에 아는 list.add() 메서드가 만들어집니다.
이제 다음글에서 알고리즘으로 접근을 해보겠습니다.

profile
질문이나 의견이 있으시면 남겨주세요. 서로의 발전이라고 생각합니다.

0개의 댓글