7. 배열(Array) []
- 같은 자료형의 변수를 하나의 묶음으로 다루는 것
- 데이터 조회, 필터(원하는 값 찾기) 등에 사용
- 선형구조이기 때문에 저장순서가 있고, 저장소를 지칭하는 번호를 가진다 (=인덱스)
- 생성된 배열은 인덱스 번호 [0]부터 저장됨
- 변수[0] = 변수의 인덱스0번 데이터, [1] = 변수의 인덱스1 …
- 0번 인덱스가 1번째, 변수명.length-1 째가 마지막이 된다.
- 오름차순, 내림차순 정렬도 가능하다 → 나중에 java.util 활용
- 생성된 배열은 인덱스 번호 [0]부터 저장됨
- 배열은 참조 변수라서 Heap힙영역에 할당됨
- 배열 위치는 스택 영역에 저장
1) 배열 변수 선언
- 배열을 저장할 수 있는 변수를 선언
- 자료형[] 배열명; 혹은 자료형 배열명[];
- 초기화 진행
- new 연산자로 생성
: 타입[] 변수 = new 타입[값 또는 길이];
int[] arr = new int[4]; //4 길이의 배열 생성
- new 연산자로 생성한 배열은 자동적으로 기본값으로 초기화됨
- 정수와 실수 기본값: 0의 의미의 값들
- 논리 기본값: false
- 문자 기본값: ‘ ‘
- 참조 기본값: null
- 배열 길이: 배열에 저장할 수 있는 전체 요소 수
- 사용되는 속성: 배열변수명.length;
타입[] 변수명 = null;
변수명 = new 타입[] {값0, 값1, …}
2) 배열 할당(초기화)
선언된 변수에 저장될 배열을 할당
- 한번 할당된 배열은 길이를 변경할 수 없다. → 미리 최대치로 길이 지정하는 것이 좋음
String[] names = new String[] {"유병승", "유지희", "유승주", "유선정", "손지연"};
//앞으로 names 배열은 5 길이를 벗어날 수 없음 -> 길이는 한번 설정되면 변경할 수 없다.
//코드 작성시 에러가 뜨지 않으나 실행시 에러 발생
- 배열 선언 후 바로 값 목록으로 생성(값 대입)
: 타입[] 변수 = {값0, 값1, —-}- 선언 후 다음 줄 다른 실행문에서 값 목록으로 배열 생성 불가능, 즉 중괄호는 선언할 때밖에 사용 못함
⇒ 한번에 선언하면서 지정해줘야함
⇒ 나중에 지정하려면 new 연산자 활용 필요 (대신 기존에 생성한 변수의 값을 바꾸지는 못함
= 즉, 위치가 다른 동명 배열이 새로 생성되는 것)
- 선언 후 다음 줄 다른 실행문에서 값 목록으로 배열 생성 불가능, 즉 중괄호는 선언할 때밖에 사용 못함
타입[] 변수;
변수 = {값0, 값1, ...} //컴파일 에러
타입[] 변수 = {값0, 값1, ...} //정상 작동
//배열이 선언된 이후에 새로운 값으로 설정하려면 new연산자를 활용해야 한다.
chArr = new char[] {'A', 'B', 'C'};
2. 인덱스를 이용한 초기화
: arr[0] = 1; arr[1] = 2;
3. for문을 이용한 초기화
: 인덱스가 순차적으로 증가함에 따라 할당될 리터럴 값이 규칙적인 경우
3) 반복문 활용
//int 배열 10개 할당, 각 저장소에 10~20까지 저장하기
int[] a = new int[10];
for(int i = 0; i<10; i++) {
a[i] = i+10;
}
for(int i = 0; i < 10 ; i++) {
System.out.println(a[i]);
4) 배열을 통한 출력 방법
배열을 바로 출력문에 넣으면 배열이라는 객체가 저장된 위치값이 출력된다.
//주의
System.out.print(copyNum); //주소값만 출력됨
(1) for문
for(int i= 0; i < copyNum.length; i++) {
System.out.print(copyNum[i] + " ");
}
(2) Arrays.toStirng() 활용
-> 1차원 배열만 출력 가능
System.out.println(Arrays.toString(num));
(3) forEach문
각 인덱스 주소가 복사되어 변수에 들어가게 되는 것이고 이 변수를 통해 간단하게 데이터 호출 가능해진다.
단점
- 인덱스값을 알수 없다
- 지역변수
- 객체배열을 사용할 경우 값을 바꾸려면 변수가 참조하는 데이터로 접근을 해서 초기화를 해줘야한다.
for(변수선언 : 배열명) { }
int[] intArr= {1,2,3,4,5};
for(int v : intArr) { //int v : 지역변수
System.out.print(v + " ");
} System.out.println();
Q. 인덱스 범위를 초과해서 설정 및 접근하게 되는 경우?
A. 에러 발생(AraayIndexOutOfBoundsExcption)
배열 길이를 알려주는 변수가 있다
: 배열명.length → 기본형
: 배열명.length() → String
//배열길이가 변경되어도 이용가능한 반복문
for(int i = 0; i < intArr.length; i++) {
System.out.println(intArr[i]);
}
5) 배열 복사
- 배열은 한번 크기가 결정되면 수정되지 않으므로 복사를 통해 해결할 수 있다.
(1) 얕은 복사
- 주소 값만 가져와 참조형 변수에 저장, 즉 하나의 객체를 두 변수가 참조
- 원본을 공유
int[] num = {1,2,3,4,5};
int [] copyNum = num;
(2) 깊은 복사
- 새로운 배열 객체를 생성하여 기존 배열의 데이터를 복사하는 것
- 사본을 생성
(1) for문
: 요소 하나 하나를 복사
- for(int i=0, i<배열명.length; i++) {새배열[i] = 기존배열[i];}
- 향상된 for문 : 배열이나 컬렉션을 좀더 쉽게 처리
- 반복 실행을 위해 루프 카운터 변수나 증감식 사용 X
- for(타입 변수: 배열명) {실행문;}
- 배열의 요소를 하나씩 변수에 대입해서 실행문에 적용
- 가져올 항목이 더 없을 경우 for문 탈출
- 향상된 for문 : 배열이나 컬렉션을 좀더 쉽게 처리
int[] deepCopyArr = new int[num.length+5];
for(int i = 0; i < num.length; i++) {
deepCopyArr[i] = num[i]; //직접 복사
}
num[1] = 500;
System.out.println(Arrays.toString(num));
System.out.println(Arrays.toString(deepCopyArr)); //얘는 500으로 안바뀜 (사본)
(2) System.arraycopy()를 이용한 복사
- 직접 수동으로 다 지정해서 사본 생성하는 것과 마찬가지인 방법이다.
- System.arraycopy(원본배열명, 원본배열 시작 인덱스번호, 사본 배열명, 사본 시작 인덱스번호, 복사 개수(길이 = .length))
- 배열의 길이와 시작번호를 잘 계산해야한다
String[] a = {1,2,3};
String[] b = new String[5]; //새로운 b는 5열
**System.arraycopy(a, 0, b, 0, a.length);**
//a에서 0번째 인덱스부터 b 0인덱스에 a의 길이만큼 복사)
(3) Arrays.copyOf(배열명, 길이) 기능 이용
- 지정한 길이만큼 자동으로 사본 배열 길이 지정, 내용까지 복사
- 기존 배열에 덮어씌우기도 가능
String[] copyName2 = Arrays.copyOf(names, 2);
System.out.println("copyName2 : " + Arrays.toString(copyName2));
str = Arrays.copyOf(str, x+y);
(4) clone() 기능 이용
: 완전 똑같이 복사하는 방법
타입[]x 사본배열명 = 원본배열[i].clone();
String[] copyName3 = names.clone();
System.out.println(Arrays.toString(copyName3));
6) 배열 정렬
- Arrays 클래스에서 제공하는 sort() 이용 ⇒ 오름차순 정렬
int[] A; int[] B;
Arrays.sort(A); //오름차순으로 정렬
Arrays.sort(B); //오름차순으로 정렬
- 내림차순시 Arrays.sort(T[], Comparator<? super T>) 이용
- Arrays.sort(int[]) 에는 Comparator 를 입력받는 오버로드가 없기 때문에 Comparator 를 사용할 수 없습니다.
- → 참조 자료형만 사용 가능
Integer []arr = new Integer[4];
Arrays.sort(arr,(x,y) -> y-x); //내림차순 람다식 정의
Arrays.stream(arr).forEach(x-> System.out.print(x)); //출력
7) 배열 내용 합치기
- String클래스에서 제공하는 join() 메소드 이용
8) 2차원 배열 [][]
자료형이 같은 1차원 배열의 묶음으로 배열 안에 다른 배열이 들어감
웹서비스 분야 보다는 빅데이터 등 큰 데이터 처리시에 2차원 배열 자주 사용
- 저장 형태: 힙에 저장된 배열 인덱스 속에 또다른 배열의 위치가 저장되어있음
- 행렬 구조
: 1차원 배열이 다시 1차원 배열을 참조하여 바둑판식의 저장구조를 갖고 있음 - 예) int[][] scores = new int[2][2]; → 2 * 2 행렬의 구조
arr[m][n]
- 행m: 가로줄, 열n: 세로줄
- 배열의 길이
i.length //2
i[0].length //2
i[1].length //3
+) 계단식 구조 생성 → 잘 안쓰이고 행렬이 대부분 사용되니 참고만 하기
int[][] i = new int[2][]; //행수 2짜리 2차원 배열 생성 i[0] = new int[2]; //2칸짜리 0행 생성 i[1] = new int[3]; //3칸짜리 1행 생성 i[0][1] = 10; //(0,1)칸에 값 10이 저장됨
(1) 2차원 배열 초기화
방법은 1차원 배열과 동일: 인덱스, for문, 선언과 동시에 초기화
//인덱스로 집어넣기
int[][] intArr;
intArr = new int[3][3]; //9개의 데이터를 저장할 수 있는 저장구조
//2차원 배열에 값 대입하기
intArr[0][0] = 100;
intArr[1][0] = 200;
for(int i = 0; i < intArr.length; i++){
for(int j=0; j<intArr[i].length; j++) {
System.out.print(intArr[i][j]+" ");
}
System.out.println();
}
//선언과 동시에 초기화하기
String[][] test = {{"가","나","다"},{"A", "B", "C"} , {"a", "b", "c"}};
(2) 2차원 배열 출력
System.out.println(intArr[0]); //배열의 배열 주소가 출력됨
System.out.println(intArr[0][0]);
//5*5 int배열을 생성하고 12345가 5줄이 되도록 출력해보기
int[][] intArr2 = new int[5][5];
for(int i = 0; i < intArr2.length; i++) {
for(int j = 0; j < intArr2[i].length; j++) {
intArr2[i][j] = j+1;
}
}
for(int i = 0; i < intArr2.length; i++) {
for(int j = 0; j < intArr2[i].length; j++) {
System.out.print(intArr2[i][j] + " "); //i가 고정인 상태에서 j가 반복(별찍기와 유사)
} System.out.println();
}
+ )참조 타입 배열
: 요소에 값(정수, 실수, 논리값)을 저장하지 않고, 객체의 번지를 가지고 있음
반응형
'JAVA' 카테고리의 다른 글
9. 자바(java) : 제어자 (modifier), 접근제한자, static 개념 간단 정리 (0) | 2024.04.01 |
---|---|
8. 자바(java) : 객체(Object), 객체 지향 개념 정리 (0) | 2024.04.01 |
6. 자바(java) : 제어문(Control Statement) 간단 정리 (0) | 2024.03.28 |
5. 자바(java) : 연산자(Operator) 간단 정리 (2) | 2024.03.27 |
4. 자바(java) : 형변환(casting) 간단 정리 (0) | 2024.03.27 |