배열
같은 자료형의 변수들을 하나로 묶음으로 다루는 것
배열은 저장된 값 마다 인덱스 번호가 부여된다. (0부터 시작)
int[] = score = new int[5]; //5개의 int값을 저장할 수 있는 배열을 생성한다.
값을 저장할 수 있는 공간은 scroe[0]부터 score[4]까지 모두 5개이다.
0~4는 배열의 인덱스(index)라 하고, 오른쪽 한 칸은 배열의 요소(element)라고 한다.
배열 선언
자료형[] 배열명; //자료형 뒤에 붙이는게 일반적임. 나도 이게 편하다.
자료형 배열명[];
배열 생성(할당)
배열명 = new 자료형[배열크기];
score = new int[5]; //int 타입의 값 5개를 저장할 수 있는 배열 생성
int[] score = {10, 20, 30, 40, 50}; //선언과 초기화를 동시에 할 수 있음. new int[] 가 생략됨
int[] arr = new int[5];
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
/* 값을 대입할때도 반복문을 사용할 수 있다. */
for(int i = 0, value = 0; i < arr.length; i++) {
arr[i] = value += 10;
}
-5명의 자바 점수를 정수로 입력 받아서 합계와 평균을 실수로 구하는 프로그램
//5명의 점수를 저장할 배열 할당
int[] scores = new int[5];
Scanner sc = new Scanner(System.in);
/* 반복문을 이용하여 매일 인덱스에 하나씩 접근해서 점수를 입력 받는다. */
for(int i = 0; i < scores.length; i++) {
System.out.print((i + 1) + "번 째 학생의 자바 점수를 입력해주세요 : ");
scores[i] = sc.nextInt();
}
/* 합계와 평균을 구한다. */
double sum = 0.0;
double avg = 0.0;
/* 합계는 모든 인덱스의 값을 sum 변수에 누적해서 담아준다. */
for(int i = 0; i < scores.length; i++) {
sum += scores[i];
}
/* 평균은 합계를 구한 값에서 배열의 길이(갯수)로 나눈다. */
avg = sum / scores.length;
System.out.println("sum : " + sum);
System.out.println("avg : " + avg);
}
2차원 배열
int[ ][ ] arr = new int[2][4]를 그림으로 나타나면 아래와 같다.
-2차원 배열 예제
값 출력 :
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
int[][] iarr = new int[3][5]; //길이 5의 배열을 3개 할당
/* 배열에 저장하기 위한 하나씩 증가하는 값을 저장할 변수 */
int value = 1;
/* 배열의 갯수만큼 반복적으로 접근하기 위한 용도의 반복문 */
for(int i = 0; i < iarr.length; i++) {
/* 하나의 배열의 0번부터 마지막 인덱스까지 차례로 접근해서 값을 대입하는 용도의 반복문 */
for(int j = 0; j < iarr[i].length; j++) {
iarr[i][j] = value++;
}
}
/* 값 출력 */
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. 얕은복사 : stack의 주소값만 복사
2. 깊은 복사 : heap의 배열에 저장된 값을 복사
얕은복사
stack에 저장되어 있는 배열의 주소값만 복사하는 것이다.
두 개의 레퍼런스 변수는 동일한 배열의 주소값을 가지고 있다.
하나의 레퍼런스 변수에 저장된 주소 값을 가지고 배열의 내용을 수정(값 변경)을 하게 되면
다른 레퍼런스 변수로 배열에 접근했을 때도 동일한 배열을 가리키고 있기 때문에 변경된 값이 반영되어 있다.
출력 값 :
123961122
123961122
1 2 3 4 5
1 2 3 4 5
/* 얕은 복사를 확인할 원본 배열 생성 */
int[] originArr = {1, 2, 3, 4, 5};
/* 원본 배열을 복사 배열에 복사 - originArr에 저장된 배열의 주소를 copyArr에도 저장 */
int[] copyArr = originArr;
/* hashCode를 출력해보면 두 개의 레퍼런스 변수는 동일한 주소를 가지고 있는 것을 볼 수 있다. */
System.out.println(originArr.hashCode());
System.out.println(copyArr.hashCode());
/* 원본 배열과 복사본 배열의 값 출력 */
for(int i = 0; i < originArr.length; i++) {
System.out.print(originArr[i] + " ");
}
System.out.println();
for(int i = 0; i < copyArr.length; i++) {
System.out.print(copyArr[i] + " ");
}
System.out.println();
originArr, copyArr 배열은 동일한 값을 가지고 있다.
복사본 배열에 값을 변경한 뒤 다시 값을 확인해보면
복사본 배열만 변경했음에도 원본 배열에 영향을 미친다.
서로 같은 배열을 가리키고 있기 때문이다. (현재 존재하는 배열은 하나 뿐이다.)
출력 값 :
99 2 3 4 5
99 2 3 4 5
copyArr[0] = 99;
for(int i = 0; i < originArr.length; i++) {
System.out.print(originArr[i] + " ");
}
System.out.println();
for(int i = 0; i < copyArr.length; i++) {
System.out.print(copyArr[i] + " ");
}
System.out.println();
깊은 복사
heap에 생성된 배열이 가지고 있는 값을 또 다른 배열에 복사를 해 놓은 것이다.
서로 다른 값을 가지고 있지만, 두 배열은 서로 다른 배열이기에 하나의 배열을 변경하더라도 다른 배열에는 영향을 주지 않는다.
-깊은 복사를 하는 방법
1. for문을 이용한 동일한 인덱스의 값 복사
원본 배열과 복사한 값은 같은 값을 가지고 나머지 인덱스는 다른 값, 다른 주소를 가지고 있다.
int[] copyArr1 = new int[10];
for(int i = 0; i < originArr.length; i++) {
copyArr1[i] = originArr[i];
}
2. Object의 clone()을 이용한 복사
원본 배열과 복사한 값은 같은 값을 가지고 나머지 인덱스는 다른 값, 다른 주소를 가지고 있다.
int[] copyArr2 = originArr.clone();
3. System의 arraycopy()를 이용한 복사 (가장 높은 성능을 보임)
복사한 만큼의 값은 같지만 길이도 다르고 주소도 다르다.
int[] copyArr3 = new int[10];
/* 원본배열, 복사를 시작할 인덱스, 복사본 배열, 복사를 시작할 인덱스, 복사할 길이의 의미를 가진다.*/
System.arraycopy(originArr, 0, copyArr3, 3, originArr.length);
4. Array의 copyOf()를 이용한 복사 (가장 많이 사용되는 방식)
복사한 만큼의 값은 같지만 길이도 다르고 주소도 다르다.
/* 시작 인덱스부터 원하는 길이만큼만 복사해서 사용 가능하다. */
int[] copyArr4 = Arrays.copyOf(originArr, 7);
향상된 for문(jdk 1.5버전부터 추가)
조건식, 증감식이 없는데도 기본으로 설정돼있다. (for반복문보다 훨씬 더 간결하게 쓸 수 있음)
<기존for문>
/* 각 배열의 인덱스에 10씩 누적 증가 시킴 */
for(int i = 0; i < arr1. length; i++) {
arr1[i] += 10;
}
/* 반복문을 이용한 값 출력 */
for(int i = 0; i < arr1.length; i++) {
System.out.print(arr1[i] + " "); //정상적으로 10씩 증가된 값을 가지고 있다.
<상단 코드를 향상된 for문으로 바꿨을 경우>
for(int i : arr2) {
System.out.print(i + " ");
}
System.out.println();
/* 향상된 for문을 이용해 값 증가 시키기 */
for(int i : arr2) {
i += 10;
/* 증가 되었는지 출력 확인 */
for(int i : arr2) {
System.out.print(i + " "); //증가되지 않음.
값을 출력해보면 값이 증가되지 않는다.
인덱스에 접근해서 값을 변경한게 아니고 꺼낸 값을 복사해서 쓴 것이다.
*향상된 for문 주의 : 배열에 인덱스에 차례로 접근할 때는 편하게 사용할 수 있지만 값을 변경할 수 없다.
대신 변경하는 것이 아니고 사용하는 것이 목적이라면 조금 더 편하게 사용할 수 있다.
정렬
-변수의 두 값 변경하기
일시적으로 변수를 저장해주기 위해 temp라는 변수를 선언하여 값을 담아주고
num1, num2 서로 값을 변경해준다.
변경 후 값 출력 :
num1 = 20
num2 = 10
int num1 = 10;
int num2 = 20;
/* 두 변수의 값을 바꾸기 위해 다른 변수 한 개가 더 필요하다. */
int temp;
temp = num1;
num1 = num2;
num2 = temp;
System.out.println("num1 : " + num1);
System.out.println("num2 : " + num2);
배열의 인덱스에 있는 값도 서로 변경할 수 있다.
변경 후 값 출력 :
1 2 3
int[] arr = {2, 1, 3};
int temp2;
temp2 = arr[0];
arr[0] = arr[1];
arr[1] = temp2;
for(int num : arr) {
System.out.print(num + " ");
}
-정렬을 통해 오름차순 정리하기
/* 초기 배열 선언 및 초기화 */
int[] iarr = {2,5,4,6,1,3};
/* 인덱스를 한 개씩 증가시키는 반복문
* 첫 번째 인덱스는 비교할 필요 없어서 1번 인덱스부터 비교 시작 */
for(int i = 1; i < iarr.length; i++) {
/* 인덱스가 증가할 때마다 처음부터 해당 인덱스 - 1 까지의 값을 비교하는 반복문 */
for(int j = 0; j < i; j++) {
/* 오름차순 정렬을 위한 처리
* 내림차순 부등호 방향을 반대로 처리
* */
if(iarr[i] < iarr[j]) { //값을 바꾸기 위한 if문
/* 값 위치 변경 */
int temp;
temp = iarr[i];
iarr[i] = iarr[j];
iarr[j] = temp;
}
}
}
/* 결과 출력 */
for(int i = 0; i < iarr.length; i++) {
System.out.print(iarr[i] + " ");
}
'TIL > Java' 카테고리의 다른 글
[Java] 객체배열 (0) | 2022.01.13 |
---|---|
[Java] 클래스와 객체, 객체지향언어, 캡슐화, 추상화, 생성자, 오버로딩 (0) | 2021.12.31 |
[Java] 반복문(for, while), 분기문(break, continue) (0) | 2021.12.27 |
[Java] if조건식, Switch (0) | 2021.12.23 |
[Java] API, Math, Scanner (0) | 2021.12.23 |