배열 (Array)
하나의 값을 저장할 수 있는 공간은 변수다.
★같은 자료형★의 변수를 하나의 묶음으로 다루는 것이 배열이다.
선언한다 -> stack 영역에 공간이 만들어지는 것
만들어진 공간에 대한 주소값이 arr에 들어간다.
new 연산자가 들어가는 순간 Heap 영역에 만들어진다.
~한 자료형의 ~한 크기를 가진.
공간의 주소값도 생성됨.
자바에서 객체의 주소값을 실제로 알 순 없다.
자바에서는 건드릴 수 없게 돼있다.
배열도 결국 참조형 자료형 중 하나다.
Scanner sc = new Scanner(System.in);
System.out.print("배열의 크기 : ");
int size = sc.nextInt();
double[] dArr = new double[size];
System.out.println(dArr); // [D@1b6d3586
System.out.println("dArr.length : " + dArr.length);
/*
for(int i = 0; i <= dArr.length-1; i++) {
System.out.println("dArr[" + i + "] : " + dArr[i]); // 0.0
}
*/
System.out.println("dArr의 크기를 30으로 변경");
dArr = new double[30];
System.out.println("dArr.length : " + dArr.length);
System.out.println(dArr); // [D@4554617c 새로 공간이 할당됐다.
// 배열은 한 번 만들면 크기를 변경할 수 없다. 우리 눈에는 크기가 변경된 것처럼 보이지만, 사실 크기가 변경된 게 아니라 새로운 공간을 만들어서 치환하고 있을 뿐이다. 원래 만든 것의 크기를 늘리거나 줄일 수 없다.
// 원래 만들었던 것과의 연결은 끊기고, 원래 만들었던 배열은 garbage collector가 정리하고... old 영역에서도... 나중에 소멸된다. 한 번 연결이 끝나면 되돌아 갈 수가 없다.
dArr = null;
System.out.println(dArr);
// null을 넣어주면 연결을 끊을 수 있다.
얕은 배열 복사
하나의 종이로 돌려보기 때문에 원본이 훼손되면 같이 훼손된다. 까맣게 칠해서 안 보이게 하면 다른 사람들도 볼 수 없는 것.
public void method1() {
int[] originArr = {1, 2, 3, 4, 5};
int[] copyArr = originArr; // 얕은 복사
System.out.println(originArr); // [I@15db9742
System.out.println(copyArr); // [I@15db9742
System.out.print("originArr : ");
for(int i = 0; i <= originArr.length-1; i++) {
System.out.print(originArr[i] + " ");
}
System.out.println();
System.out.print("copyArr : ");
for(int i = 0; i <= copyArr.length-1; i++) {
System.out.print(copyArr[i] + " ");
}
System.out.println();
// originArr[0]의 값을 99로 변경
originArr[0] = 99;
System.out.println(originArr[0]); // 99
System.out.println(copyArr[0]); // 99
// 같은 주소를 참조하고 있기 때문에 copyArr의 데이터도 바뀐다.
}
주소값을 복사하는 게 아니라 그 안에 있는 데이터를 그대로 복사해서 내가 갖고 있는 것
/*
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
native가 적혀 있으면 까 볼 수 없다.
*/
attach sources...에 src.zip을 첨부
* @param src the source array.
* @param srcPos starting position in the source array.
* @param dest the destination array.
* @param destPos starting position in the destination data.
* @param length the number of array elements to be copied.
* @exception IndexOutOfBoundsException if copying would cause
* access of data outside array bounds.
* @exception ArrayStoreException if an element in the <code>src</code>
* array could not be stored into the <code>dest</code> array
* because of a type mismatch.
* @exception NullPointerException if either <code>src</code> or
* <code>dest</code> is <code>null</code>.
*/
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
public void method4() {
// 깊은 복사
// 3. Arrays클래스에 있는 copyOf()메소드를 이용한 복사
// 배열을 이용할 때 유용한 메소드들을 모아놓은 클래스가 Arrays클래스이다.
// ※ Collections : 컬렉션을 이용할 때 유용한 메소드들을 모아놓은 클래스
int[] originArr = {1, 2, 3, 4, 5};
int[] copyArr = new int[10];
// Arrays.copyOf(original, newLength)
// 밑줄 전체가 copy가 된다.
copyArr = Arrays.copyOf(originArr, originArr.length);
// Arrays라는 클래스의 copyOf라는 메소드
/* ★여기★
public static int[] copyOf(int[] original, int newLength) {
int[] copy = new int[newLength]; // Heap영역에 새롭게 공간을 만들었다.
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength)); // original.length와 newLength 둘 중 더 작은 것을 고르는 Math 클래스의 min 메소드. 둘 다 5이기 때문에 어느 것이어도 상관없게 됨.
★여기★ ==> 같은 자료형이어야 한다
return copy; // return, 나를 불러준 메소드로 돌아간다. 값이 있는 상태에서 돌아간다. Arrays.copyOf로.
}
*/
// originArr 출력
for(int i = 0; i <= originArr.length-1; i++) {
System.out.print(originArr[i] + " "); // 1 2 3 4 5
}
System.out.println();
// copyArr 출력
for(int i = 0; i <= copyArr.length-1; i++) {
System.out.print(copyArr[i] + " "); // 1 2 3 4 5
}
System.out.println();
}
★Arrays 클래스의 copyOf 메소드 흐름이 중요★