Java/Java 스터디

Chapter 05. 배열

되다 2023. 2. 15. 17:00

1. 배열 (array)

1.1 배열(array)이란?

int score1, score2, score3, score4;

-> int[] score = new int[5];
  • 값을 저장할 수 있는 공간은 score[0]부터 score[4]까지 5개
  • score 자체는 값을 저장할 수 있는 공간이 아닌 참조변수임


1.2 배열의 선언과 생성

선언 방법 선언 예

타입[] 변수 이름; int[] score;
String[] name;  
타입 변수이름[]; int score[];
String name[]  

→ 두 가지 방법이 있으나 ‘타입[] 변수이름’ 추천

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

//이 선언 방법을 보통 아래와 같이 줄인다.
int[] score = new int[5]


1.3 배열의 길이와 인덱스

  • 주의점 : index의 범위를 벗어난 값을 index로 사용하면 안된다.

  • 프로그래밍을 하다보면 길이가 0인 배열이 필요한 상황이 있다.

배열 이름.length

int[] arr = new int[5];
int tmp = arr.length; // arr.length의 값을 5이고 tmp에 저장된다.
for (int i = 0; i < 6; i ++){}

//코드의 관리를 쉽게하기

for(int i = 0; i < score.length;i ++){}

→ .length를 사용하면 배열의 길이를 직접 적어주지 않고, 에러가 발생할 확률이 적어진다.

배열의 길이 변경하기

→ 이 작업은 비용이 많이 들기 때문에 처음부터 배열의 길이를 넉넉하게 잡아주는 것이 좋다.


1.4 배열의 초기화

  • 배열은 생성과 동시에 자동적으로 자신의 타입에 해당하는 기본값으로 초기화 됨
int[] score = new int[5];
score[0] = 50;
score[1] = 60;
score[2] = 70;
score[3] = 80;
score[4] = 90;
int[] score = new int[] {50, 60, 70, 80, 90}; 
// 다음과 같이 배열의 생성과 초기화를 동시에 진행할 수 있다
// {}괄호 안의 개수로에 의해 배열의 길이가 결정되기 때문에 []안에 숫자를 적지 않아도 된다.
  • new 타입[] 생략 가능
int[] score = {50, 60, 70, 80, 90}; 
  • 길이가 0인 배열
int[] score = new int[0];
int[] score = new int[]{};
int[] score = {};

배열의 출력

  • 반복문의 형태로 배열의 저장된 값을 확인할 수 있다.
int[] iArr = {100, 95, 80, 70, 60};

for (int i = 0; i < iArr.length; i++)
{
		System.out.println(iArr[i]);
}
  • Arrays.toString(배열이름)’ 메서드를 사용해서 출력할 수 있다
int [] iArr = {100, 95, 90, 85, 80};

System.out.println(Arrays.toString(iArr));

[100, 95, 90, 85, 80] 출력

  • 만약 메서드 없이 바로 출력한다면?
import java.util.*;
class FlowEx2 {
    public static void main(String[] args) {

        int[] iArr = {100, 95, 90, 85, 80};

        System.out.println(iArr);
        }
    }

[I@7ef20235 (자바 내의 주소가 출력된다)

  • 예외 : char 배열
char [] chArr = {'a', 'b', 'c', 'd'};
System.out.println(chArr);

abcd char 배열은 println 메서드로 출력하면 각 요소가 구분자없이 그대로 출력된다.


1.5 배열의 복사

  • 배열은 한 번 생성하면 그 길이를 변경할 수 없기 때문에 더 많은 저장공간이 필요하다.
  • for문을 이용한 복사
int[] arr = new int[5];
//....
int[] tmp = new int[arr.length*2];; //기존 배열보다 길이가 2배인 배열 생성

for(int i = 0; i < arr.length; i++)
{
		tmp[i] = arr[i]; // arr값을 tmp에 저장
}

arr = tmp; //참조변수 arr이 새로운 배열을 가리키게 한다.

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

System.arraycopy() 를 이용한 복사

  • 복잡한 for문 대신에 System 클래스의 arraycopy()를 통해 간단하고 빠르게 배열 복사 가능
    • for문 → 배열 요소 하나하나에 접근해서 복사
    • arraycopy() → 요소가 연속적으로 저장되어 있다는 배열의 특성을 통해 한 번에 통째로 복사

    for(int i = 0; i < num.length; i++) {newNum[i] = num[i]
    
    // 기존의 for문 대신
    
    System.arraycopy(num, 0, newNum, 0, num.length)
    // num // [0] 에서 // nueNum // [0]으로 // num.length개의 데이터를 복사한다.
    
    • 에러 : ArrayIndexOutOfBoundsException → 복사 내용보다 여유공간이 적으면 발생함


1.6 배열의 활용

[예제 5-5] 총합과 평균

class FlowEx2 {
    public static void main(String[] args) {

        int sum = 0;
        float average = 0f;
        int [] score = {100, 88, 92, 94 ,40};

        for(int i = 0; i < score.length; i++)
        {
            sum += score[i];
        }

        average = sum / (float)score.length; /* 계산결과를 float로 얻기 위해 형변환
				int와 int와의 연산은 int로 결과가 나오기 때문에 float형으로 변경시켜준다.
				*/
				
        System.out.println("총점: " + sum);
        System.out.println("평균: " + average);

    }
}

총점: 414 평균: 82.8

임의의 값으로 배열 채우기

for(i = 1; i < arr.length; i++){
		arr[i] = (int) (Math.random() * 5); // 0~4 범위의 임의의 값을 저장

예제 5-8 로또

class Ex {
    public static void main(String[] args) {

        int[] Lotto = new int[45];

        for(int i = 0; i < Lotto.length; i ++)
        {
            Lotto[i] = i + 1;
        }

        int tmp = 0;
        int j = 0;

        for(int i = 0; i < 6; i++)
        {
            j = (int) (Math.random() * 45);
            tmp = Lotto[i];
            Lotto[i] = Lotto[j];
            Lotto[j] = tmp;
        }

        for(int i = 0; i < 6; i ++)
        {
            System.out.println(Lotto[i]);
        }

    }
}

2. String 배열

2.1 String 배열의 선언과 생성

  • String 타입의 참조형 변수의 기본값을 null이다.

참고 → 변수의 타입에 따른 기본값

자료형 기본값

boolean false
char 'u0000’
byte, short, int 0
long 0L
float 0.0f
double 0.0d 또는 0.0
참조형 변수 null

2.2 String 배열의 초기화

String [] name = new String[3]; // 길이가 3인 String배열 생성
name[0] = "Kim";
name[1] = "Park";
name[2] = "Yi";

// 또는 다음과 같이 괄호를 사용하여 간단하게 초기화할 수 있다.

Stirng[] name = new Stinrg[]{"Kim", "Park", "Yi"};
  • 원래 String은 클래스이므로 아래처럼 new 연산자를 통해 객체를 생성해야한다.
String[] name = new String[3];
name[0] = new String("Kim");
name[1] = new String("Park");
name[2] = new String("Yi");
             **name**

 

  • 배열에는 실체 객체가 아닌 객체의 주소가 저장되어 있다.

2.3 char 배열과 String 클래스

  • 사실 문자열이라는 용어는 ‘문자를 연이어 늘어놓은 것’을 의미하므로 문자배열인 char배열과 같은 뜻이다

  • 따라서 char배열을 사용하는 것보다 String클래스를 사용하는 것이 문자열을 다루기 더 편리하다.
  • char 배열과 String클래스의 중요한 차이 : String객체는 문자열을 읽을 수만 있을 뿐, 내요을 변경할 수 없다
String str ="Java";
str = str + "8"; //"Java8"이라는 새로운 문자열 str에 저장된다
System.out.println(str); //"Java8"

→ 위의 문장에서 str의 내용이 변경되는 것이 아닌, 문자열은 변경할 수 없으므로 아예 새로운 내용의 문자열이 생성되는 것이다.

String 클래스의 주요 메서드

 

메서드  설명
char charAt(int index) 문자열에서 해당 위치(index)에 있는 문자를 반환한다.
int length() 문자열의 길이를 반환한다.
String substring(int from, int to) 문자열에서 해당 범위(from ! to)에 있는 문자열을 반환한다
boolean equals(Object obj) 문자열의 내용이 obj와 같은지 확인한다. 같으면 결과는 true, 다르면 false가 된다.
char[] toCharArray() 문자열을 문자배열(char[)로 변환해서 반환한다.

char charAt()

String str = "ABC**D**E**"**
char ch = str.charAt(**3**); // 문자열 str의 4번째 문자 'D'를 ch에 저장

String substring

String str = "0**123**45"
String tmp = str.substring(1,4); // str에서 index범위 1~4의 문자들을 반환
System.out.println(tmp) // 123이 출력된다

Boolean equals()

String str = "abc"
if(str.equals("abc")){ // str와 "abc"가 내용이 같은지 확인한다.
	//....
}
  • 대소문자 구분없이 비교하려면 equals()대신 equalsIgnoreCase()를 사용해야한다

char 배열과 String 클래스의 변환

char[] chArr = {'A', 'B', 'C'};
String str = new String(chArr); // char 배열 => String
char[] tmp = str.toCharArray(); // String => char 배열
  • 가끔 char배열을 String클래스로 변환하거나, 또는 그 반대로 변환해야하는 경우가 있다.

3. 다차원 배열

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

선언방법 선언 예

타입[][] 변수이름; int[][] score;
타입 변수이름[][]; int score[][];
타입[] 변수이름[]; int[] score[];

→ 3차원 이상의 고배열 선언은 대괄로 개수를 차원의 수만큼 추가해 주기만 하면 된다.

int[][] score = new int[4][3]

4행 * 3열, 총 12개의 int를 저장할 수 있는 공간이 마련된다.

int int int

int int int
int int int
int int int

3.2 2차원 배열의 초기화

  • 2차원 배열도 괄호{}를 사용햇 생성과 초기화를 동시에 할 수 있다.
int[][] arr = new int[][] { {1, 2, 3}, {4, 5, 6} };
int[][] arr = { {1, 2, 3}, {4, 5, 6} }; // new int가 생략됨
  • 크기가 큰 배열을 아래와 같이 행별로 줄바꿈 해주는 것이 가독성이 좋다
  • 코드
int[][] arr = new int[][] { 
		            {1, 2, 3}, 
		            {4, 5, 6} 
		        	};

ex) 다음과 같은 자료를 데이터 배열에 저장하려면?

국어 영어 수학

1 100 100 100
2 20 20 20
3 30 30 30
4 40 40 40
5 50 50 20

 

int[][] score = {
		{100, 100, 100}
		,{20, 20, 20}
		,{30, 30, 30}
		,{40, 40, 40}
		,{50, 50, 50}
		};
  • 2차원 배열은 ‘배열의 배열’로 구성되어 있다

예제 5-18

class Ex {
    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[j].length; j++)
            {
                System.out.printf("score[%d][%d]=%d%n", i, j, score[i][j]);
            }
        }
        for(int[] tmp : score)
        {
            for(int i: tmp)
            {
                sum += i;
            }
        }
        System.out.println("sum="+sum);
    }
}
  • 향상된 for문
for (int i : score){  // 에러. 2차원 배열 score의 각 요소는 1차원 배열
		sum += i;
}
for (int[] tmp : score){ // score의 각 요소(1차원 배열 주소)를 tmp에 저장
				for(int i : tmp){ // tmp는 1차월 배열을 가리키는 참조변수
						sum += i;
				}
}

3.3 가변 배열

int[][] score = new int[5][];
score[0] = new int[4];
score[1] = new int[3];
score[2] = new int[2];
score[3] = new int[2];
score[4] = new int[3];
  • 이 코드와 같이 2차원 배열을 생성하면 각 행마다 다른 길이의 배열을 생성하는 것이 가능하다
 int[][] score = {
                            {100, 100, 100, 100}
                          , {20, 20, 20}
                          , {30, 30, }
                          , {40, 40, 40}
                        };
  • 이 코드와 같이 중괄호를 이용해서 생성과 초기화를 동시에 할 수 있다