반응형
2차원 배열
자료형이 같은 1차원 배열들의 묶음
2차원 배열은 할당 된 공간 마다 인덱스 번호 두개 부여 (앞 번호는 행, 뒷 번호는 열)
2차원 배열 선언과 할당
배열 선언 | 배열 할당 | 배열의 선언과 할당 |
자료형[][] 배열명; 자료형 배열명[][]; 자료형[]배열명[]; |
자료형[][]배열명 = new 자료형[행크기][열크기] | 자료형[][] 배열명 = new 자료형[행크기][열크기] 자료형 배열명[][]; = new 자료형[행크기][열크기] 자료형[]배열명[]; = new 자료형[행크기][열크기] |
2차원 배열의 저장구조
2차원 배열의 사용 방법
1 . 배열의 주소를 보관할 레퍼런스 변수 선언(stack)
int[][] iarr1;
int iarr2[][];
int[] iarr3[];
2. 여러 개의 1차원 배열의 주소를 관리하는 배열을 생성(heap)
배열의 주소를 관리하는 배열의 길이는 앞 부분에
정수형으로 표기하며 반드시 크기를 지정해줘야 한다.
iarr1 = new int[3][];
(x)iarr1 = new int[][]; 크기를 지정하지 않으면 에러 발생함
(x)iarr1 = new int[][4]; 주소를 묶어서 관리할 배열의 크기를 지정하지 않으면 에러 발생함
3. 주소를 관리하는 배열의 인덱스마다 배열을 할당(heep)
iarr1[0] = new int[5];
iarr1[1] = new int[5];
iarr1[2] = new int[5];
위에서 진행한 2,3번을 동시에 진행할 수도 있다. 앞 부분 정수는 주소를 관리하는 배열의 크기, 뒷 부분 정수는 각 인덱스에 할당하는 배열의 길이이다. 관리하는 여러개의 배열의 길이가 동일한 경우 아래와 같이 한 번에 할당할 수도 있다.
하지만 여러 개의 배열의 길이가 각각 다른 경우에는 위에서 했던 방식처럼 인덱스별로 배열을 따로 할당해 주어야 한다.
서로 같은 길이의 여러 개 배열을 하나로 묶어 관리하는 2차원 배열을 "정변 배열"이라고 하며, 서로 길이가 같지 않은 여러 개의 배열을 하나로 묶어 관리하는 2차원 배열을 "가변 배열"이라고 한다.
4. 각 배열의 인덱스에 차례로 접근해서 값 출력
(1) 배열 하나씩 접근해서 출력하기
0번 인덱스의 배열 값 출력
for(int i = 0; i < iarr1[0].length; i++) {
System.out.print(iarr1[0][i] + " ");
}
1번 인덱스의 배열 값 출력
for(int i = 0; i < iarr1[1].length; i++) {
System.out.print(iarr1[1][i] + " ");
}
2번 인덱스의 배열 값 출력 */
for(int i = 0; i < iarr1[2].length; i++) {
System.out.print(iarr1[2][i] + " ");
}
(2) 중첩 for문을 이용해서 배열의 값 출력 */
for(int i = 0; i < iarr1.length; i++) {
for(int j = 0; j < iarr1[i].length; j++) {
System.out.print(iarr1[i][j] + " ");
}
◇ 실행 결과
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
5 . 선언과 동시에 모든 배열을 할당 후 출력하는 방법
(1) 선언과 동시에 배열 할당
int[][] iarr = new int[3][5];
(2) 각 배열의 인덱스에 접근해서 값 대입 후 출력
↓ 배열에 저장하기 위해 하나씩 증가하는 값을 저장할 변수만들기
int value = 1;
↓ 배열의 갯수만큼 반복적으로 접근하기 위한 용도의 반복문 작성
for(int i = 0; i < iarr.length; i++){
for(int j = 0; j < iarr.length; j++){
iarr[i][j] = value++;
↑ 하나의 배열이 0번부터 마지막 인덱스까지 차례로 접근해서
값을 대입하는 용도의 반복문 작성
}
(3) 값 출력
for(int i = 0; i < iarr.length; i++){
for(int j = 0; j < iarr.[i].length; j++){
System.out.print(iarr[i][j] + " ");
}
System.out.println();
}
◇ 실행 결과
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
6. 가변 배열의 선언 및 할당하고 출력하기
- 가변 배열의 선언과 동시에 모든 배열을 할당할 배열의 갯수만 지정하고 각 인덱스에 서로 다른 길이의 배열을 따로 할당해야 한다.
- 자료형[ ][ ] 변수명 = new 자료형[할당할 배열의 갯수] [ ] ;
- 변수명[ 배열 인덱스] = new 자료형[ 배열의 길이];
(1) 주소를 관리하는 배열의 주소를 보관하기 위한 변수 선언
int[][] iarr = new int[3][];
(2) 주소를 관리하는 배열의 각 인덱스마다 배열을 할당하여 주소값 대입
iarr[0] = new int[3];
iarr[1] = new int[2];
iarr[2] = new int[5];
(3) 각 배열의 인덱스마다 접근하여 값 대입
iarr[0][0] = 1;
iarr[0][1] = 2;
iarr[0][2] = 3;
iarr[1][0] = 4;
iarr[1][1] = 5;
iarr[2][0] = 6;
iarr[2][1] = 7;
iarr[2][2] = 8;
iarr[2][3] = 9;
iarr[2][4] = 10;
(4) 가변 배열 역시 반목문을 이용해서 값을 대입하고 출력할 수 있음.
for(int i = 0; i < iarr.lenght; i++){
for(int j = 0; j < iarr[i].length; j++){
System.out.print(iarr[i][j] + " ");
}
Sustem.out.println();
}
◇실행 결과
1 2 3
4 5
6 7 8 9 10
7. 선언과 할당을 하며 초기화하는 방법
(1) 정변 배열
int[][] iarr = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15}};
(2) 가변 배열
int[][] iarr2 = {{1, 2, 3}, {4, 5}, {6, 7, 8, 9, 10}};
(3) 미리 할당한 배열을 이용한 방식
int[] arr1 = {1, 2, 3, 4, 5};
int[] arr2 = {6, 7, 8, 9, 10};
int[][] arr3 = {arr1, arr2};
반응형
배열 복사
1. 얇은 복사(shallow copy)
- 객체 stack의 주소값만 복사한다.(하나의 객체를 두 변수가 참조하는 것)
- 얇은 복사는 주로 메소드 호출 시 인자로 사용하는 경우와 리턴 값을 동일한 배열을 리턴해주고 싶은 경우에 활용한다.
- 두 개의 레퍼런스 변수의 주소값이 동일한지 확인해보기.
(1) 얕은 복사를 확인할 원본 배열 생성하기
int[] originArr = {1, 2, 3, 4, 5};
(2) 원본 배열을 복사 배열에 복사
int[] copyArr = originArr;
=> originArr에 저장 된 배열의 주소를 copyArr에도 저장
(3) hashCode를 출력하여 두 개의 레퍼런스 변수의 주소확인하기
System.out.println(originArr.hashCode());
System.out.println(copyArr.hashCode());
◇실행 결과
originArr 주소값 : 1651191114
copyArr 주소값 : 1651191114
=> 두 개의 레퍼런스 변수는 동일한 주소를 갖고 있는 것을 확인할 수 있다.
- 원본 배열과 복사본 배열의 값을 출력하여 비교해보기
(4) originArr과 copyArr 배열의 값 출력
for(int i = 0; i < originArr.length; i++) {
System.out.print(originArr[i] + " ");
}
for(int i = 0; i < copyArr.length; i++) {
System.out.print(copyArr[i] + " ");
}
◇실행 결과
1 2 3 4 5
1 2 3 4 5
- 복사본 배열을 통해 값 변경 후 출력해보기
copyArr[0] = 99;
for(int i = 0; i < originArr.length; i++) {
System.out.print(originArr[i] + " ");
}
for(int i = 0; i < copyArr.length; i++) {
System.out.print(copyArr[i] + " ");
}
◇ 실행 결과
99 2 3 4 5
99 2 3 4 5
=> 서로 같은 배열을 가리키고 있기 때문에
복사본 배열만 변경해도 원본 배열에 영향을 미침을 알 수 있다.
2. 깊은 복사(deep copy)
- heap에 생성 된 배열이 가지고 있는 값을 또 다른 배열에 복사를 해 놓은 것이다. (새로운 배열 객체 생성 후 기존 배열 복사)
- 서로 같은 값을 가지고 있지만, 두 배열은 서로 다른 배열이기에 하나의 배열을 변경하더라도 다른 배열에는 영향을 주지 않는다.
2 -1. 깊은 복사를 하는 방법
- for문을 이용한 동일한 인덱스의 값 복사
- Object의 clon()을 이용한 복사
- System의 arraycopy()를 이용한 복사(가장 높은 성능, copyOf()도 arraycopy를 이용한 기능이다 )
- Arrays의 copyOf()를 이용한 복사 (가장 많이 사용되는 방식, 내부적으로는arraycopy를 쓰고 있는 메소드 )
- => clon()은 이전 배열과 같은 배열 밖에 만들 수 없고, 그 외 3가지 방법은 복사하는 배열의 길이를 마음대로 조절 할 수 있다.
(1) for문을 이용한 동일한 인덱스 값 복사
◇ print()로 호출하기 위하여 배열을 매개변수로 전달 받아 모든 인덱스에 저장 되어 있는 값을
출력하는 기능을 제공하는 메소드 작성
public static void print(int[] iarr) {
전달 받은 배열의 hashCode 출력
System.out.println("iarr의 hashCode : " + iarr.hashCode());
전달 받은 배열의 값 출력
for(int i = 0; i < iarr.length; i++) {
System.out.print(iarr[i] + " ");
}
public class Application3 {
public static void main(String[] args) {
(1) 원본 배열 할당 및 초기화 후 별도의 출력 메소드로 호출해서 확인
int[] originArr = {1, 2, 3, 4, 5};
print(originArr);
(2) for문을 이용한 동일한 인덱스 값 복사
int[] copyArr1 = new int[10];
for(int i = 0; i < originArr.length; i++) {
copyArr1[i] = originArr[i];
}
(3) 출력 메소드 호출해서 확인하기
print(copyArr1);
}
◇ 실행 결과
iarr의 hashCode : 1651191114
1 2 3 4 5
iarr의 hashCode : 1586600255
1 2 3 4 5 0 0 0 0 0
=> 원본 배열과 복사한 값은 같은 값을 가지고
나머지 인덱스는 다른 값, 다른 주소를 가지고 있는 걸 확인 할 수있다.
(2) Object의 clone()을 이용한 복사
(1) clone()으로 originArr 복사
int[] copyArr2 = originArr.clone();
(2)별도의 출력 메소드로 호출
print(copyArr2);
◇ 실행 결과
iarr의 hashCode : 1651191114
1 2 3 4 5
iarr의 hashCode : 474675244
1 2 3 4 5
=> 동일한 길이, 동일한 값을 가지는 배열이 생성되지만 주소는 다르다.
(3) System의 arraycopy()를 이용한 복사
(1) 새로운 배열 만들기
int[] copyArr3 = new int[10];
(2)System의 arraycopy()를 이용한 복사하기
System.arraycopy(originArr, 0, copyArr3, 3, originArr.length);
arraycopy()의 ()안은
원본 배열, 복사를 시작할 인덱스, 복사본 배열,
복사를 시작할 인덱스, 복사할 길이의 의미를 가진다.
(3) 출력 메소드로 호출해서 확인
print(copyArr3);
◇ 실행 결과
iarr의 hashCode : 932583850
0 0 0 1 2 3 4 5 0 0
=> 복사한 만큼의 값은 같지만 길이도 다르고 주소도 다르다.
그때그때 다른 형태로 복사가 가능하다는 걸 확인할 수 있다
(4) Arrays의 copyOf()를 이용한 복사
int[] originArr = {1, 2, 3, 4, 5};
(1)복사할 배열과 원하는 길이를 정해서 복사하기
int[] copyArr4 = Arrays.copyOf(originArr, 7);
시작 인덱스부터 원하는 길이만큼만 복사해서 사용가능하다.
(2) 출력 메소드로 호출
print(copyArr4);
◇ 실행 결과
iarr의 hashCode : 212628335
1 2 3 4 5 0 0
원하는 길이만큼 복사되고 나머지는 초기값 0이나온다.
깊은 복사이기 떄문에 길이와 주소값은 다른걸 확인할 수 있다.
향상된 for문으로 인덱스에 접근하는 방법
- 향상 된 for문 (for each문) : 배열 인덱스에 하나씩 차례로 접근해서 담긴 값을 임시로 사용할 변수에 담고 반복문을 실행한다.(값을 변경하는 건 불가능. 출력할 때만 사용)
- 작성 방법 : for(변수 설정 : 반복의 대상이 되는 배열){ } / 변수는 배열 타입과 동일해야 한다.
(1)향상 된 for문으로 값 출력
int[] arr1 = {1, 2, 3, 4, 5};
for(int i : arr2) {
System.out.print(i + " ");
}
◇ 실행 결과
1 2 3 4 5
(2) 향상 된 for문을 이용해 값 증가 시키기
for(int i : arr2) {
i += 10;
}
◇ 실행 결과
1 2 3 4 5
=> 증가되서 출력x,
인덱스에 접근해서 값을 변경한게 아니고 꺼낸 값을 복사해서 쓴 것이다.
향상된 for문은 배열에 인덱스에 차례로 접근할 때는 편하게 사용할 수 있지만 값을 변경할 수는 없다.
반응형
'프로그래밍 > java' 카테고리의 다른 글
[자바JAVA] 클래스(class)_객체 생성, 전역변수, 접근제한자, this. (0) | 2022.07.07 |
---|---|
[자바JAVA] 배열의 정렬(오름차순으로 정렬하기, 중복 값 제거하기) (0) | 2022.07.07 |
[자바JAVA] 배열(Array)_ 1차원 배열 (0) | 2022.07.05 |
[자바JAVA] 제어문 _ 조건문(if문과 switch문) (0) | 2022.07.05 |
[자바JAVA] API (절대값, 최소값, 최대값, 원주율, 난수, nextInt 활용) (0) | 2022.07.04 |