신규 블로그를 만들었습니다!

2020년 이후부터는 아래 블로그에서 활동합니다.

댓글로 질문 주셔도 확인하기 어려울 수 있습니다.

>> https://bluemiv.tistory.com/

1. 배열(array)

1.1. 배열이란?

많은 양의 데이터를 다룰때는 배열을 이용하는 것이 편하다.

배열은 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것

단, 데이터의 타입이 모두 동일해야 한다.

int[] score = new int(5) // 5: 배열의 길이
// score[0] ~ scroe[4], 총 5개의 공간이 생성됨

1.2. 배열의 선언과 생성

배열을 생성하는 방법은 2가지가 있다.

int[] score = new int(5);
int score[] = new int(5);

1.2.1. 배열의 생성

타입[] 변수이름; // 배열의 선언
타입[] 변수이름 = new 타입[길이] // 배열 생성 (new 키워드를 이용해서 배열을 생성)

배열을 선언만 하면, 아직 데이터를 저장할 공간은 생성되지 않는다.

new 키워드를 이용하여 배열을 생성하면, 배열 개수만큼 공간이 생성되고 score는 score[0]의 참조값을 가지게 된다. (배열은 처음 생성하면 default 값으로 원소의 값이 0이 할당된다)

1.3. 배열의 길이와 인덱스

배열을 사용할 때 인덱스를 벗어나는 값을 사용하지 않도록 주의해야한다. 컴파일러는 이런경우를 걸러주지 못한다.

1.3.1. 배열이름.length

자바에서는 JVM이 모든 배열의 길이를 별도로 관리하고 있다. .length를 통해 배열의 길이를 확인할 수 있다.

이미 생성된 배열의 길이는 변하지 않는다. 따라서, 배열이름.length는 상수이고 변경하지 못하며, 읽는 것만 가능하다.

int[] nums = {1, 2, 4, 6, 7, 8, 9};
nums.length = 10; // 컴파일 에러

1.3.2. 배열의 길이 변경하기

배열을 한번 생성하면 길이를 변경할 수 없는데, 배열의 길이를 늘리고 싶다면 새로운 배열을 생성하여 하나씩 복사를 하면 된다.

하지만, 위 작업은 비용이 많이 들기 때문에 처음부터 배열을 넉넉히 잡는 것이 좋다. 그렇다고 너무 크게 잡아도 낭비되므로 안되나. 적당히!

1.4. 배열의 초기화

배열을 초기화 방법 1.

int[] nums = new int[5];
nums[0] = 1;
nums[1] = 3;
nums[2] = 7;
nums[3] = 10;
nums[4] = 15;

배열을 초기화 방법 2.

int[] nums = new int[] {1, 3, 7, 10, 15};
// int[] nums = {1, 3, 7, 10, 15}; // new int[] 생략 가능

for(int num : nums) {
    System.out.println(num);
}

new int[] 를 생략하고 { ... } 만 작성하여 초기화 할 수도 있다. 주의할 점은 메소드 인자로 배열을 직접 넘기는 경우, new int[]를 생략할 수 없다. (배열을 선언하고 생성을 따로하는 경우는 생략이 불가능하다)

// 방법 1. new int[] 생략 가능
int[] nums = {1, 3, 7, 10, 15};
add(nums);

// 방법 2. new int[] 생략 불가능
add(new int[] {1, 3, 7, 10, 15});

// 컴파일 에러
add({1, 3, 7, 10, 15});

1.5. 배열의 복사

방법 1. for문을 이용한 방법

int[] arr = {1, 2, 3};

int[] tmp = new int[5];
for (int i=0; i<arr.length; i++) {
    tmp[i] = arr[i];
}
arr = tmp;

방법 2. System.arraycopy()를 이용한 방법

int[] nums = {1, 2, 3, 4};
int[] new_nums = new int[10];
System.arraycopy(nums, 0, new_nums, 0, nums.length);
// nums의 0번째부터 nums.length 길이 만큼, new_nums의 0번째 원소부터 복사하라
// - new_nums[0] = nums[0]
// - new_nums[1] = nums[1] ...
// - new_nums[nums.length-1] = nums[nums.length-1] ...

System.arraycopy() 를 이용하는 방법이 for문을 이용한 방법보다 간단하고 빠르게 배열을 복사할 수 있다.

for문은 배열 요소 하나하나에 접근해서 복사를 하지만, System.arraycopy()는 지정된 범위의 값을 통째로 복사하기 때문이다. (배열은 각 요소들이 연속적으로 저장되어 있는 특징 때문에, 이러한 것이 가능하다)

1.6. 배열의 활용

1.6.1. 총합과 평균

int sum = 0; // 합
float avg = 0f; // 평균

int[] scores = {100, 80, 77, 99, 67, 88};
for (int score : scores) {
    sum += score;
}

avg = sum / (float) scores.length;

System.out.println("총 합: " + sum);
System.out.println("평균: " + avg);

1.6.2. 최댓값과 최솟값

int[] scores = {78, 56, 44, 89, 67, 96, 23, 87, 80, 96};

int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for (int score : scores) {
    max = score > max ? score : max;
    min = score > min ? min : score;
}

System.out.println("최댓값: " + max);
System.out.println("최솟값: " + min);

1.6.3. 셔플 Suffle

int[] nums = new int[10];

// 배열 초기화
for (int i=0; i<nums.length; i++) {
    nums[i] = i;
}

// suffle
int tmp = 0;
for (int i=0; i<nums.length; i++) {
    int tmp_idx = (int) (Math.random() * nums.length);

    tmp = nums[i];
    nums[i] = nums[tmp_idx];
    nums[tmp_idx] = tmp;
}

// print
for (int num : nums) {
    System.out.print(num + " "); // 8 3 5 0 4 6 9 1 2 7
}

1.6.4. 임의의 값으로 배열 채우기

int[] code = {-2, -5, 1, 4, 8, -20, 0, 56, 3, -23}; // 불연속적인 값의 모음
int[] arr = new int[code.length];

for (int i=0; i<code.length; i++) {
    // 랜덤한 인덱스 값을 가져와서 배열에 담음
    int tmp_idx = (int) (Math.random() * code.length);
    arr[i] = code[tmp_idx]; 
}

for (int element : arr) {
    System.out.print(element + " ");
}

1.6.5. 정렬하기 sort

int[] data = new int[10];

// 초기화
for(int i=0; i<data.length; i++) {
    data[i] = (int)(Math.random() * 100); // 0 ~ 99까지의 수
}

// Sort
int tmp = -1;
for (int i=0; i<data.length-1; i++) {
    for (int j=i+1; j<data.length; j++) {
        if(data[i] > data[j]) {
            tmp = data[i];
            data[i] = data[j];
            data[j] = tmp;
        }
    }

    // Print step by step
    System.out.print((i+1) + "번째: ");
    for (int d : data) {
        System.out.print(d + " ");
    }
    System.out.println();
}

// Print
for (int d : data) {
    System.out.print(d + " ");
}
/*결과
1번째: 3 34 40 36 58 5 4 85 51 29 
2번째: 3 4 40 36 58 34 5 85 51 29 
3번째: 3 4 5 40 58 36 34 85 51 29 
4번째: 3 4 5 29 58 40 36 85 51 34 
5번째: 3 4 5 29 34 58 40 85 51 36 
6번째: 3 4 5 29 34 36 58 85 51 40 
7번째: 3 4 5 29 34 36 40 85 58 51 
8번째: 3 4 5 29 34 36 40 51 85 58 
9번째: 3 4 5 29 34 36 40 51 58 85 
3 4 5 29 34 36 40 51 58 85 
*/

1.6.6. 빈도수 구하기

int[] nums = new int[10];
int[] counts = new int[10]; // default 값으로 0으로 초기화 됨

// nums 초기화
System.out.print("nums: ");
for(int i=0; i<nums.length; i++) {
    nums[i] = (int)(Math.random() * 10); // 0 ~ 9 까지의 수
    System.out.print(nums[i] + " ");
}
System.out.println();

// Counting
for(int num : nums) {
    counts[num]++;
}

// Display
for (int i=0; i< counts.length; i++) {
    System.out.println(i + "의 개수: " + counts[i]);
}
/* 결과
nums: 4 5 2 7 0 2 5 8 8 7 
0의 개수: 1
1의 개수: 0
2의 개수: 2
3의 개수: 0
4의 개수: 1
5의 개수: 2
6의 개수: 0
7의 개수: 2
8의 개수: 2
9의 개수: 0
*/

2. String 배열

2.1. String 배열의 선언과 생성

정수 배열 선언하듯이 똑같이 하면 된다.

String[] name = new String[3];

2.2. String 배열의 초기화

String[] name = new String[] {"Kim", "Tae", "Hong"};
String[] name = {"Kim", "Tae", "Hong"};

new String[] 은 생략이 가능하다.

문자열은 참조형 타입이기 때문에 각 원소에는 문자열의 주소값이 들어간다. (즉, 실제 값이 아닌 주소값이 들어감)

2.3. char 배열과 String 클래스

문자열은 사실 문자의 연이어 나열한것과 같은데(char 배열) String 클래스를 사용하는 이유는 기타 유용한 기능들이 String 클래스에 포함되어 있어서 문자열을 정의할때 String 클래스를 이용한다.

2.3.1. char 배열과 String 클래스의 차이점

char 배열과 String 클래스의 차이점이 있는데, 문자열은 변경할 수 없기 때문에 새로운 문자열로 생성된다.

변경 가능한 문자열을 다루려면 StringBuffer 클래스를 이용하면 된다.

2.3.2. String 클래스의 주요 메소드

  • char charAt(int index): 문자열에서 해당 위치에 있는 문자를 반환한다.
  • int length(): 문자열의 길이를 반환한다.
  • String substring(int from, int to): 문자열에서 해당 범위(from ~ to)에 있는 문자열을 반환한다.
  • boolean equals(String str): 문자열의 내용이 같은지 확인한다.
  • char[] toCharArray(): 문자열을 문자배열(char[])로 변환해서 반환한다.

2.3.3. char 배열과 String 클래스의 변환

char[] chArr = {'A', 'B', 'C'};
String str = new String(chArr); // char 배열을 String으로 변경
char[] tmp = str.toCharArray(); // String 을 char 배열로 변경

2.4. 커맨드 라인을 통해 입력받기

커맨드로 입력받은 인자 args는 아무런 값도 입력하지 않으면 크기가 0인 배열로 생성된다.

만약 크기가 0인 배열이 아니라 null로 지정되는경우 if 문을 이용하여 null 처리를 해줘야 하겠지만, JVM에서 크기 0인 배열을 생성해주기 때문에 이런 수고를 덜 수 있다.

3. 다차원 배열

3.1. 배열 선언 및 초기화

int[][] score = new int[4][3]; // 4행 3열, 2차원 배열 생성
System.out.println(score[0][0]); // 인덱스로 값을 참조
// 생성 및 초기화
int[][] arr = {
        {1, 2, 3},
        {4, 5, 6}
};

3.2. for문 이용하기

// 1. for문을 이용한 출력
for(int i=0; i<arr.length; i++) {
    for(int j=0; j<arr[i].length; j++) {
        System.out.print(arr[i][j] + " ");
    }
    System.out.println();
}

// 2. 향상된 for문을 이용한 출력
for(int[] tmp : arr) {
    for(int num : tmp) {
        System.out.print(num + " ");
    }
    System.out.println();
}

3.3. 활용

행렬 곱셈

int[][] m1 = {
        {1, 2, 3},
        {4, 5, 6}
};
int[][] m2 = {
        {1, 2},
        {3, 4},
        {5, 6}
};

final int ROW = m1.length;
final int COLUMN = m2[0].length;
final int M2_ROW = m2.length;
int[][] m3 = new int[ROW][COLUMN];
for (int i=0; i<ROW; i++) {
    for (int j=0; j<COLUMN; j++) {
        for (int k=0; k<M2_ROW; k++) {
            m3[i][j] += m1[i][k] * m2[k][j];
        }
        System.out.print(m3[i][j] + " ");
    }
    System.out.println();
}
22 28
49 64

Reference

Java의 정석, 남궁 성 지음

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기