배열(Array)

우수민·2021년 10월 19일
0
post-thumbnail

1. 배열(array)

1.1 배열(array)이란?

  • 배열(Array) : 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것
    • 중요한 점은 같은 타입이라는 점이다. -> 파이썬은 여러 변수가 가능
// 배열 사용하지 않을 경우
int score1, score2, score3, score4, score5; 

// 배열 사용 경우
int[] score = new int[5]; // 5개의 int를 저장할 수 있는 배열을 생성
  • 변수 score은 배열을 다루는데 필요한 참조변수일 뿐 값을 저장하기 위한 공간은 아니다.

  • 변수와 달리 배열은 각 저장공간이 연속적으로 배치되어 있다는 특징이 있다.

1.2 배열의 선언과 생성

  • 배열의 생성은 원하는 타입의 변수를 연선하고 변수 또는 타입에 배열임을 의미하는 대괄호[]를 붙이면 된다.
타입[] 변수이름;
타입 변수이름[];
  • 배열의 선언과 생성을 동시에 하면 간략히 한줄로 표현이 가능하고 대부분 이렇게 활용한다.
타입[] 변수이름 = new 타입[길이];
int[] score   = new int[5];
  • 배열 생성 단계
    1. int[] score ;
      • 참조 변수 score 선언 -> 저장 공간 마련 X
    2. score = new int[5];
      • 연산자 new에 의하여 빈공간 5개에 데이터를 저장하는 공간이 마련
      • 각 공간은 0으로 초기화
      • 끝으로 대입 연산자'='에 의해 배열의 주소가 int형 배열 참조 변수 score에 저장

1.3 배열의 길이와 인덱스

  • 생성된 배열의 각 저장 공간을 '배열의 요소(element)'라고 하며, '배열이름[인덱스]'의 형식으로 배열의 요소에 접근한다.
  • 유효하지 않은 값을 index로 사용하면, 무사히 컴파일을 마쳤더라고 실행 시에 에러(ArrayIndexOutOfBoundsException)가 발생한다.
  • 배열의 길이는 당연하게 양의 정수이어야 하며 최대값은 in타입의 최대값, 약 20억이다. 즉, 제약이 없다.
타입[] 배열 이름 = new 타입[길이];
int[] arr = new int[5];
  • 프로그래밍을 하다 보면 길이가 0인 배열이 필요한 상황이 있고 나름 유용하다.
  • 자바에서는 JVM이 모든 배열의 길이를 별도로 관리하며, '배열이름.length'를 통해 배열의 길이의 정보를 얻을 수 있다.
int[] arr = new int[5];
int tmp = arr.lengh;
  • 배열은 한번 생성하면 길이를 변경할 수 없기 때문에, 이미 생성된 배열의 길이는 변하지 않는다. -> 파이썬 리스트는 가능
    • 즉, 배열이름.length는 상수이며, 값을 읽을 수만 있으며 값을 변경할 수 없다.
  • 배열에 저장할 공간이 부족한 경우에는 아래의 방법을 활용할 수 있다.
    1. 더 큰 배열을 새로 생성한다.
    2. 기존 배열의 내용을 새로운 배열에 복사한다.
  • 다만, 위의 작업은 비용이 많이 들기 때문에, 처음부터 배열의 길이를 넉넉하게 잡아주는 것이 좋다.

1.4 배열의 초기화

  • 배열은 생성과 동시에 자동적으로 자신의 타입에 해당하는 기본값으로 초기화되므로 배열을 사용하기 전에 따로 초기화를 해주지 않아도 되지만, 원하는 값을 저장하려면 각 요소의 값을 정해줘야 한다.
int[] score = new int[]{50,60,70,80,90}; // 배열의 생성과 초기화를 동시에 
int[] score = {50,60,70,80,90}; // new int[]를 생략할 수 있음

// 더 간단히 하는 방법
int[] score;
score = new int[]{50,60,70,80,90} // OK
score = {50,60,70,80,90} // 에러. new int[]를 생략할 수 없음
  • 매서드에서 호출하는 경우에도 'new 타입[]'을 생략할 수 없다.
int add(int[] arr) {/* 내용 생략 */} // add메서드
int result = add(new int[]{100,40,50,60}) // ok
int result = add({100,40,50,60}) // 에러. new int[] 생략 불가능
  • 중괄호{} 안에 아무것도 넣지 않는다면 길이가 0인 배열이 생성된다.

  • 배열의 출력은 for문을 활용 할 수 있으며, 'Arrays.toString(배열이름)'메서드를 사용한다.

int[] iArr = {1,2,3,4,5};
System.out.println(Arrays.toString(iArr));

1.4 배열의 복사

  • 크기가 5인 배열이 복사되는 원리
    1. 배열 arr의 길이인 arr.length의 값이 5이므로 길이가 10인 int배열 tmp가 생성되고, 배열 tmp의 각 요소는 int의 기본값인 0으로 초기화된다.
    2. for문을 활용해 배열 arr의 모든 요소를 tmp에 복사한다.
    3. 참조 변수 arr에 참조변수 tmp값을 저장한다.

배열은 참조변수를 통해서만 접근할 수 있기 때문에, 자신을 가리키는 참조변수가 없는 배열은 사용할 수 없다. 이렇게 쓸모없게 된 배열은 JVM의 가비지 컬렉터에 의해서 자동적으로 메모리에서 제거된다.

System.arraycopy()를 이용한 배열의 복사

  • for문보다 간단하고 빠르게 배열을 복사할 수 있다. -> 더 효율적
  • for문의 경우 하나씩 접근하지만, arraycopy()는 지정된 범위의 값들을 한 번에 통째로 복사한다.
for(int i=0; i<num.length;i++){newNum[i] = num[i]}; // for문 활용
System.arraycopy(num, 0, newNum, 0, num.length); // arraycopy() 활용
  • System.arraycopy(num, 0, newNum, 0, num.length);
    • num[0]에서 newNum[0]으로 num.length개의 데이터 복사

1.5 배열의 활용

  1. 총합과 평균
  2. 최대값과 최소값
  3. 섞기(shuffle)
  4. 임의의 값으로 배열 채우기
for(i=0;i<arr.length;i++){
	arr[i] = (int)(Math.random()*5) // 	
}
  1. 빈도수 구하기
class ArrayEx11 {
	public static void main(String[] args) {
		int[] numArr  = new int[10];
		int[] counter = new int[10];

		for (int i=0; i < numArr.length ; i++ ) {
			numArr[i] = (int)(Math.random() * 10); // 0~9의 임의의 수를 배열에 저장
			System.out.print(numArr[i]);
		}
		System.out.println(); // 9558044998

		for (int i=0; i < numArr.length ; i++ ) {
			counter[numArr[i]]++; // 이러한 식으로 배열에 값을 1씩 더해줌
		}

		for (int i=0; i < numArr.length ; i++ ) {
			System.out.println( i +"의 개수 :"+ counter[i]);
		}
	} 
}

2. String 배열

2.1 String배열의 선언과 생성

  • 배열의 타입이 String인 경우에도 int배열의 선언과 생성방법은 다르지 않다.
String[] name = new String[3]; // 3개의 문자를 담을 수 있는 배열 생성
  • 위의 문장을 수행하면 3개의 String타입의 참조변수를 저장하기 위한 공간이 마련되고 기본값은 Null이므로 각 요소의 값은 Null로 초기화가 된다.
자료형기본값
booleanstatic
char\u0000
byte, short, int0
long0L
float0.0f
double0.0d 또는 0,0
참조형 변수null

2.2 String배열의 초기화

  • 초기화 역시 int 배열과 동일한 방법으로 한다.
  • 특별히 String클래스만 "Kim"과 같이 큰따옴표로만으로 간략히 표현하는 것이 허용되지만, 원래 String은 클래스 이므로 new연산자를 통해 객체를 생성해야한다.
// 기존 방식
String[] name = new String[3];
name[0] = new String("Kim");
name[1] = new String("Park");
name[2] = new String("Yi");

// String 허용 방식
String[] name = new String[3];
name[0] = "Kim";
name[1] = "Park";
name[2] = "Yi";

  • 위의 이미지와 같이 배열에 실제 객체가 아닌 객체의 주소가 저장이 되어있다. 이처럼, 기본형 배열이 아닌 경우, 즉, 참조형 배열의 경우 배열에 저장되는 것은 객체의 주소이다.
  • 참조형을 객체 배열이라고도 한다.

2.3 char배열과 String클래스

  • 사실 문자열이라는 용어는 '문자를 연이어 늘어놓은 것'을 의미하므로 문자배열인 char배열과 같은 뜻이다.
  • 그런데 자바에서는 char배열이 아닌 String클래스를 이용하서 문자열을 처리하는 이유는 String클래스가 char배열에 여러 가지 기능을 추가하여 확장한 것이기 때문이다. 그래서 더 편하다.

    String클래스는 char배열에 기능(메소드)을 추가한 것이다.

  • 객체지향언어인 자바에서는 char배열과 그에 관련된 기능(=함수, 메소드)들을 함께 묶어서 클래스에 정의한다.
  • char배열과 String클래스의 한 가지 중요한 차이는, String객체(문자열)는 읽을수만 있을 뿐 내용을 변경할 수 없다.
매서드설명
char charaAt(int index)해당 위치에 있는 문자 반환
int length()문자 길이 반환
String substring(int from, int to)문자열에서 해당 범위 문자열 반환(마지막은 포함X)
boolean equals(Object obg)문자열의 내용이 obj와 같은지 확인
char[]toCharArray()문자열을 문자배열(char[])로 변환하여 반환

3. 다차원 배열

3.1 2차원 배열의 선언과 인덱스

선언 방법선언 예
타입[ ][ ] 변수이름;int[ ][ ] score;
타입 변수이름[ ][ ];int score[ ][ ];
타입[ ] 변수이름[ ];int[ ] score[ ];
  • 2차원 배열은 주로 테이블 형태의 데이터를 담는데 사용되며, 만일 4행 3열의 데이터를 담기 위한 배열은 아래와 같다.
int[][] score = new int[4][3]

3.2 2차원 배열의 초기화

  • 2차원 배열도 괄호{}를 써서 생성과 초기화를 동시에 할 수 있다.
int[][] arr = new int[][]{{1,2,3},{4,5,6}};
int[][] arr = {{1,2,3},{4,5,6}}; // new int[][]생략

class ArrayEx18 {
	public static void main(String[] args) {
		 int[][] score = {
							{ 100, 100, 100}
							, { 20, 20, 20}
							, { 30, 30, 30}
							, { 40, 40, 40}
						};
		int sum = 0;

		for(int i=0;i < score.length;i++) {
			for(int j=0;j < score[i].length;j++) {
				System.out.printf("score[%d][%d]=%d%n", i, j, score[i][j]);
			}
		}
		// socre 모든 합 구하기
		for (int[] tmp : score) { 
			 for (int i : tmp) { 
				sum += i;
			 } 
		} 

		System.out.println("sum="+sum);
	}
}

3.3 가변 배열

  • 자바에서는 2차원 이상의 배열을 '배열의 배열'의 형태로 처리한다는 사실을 이용하면 보다 자유로운 형태의 배열을 구성할 수 있다.
  • 2차원 이상의 다차원 배열을 생설할 때 전체 배열 차수 중 마지막 차수의 길이를 지저하지 않고, 추후에 각기 다른 길이의 배열을 생성함으로써 고정된 형태가 아닌 보다 유동적인 가변 배열을 구성할 수 있다.
int[][] score = new int[5][3]; // 5행 3열의 2차원 배열 생성
// 아래로 표현 가능
int[][] score = new int[5][];
score[0] = new int[3]; 
score[1] = new int[3];
score[2] = new int[3];
score[3] = new int[3];
score[4] = new int[3]; 

  • MultiArrEx1???
// 0행에 행번호를, 0열에 열번호를 저장한다. 
for(int i=1;i<SIZE;i++)
	board[0][i] = board[i][0] = (char)(i+'0');

  • 참고 : 자바의 정석 3판
profile
데이터 분석하고 있습니다

0개의 댓글