참고 교재 : 자바의 정석
배열이란??
같은 타입의 여러 변수를 하나의 묶음으로 다루는 것이다.
변수와는 다르게 배열은 각 저장공간이 연속적으로 배치되어 있다는 특징을 가진다.
public class Main {
public static void main(String[] args) {
int[] score;
score = new int[5];
}
}
이렇게 선언하면 배열에는 어떻게 저장이 될까??
1. new int[5]를 통해서 빈공간 5개의 int형 데이터를 저장할 수 있는 공간이 생성된다.
2. 대입연산자로 첫번째 빈공간의 주소값이 score에 저장된다. (ex) 0x200
배열을 사용할때 주의해야 하는 부분
배열을 사용할때는 인덱스의 범위는 0 - 배열길이 -1 인걸 주의해야 한다.
만약 유효한 범위를 벗어난 곳을 참조하게 된다면 ArrayIndexOutBoundsException을 발생시킨다.
보통 배열의 Index로 변수를 많이 사용한다 -> 변수의 값을 잘못설정한다면 컴파일러는 실수를 걸러주지 못한다!!
왜?? -> 변수의 값은 실행 시에 대입되기 때문에 컴파일러는 이 값의 범위를 확인할 수 없습니다.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int index;
int[] score;
score = new int[5];
//index입력
index = scanner.nextInt();
//score에 접근
System.out.println(score[index]);
}
}
해당 코드를 확인해보면 컴파일러는 실행했을 때 Index의 값이 무엇인지 알 수 없다. 하지만 사용자가 입력값을 5를 준다면
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
at Main.main(Main.java:13)
다음과 같은 오류가 발생하게 되는걸 볼 수 있을것이다.
배열의 복사
기존에 사용하던 배열의 크기를 늘려서 값을 더 저장하는건 불가능하다. 그래서 새로운 배열을 생성해서 값을 저장해줘야 하는데
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int[] score = new int[5];
for(int i = 0;i<score.length;i++)
{
score[i] = i+1;
}
int[] tmp = new int[score.length]; // score에 비해서 두배정도 큰 배열을 생성
for(int i = 0;i<score.length;i++)
{
tmp[i] = score[i];
}
System.out.println("변경하기 전");
System.out.println(score);
System.out.println(tmp);
System.out.println("변경하기 후");
score = tmp;//저장값 변경
System.out.println(score);
System.out.println(tmp);
}
}
다음과 같이 수행하면 더 큰 배열에 값을 저장할 수 있다. 여기서는 출력으로 주소값을 출력하고 있다.

저장값을 변경하기 전에는 이렇게 형성되어 있고 각각 다른 주소값을 가지고 있다.

저장값을 변경한 이후에는 그림처럼 score도 같은 배열의 주소값을 가지게 되는데 이러면 5칸짜리 배열은 아무도 가리키고 있지 않게 된다.
그러면 메모리만 차지하고 사용은 못하는 공간으로 남아버리는데 이때 가비지 컬렉터가 문제를 해결해준다.
JVM의 가비지 컬렉터는 쓸모없게된 배열을 자동적으로 메모리에서 제거해주는 역할을 수행해준다 -> 문제 해결!!
또 다른 방법은 System.arraycopy를 사용하는 것이다.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int[] score = new int[5];
for(int i = 0;i<score.length;i++)
{
score[i] = i+1;
}
int[] tmp = new int[score.length]; // score에 비해서 두배정도 큰 배열을 생성
for(int i = 0;i<score.length;i++)
{
tmp[i] = score[i];
}
int[] tmp2 = new int[score.length + tmp.length];
//Score index 0 ~ (score.length-1)까지 저장된 값을 tmp2의 index 0 위치부터 복사해서 넣는다.
System.arraycopy(score,0,tmp2,0,score.length);
//tmp index 0 ~ (tmp.length-1)까지 저장된 값을 tmp2의 index score.length 위치부터 복사해서 넣는다.
System.arraycopy(tmp,0,tmp2, score.length,tmp.length);
}
}
String 배열
public class Main {
public static void main(String[] args) {
String[] name = new String[3]; // 여기서 각각은 null값이 들어있다. 참조변수의 기본값
name[0] = new String("kim");
name[1] = new String("Park");
name[2] = new String("Yi");
for(int i = 0;i<3;i++)
{
System.out.println(name[i]);
}
}
}
String 배열은 각 칸에 들어있는 값은 값이 아닌 객체의 주소값이 들어가 있다.
근데 왜 for문을 이용해서 출력을 할 때 주소값이 아닌 kim, Park, Yi가 출력될까??
바로 toString()때문이다.
String 클래스를 들어가면
public String toString() {
return this;
}
다음과 같이 toString()이 메소드로 정의가 되어 있다.
println()을 사용해서 출력을 하게 된다면 자동으로 toString()메소드가 실행되면서 주소값이 아닌 참조하고 있는 주소값에 들어있는 값을 출력하게 된다. 그래서 저장된 값이 결과로 보여지는 것이다.
또 다른 궁금증이 생길 수 있다.
C언어에서는 char배열로 문자열을 다루던데 Java에서도 그렇게 하면 안되나요??
JAVA에서 String클래스는 char배열에 기능을 추가한 것이다.
여기서 가장 큰 차이점은 String객체는 읽을 수 있지만 내용을 변경할 수는 없다는 것이다.
public class Main {
public static void main(String[] args) {
String str = "Hello";
str = str + " rkrzy";
System.out.println(str);
}
}
코드를 확인하면 문자열에 더해져서 str이 참조하고 있는 객체의 값을 출력하는 걸로 보이지만 새로운 객체를 만들어서 출력하고 있는것이다.
public class Main {
public static void main(String[] args) {
String str = "Hello";
System.out.println(System.identityHashCode(str));//1072591677
str = str + " rkrzy";
System.out.println(System.identityHashCode(str));//1175962212
System.out.println(str);
}
}
다음 코드를 실행하면 서로 다른 해쉬값(고유 식별값)이 나오는걸 확인할 수 있다 -> 다른 객체라는것.
다차원 배열
public class Main {
public static void main(String[] args) {
int[][] score = {
{ 100, 100, 100}
,{ 30, 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++)
{
sum = score[i][j];
}
}
System.out.println(sum);
}
}
2차원 배열을 생성하고 들어있는 값들을 모두 더하는 코드를 작성했다.
1. 여기서 score[0]에는 어떤 값이 들어 있을까??
2. score[0][0]에는 어떤 값이 들어 있을까??
정답
1. 참조하기 위한 주소값
2. 100이 저장됨.

그림처럼 저장되고 score[0][0]과 같은 형태로 저장될 때만 값이 들어가 있다는 걸 기억하자.
나머지는 주소값을 저장하고 있다.
int [][] arr1= new int[5][];
arr1[0] = new int[3];
arr1[1] = new int[2];
arr1[2] = new int[1];
int[][] score = {
{ 100, 100, 100}
,{ 200, 200}
,{ 300}
};
이렇게 길이가 다르게 다차원 배열을 생성하는 것 또한 가능하다.
public class Main {
public static void main(String[] args) {
int[][] m1 = {
{1,2,3},
{4,5,6}
};
int[][] m2 = {
{1,2},
{3,4},
{5,6}
};
final int ROW = m1.length;
final int COL = m2[0].length;
final int M2_ROW = m2.length;
int[][] m3 = new int[ROW][COL];
for(int i =0;i<ROW;i++)
{
for(int j = 0;j<COL;j++)
{
for(int k = 0;k<M2_ROW;k++)
{
m3[i][j] += m1[i][k] * m2[k][j];
}
}
}
for(int i = 0;i<ROW;i++)
{
for(int j = 0;j<COL;j++)
{
System.out.printf("%3d ", m3[i][j]);
}
System.out.println();
}
}
}
다차원 배열 활용 예시다. 행렬의 곱셈을 코드로 작성한 것이다.
22 28
49 62
출력값은 다음과 같이 표시된다.
새롭게 알게된 사실
- 배열은 길이가 0으로도 생성이 가능하고 유용한 부분이 있다.
- println을 이용해서 char배열을 출력하면 저장된 값들이 구분자없이 출력된다.
- 쓸모없게된 배열은 JVM의 가비지 컬렉터가 메모리에서 제거를 해준다.
- Math.random()은 0.0이상 1.0미만의 난수를 반환한다.
- String[] name = new String[3]과 같은 형태로 생성하면 각각은 기본값(null)로 초기화 된다.
- 길이가 다르게 다차원 배열을 생성하는게 가능하다.
- println메서드로 1차원 char배열의 참조변수를 출력하면, 배열의 모든 요소를 한 줄로 출력한다.
'자바(Java)' 카테고리의 다른 글
선택 안됨 [자바][Java Programming Language]객체지향 프로그래밍 -package와 import (0) | 2025.02.08 |
---|---|
[자바][Java Programming Language]객체지향 프로그래밍 - 오버라이딩 (0) | 2025.01.24 |
[자바][Java Programming Language]객체지향 프로그래밍 - 상속 (0) | 2025.01.23 |
[자바][Java Programming Language] 객체지향프로그래밍(클래스, 생성자, 매개변수, 메서드) (1) | 2025.01.22 |