자료구조 > 데이터 저장하는 물리적인 구조
데이터의 집합 > 변수들을 모아놓은 집합
같은 자료형을 저장하는 데이터의 집합
- 배열의 요소: 배열내의 방 하나(element)
- 배열의 길이: 배열내의 방의 개수(length)
- 배열의 첨자: 방의 순서(index)
- 배열의 최대 첨자 == 배열의 길이 - 1
- 배열의 첨자 잘못 사용 > ArrayIndexOutOfBoundException 발생
배열은 생성 직후 모든 요소(방)가 초기화가 된다.
초기화 규칙
1. 정수배열 > 0
2. 실수배열 > 0.0
3. 문자열 > \0(\u0000)
4. 논리배열 > false
5. 참조형배열 > null
//배열 선언
자료형[] 배열명 = new 자료형[길이];
//요소의 접근
배열명[첨자] = 값; //쓰기
System.out.println(배열명[첨자]); //읽기
//초기화 리스트
자료형[] 배열명 = { 요소, 요소 요소 };
// 요구사항] 학생 3명 > 국어 점수 > 총점, 평균
// 추가사항] 학생수 증가 > 300명
// 배열 선언하기
// - 자료형[] 변수명 = new 자료형[길이];
// - 배열타입 배열명 = new 배열타입[배열의길이];
int[] kors = new int[5];
// 배열의 방(요소, Element)에 접근 > 방 번호(첨자, Index) 사용
kors[0] = 100;
kors[1] = 90;
kors[2] = 80;
// int total = kors[0] + kors[1] + kors[2];
int total = 0;
for (int i = 0; i < kors.length; i++) {
total += kors[i];
}
double avg = (double) total / kors.length; // 속성, 필드, 프로퍼티
System.out.printf("총점: %d점, 평균: %.1f점\n", total, avg);
// 배열 복사(= 참조형 복사)
// 값형 복사
int a = 10;
int b;
b = a;
// 값형 > 원본을 수정해도 복사본에 영향을 주지 않는다.
// > Side effect가 발생하지 않는다.
a = 20; // 원본 수정
System.out.println("a: " + a);
System.out.println("b: " + b);
System.out.println();
int[] nums = new int[3];
nums[0] = 10;
nums[1] = 20;
nums[2] = 30;
int[] copy;
// int[] = int[]
copy = nums;
System.out.println(copy[0]);
System.out.println(copy[1]);
System.out.println(copy[2]);
// 원본을 수정하면 복사본도 수정된다.
// 복사본을 수정하면 원본도 수정된다.
// > Side effect가 발생한다.
nums[0] = 100;
System.out.println(copy[0]);
System.out.println(copy[1]);
System.out.println(copy[2]);
copy[1] = 200;
System.out.println(nums[1]);
// 배열 복사
// 1. 얕은 복사, Shallow Copy
// - 주소값 복사
// - Side Effect 발생
// 2. 깊은 복사, Deep Copy
// - 실제 배열 복사
// - Side Effect 발생 안함
int[] nums = new int[3];
nums[0] = 10;
nums[1] = 20;
nums[2] = 30;
int[] copy = new int[3];
for (int i = 0; i < nums.length; i++) {
// 방과 방끼리의 복사 > 요소끼리의 복사
// int = int
copy[i] = nums[i];
}
nums[0] = 100;
System.out.println(copy[0]);
//깊은 복사
//결과 : 10
=> 깊은 복사를 해주는 클래스가 있다!
// Arrays 클래스
// - 유틸리티 클래스
// - 배열과 관련된 여러가지 기능을 구현한 클래스
// - 배열을 조작하는 편리한 기능을 제공하는 역할
int[] nums = new int[3];
nums[0] = 10;
nums[1] = 20;
nums[2] = 30;
// 배열의 상태를 확인?
// - [I > int[]
// - @
// - 2ff4acd0 > 메모리 주소
System.out.println(nums); // 쓸모없음
printArray(nums);
System.out.println(Arrays.toString(nums)); // dump(덤프)
// *** C계열의 언어들은 범위를 나타날때
// - 시작위치(inclusive) ~ 끝위치(exclusive)
int[] copy;
// 깊은 복사
copy = Arrays.copyOfRange(nums, 0, nums.length);
nums[0] = 100;
System.out.println(Arrays.toString(nums));
System.out.println(Arrays.toString(copy));
//결과
[I@2ff4acd0
10 20 30
[10, 20, 30]
[100, 20, 30]
[10, 20, 30]
정렬
- 크기 비교 후 > 재배치
1. 오름차순
a. 숫자: 작은수 > 큰수
b. 문자열 : 문자코드값 순
c. 날짜 시간 : 과거 > 미래
2. 내림차순
a. 숫자: 큰수 > 작은수
b. 문자열 : 문자코드값 역순
c. 날짜 시간 : 미래 > 과거
정렬 구현
1. 직접 구현 > 정렬 알고리즘
2. JDK 구현된 기능
버블정렬 + swap
swap > 두 공간의 데이터를 서로 바꾸는 작업
int[] nums = { 5, 3, 1, 4, 2 };
System.out.println(Arrays.toString(nums));
//가장 큰 또는 작은 원소가 배열의 끝으로 이동
for (int i = 0; i < nums.length; i++) { // 사이클(0,1,2,3)
// 서로 인접한 두 원소를 비교하고 필요한 경우 위치 교환
for (int j = 0; j < nums.length - 1 - i; j++) {
// 오름차순
if (nums[j] > nums[j + 1]) {
temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
}
System.out.println("오름차순 정렬: " + Arrays.toString(nums));
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums.length - 1 - i; j++) {
// 내림차순
if (nums[j] < nums[j + 1]) {
temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
}
System.out.println("내림차순 정렬: " + Arrays.toString(nums));
1. 배열 요소 삽입(Insertion)
Right Shift > 오른쪽으로 한 칸씩 이동했다.
=> 값을 오른쪽에 복사 해놓음
삽입 이후의 요소들이 인덱스가 변경된다. (중요)
int[] nums = { 1, 2, 3, 4, 5 };
int index = 1;
int value = 9;
System.out.println("nums[0] = " + nums[0]);
System.out.println("nums[3] = " + nums[3]);
System.out.println(Arrays.toString(nums));
for (int i = nums.length - 2; i >= index; i--) {
// System.out.println(i);
nums[i + 1] = nums[i];
System.out.println(Arrays.toString(nums));
}
System.out.println();
nums[index] = value;
System.out.println(Arrays.toString(nums));
System.out.println("nums[0] = " + nums[0]); //처음에 넣었던 값을 기억 못하면 큰일!
System.out.println("nums[3] = " + nums[3]); //값이 바뀌는 데 에러는 안 떠있음
//결과
nums[0] = 1
nums[3] = 4
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 4]
[1, 2, 3, 3, 4]
[1, 2, 2, 3, 4]
[1, 9, 2, 3, 4]
nums[0] = 1
nums[3] = 3
2. 배열 요소 삭제(Deletion)
Left Shift > 왼쪽으로 한칸씩 이동했다.
int[] nums = { 1, 2, 3, 4, 5 };
int index = 1;
System.out.println(Arrays.toString(nums));
for (int i=index; i <=nums.length-2; i++) {
// System.out.println(i);
nums[i] = nums[i+1];
}
nums[nums.length-1] =0; //맨 마지막 값 0으로 초기화
System.out.println(Arrays.toString(nums));
//결과
[1, 2, 3, 4, 5]
[1, 3, 4, 5, 0]
1차원 배열, 2차원 배열, 3차원 배열
//1차원 배열
int[] nums1 = new int[3];
nums1[0] = 10;
nums1[1] = 20;
nums1[2] = 30;
System.out.println(Arrays.toString(nums1));
//2차원 배열
int[][] nums2 = new int[2][3];
nums2[0][0] = 10;
nums2[0][1] = 20;
nums2[0][2] = 30;
nums2[1][0] = 40;
nums2[1][1] = 50;
nums2[1][2] = 60;
//nums2 자료형? > int[][]
//nums2[0] 자료형 > int[]
//nums2[0][0] 자료형 > int
nums2[0][1] = 20;
System.out.println(nums2.length); //출력 : 2
System.out.println(nums2[0].length); //출력 : 3
System.out.println(nums2[0][0]); //출력 : 10(int 값)
System.out.println(Arrays.toString(nums2));
System.out.println(Arrays.deepToString(nums2));
//2차원 배열 탐색
for(int i=0; i<nums2.length; i++) {
for(int j=0; j<nums2[0].length; j++) {
System.out.print(nums2[i][j] + "\t");
} // 하나의 층에 있는 배열 출력
System.out.println();
}
System.out.println();
//3차원 배열
int[][][] nums3 = new int[2][2][3];
nums3[0][0][0] =10;
nums3[0][0][1] =20;
nums3[0][0][2] =30;
nums3[0][1][0] =40;
nums3[0][1][1] =50;
nums3[0][1][2] =60;
nums3[1][0][0] =70;
nums3[1][0][1] =80;
nums3[1][0][2] =90;
nums3[1][1][0] =100;
nums3[1][1][1] =110;
nums3[1][1][2] =120;
for(int i=0;i<nums3.length;i++) {
for(int j=0; j<nums3[0].length;j++) {
for(int k=0; k<nums3[0][0].length;k++) {
System.out.printf("%5d",nums3[i][j][k]);
}
System.out.println();
}
System.out.println();
}
//결과
[10, 20, 30]
2
3
10
[[I@2ff4acd0, [I@54bedef2]
[[10, 20, 30], [40, 50, 60]]
10 20 30
40 50 60
10 20 30
40 50 60
70 80 90
100 110 120
❗ 배열의 길이는 불변이다. ❗
=> 한번 만들어진 배열의 방은 더 늘리거나 삭제할 수 없다.
Scanner scanner = new Scanner(System.in);
System.out.print("학생수 : ");
int lenght = scanner.nextInt();
int[] kor = new int [lenght]; //동적으로 길이 할당
System.out.println(kor.length);