제이제이
article thumbnail

 

배열


🤔 배열이란?

  • 자료형이 같은 둘 이상의 데이터 값을 저장할 수 있는 메모리 공간을 의미합니다.
  • 배열은 구조에 따라 1차원 배열2차원 이상의 배열인 다차원 배열로 구분됩니다.
  • 먼저 1차원 배열부터 살펴보겠습니다.

 

❓ 1차원 배열이란?

  • 자료형이 같은 둘 이상의 데이터를 저장할 수 있는 1차원 구조의 메모리 공간을 의미합니다.
  • 자바는 배열을 인스턴스(객체)로 인식하고 사용합니다.

 

1차원 배열의 선언

방법1

int [] array = new int[5]; //크기가 5인 int형 1차원 배열의 생성문

 

  • 위의 코드를 뜯어보면 등호를 기준으로 왼편에는 배열의 참조 변수 선언과 오른쪽에는 배열의 생성을 나타납니다.

왼쪽(배열의 참조 변수 선언)

int[] array //배열의 인스턴스를 참조할 수 있는 '참조변수의 선언'

 

오른쪽(배열의 생성)

new int[5] //int형 값 5개를 저장할 수 있는 '배열 인스턴스(객체)의 선언'

 

  • 또한 다음과 같이 배열의 참조 변수 선언과 배열의 생성을 따로 구분하여 1차원 배열을 선언할 수 있습니다.

 

방법2

int [] array;//배열의 참조변수 선언
array = new int[5]; //배열의 인스턴스 생성

 

  • 아래의 코드를 통해 배열을 더욱 자세히 살펴봅시다.

 

💻 예시 코드

public class ArrayIsInstance{
		public static void main(String[] args) {
			//길이가 5인 int형 1차원 배열 생성
			  int[] array1 = new int[5];

		  //길이가 7인 double형 1차원 배열 생성
				double[] array2 = new double[7];

			//배열의 참조변수와 인스턴스 생성을 분리하여 선언한 float형 1차원 배열의 생성
				float[] array3;
				array3 = new float[9];

			//배열의 인스턴스 변수에 접근하여 출력
        System.out.println("배열 ar1 길이:" + array1.length);
        System.out.println("배열 ar2 길이:" + array2.length);
        System.out.println("배열 ar3 길이:" + array3.length);
    }
}

 

📸 출력 결과

배열 array1 길이:5
배열 array2 길이:7
배열 array3 길이:9

 

  • 위의 코드에서 배열의 인스턴스 변수의 length에 접근하여 생성된 배열의 길이를 출력하였습니다.
  • 이렇게 인스턴스 변수를 통해 접근이 가능하다는 것은 배열이 인스턴스(객체)임을 알려줍니다.
  • 또한 1차원 배열의 참조변수(인스턴스 변수)배열의 길이에 상관없이 참조가 가능합니다.
public static void main(String[] args){
		int[] array = new int[50];
		System.out.println("length: " + array.length); //length:50
		array = new int[100]; //길이가 다른 배열을 참조함
		System.out.println("length: " + array.legnth); //length: 100
}

 

  • 배열은 int형 doulbe형과 같은 기본 자료형을 대상뿐만 아니라 다른 인스턴스(객체)를 저장할 수 있는 배열의 생성도 가능합니다.

 

💻 예시 코드

class Box{ //Box 인스턴스(객체) 정의
		private String conts;

    public Box(String conts) {
        this.conts = conts;
    }
    public String toString(){
        return conts;
    }
}
public class ArrayInInstance2 {
    public static void main(String[]args){
        Box[] array = new Box[5]; // 길이가 5인 Box형 1차원 배열의 생성
        System.out.println("length : " + array.length);
    }
}

 

📸 출력 결과

length : 5

 

  • 위의 코드에서 Box 클래스를 정의하고 이 클래스의 인스턴스 5개를 정의할 수 있는 배열을 생성하였습니다.
Box[] array = new Box[5];

 

  • 여기서 주의해야 할 사항은 다음과 같습니다.

-> Box 인스턴스 5개를 저장할 수 있는 참조변수의 배열 생성입니다.

 

  • 즉, Box 인스턴스(객체) 생성과는 관계가 없습니다.
  • 단지 5개의 Box 인스턴스를 저장할 수 있는 배열을 만든다는 점입니다.

 

배열에 값을 저장하고 참조하는 방법

  • 다음으로는 배열에 값을 저장하고 이를 참조하는 방법에 대해서 알아봅시다.
int [] array = new int[3];//int형 값 3개를 저장할 수 있는 배열을 선언

 

생성된 배열에 값을 저장하는 방법

  • 생성된 배열의 첫번째 공간(첫번째 요소)에 값을 저장하는 방법은 다음과 같습니다.
array[0] = 10;

 

배열의 요소

  • 다음으로 두번째 요소, 세번째 요소를 값을 저장하면 다음과 같습니다.
array[1]= 9; //배열의 두번째 요소에 정수 9을 저장
array[2]= 8; //배열의 세번째 요소에 정수 8을 저장

 

생성된 배열의 값을 참조하는 방법

  • 생성된 배열의 값을 참조하는 방법은 다음과 같습니다.
  • 다음은 배열 array에 저장된 모든 요소의 값을 저장하는 코드입니다.
int num = array[1] + array[2] + array[3];

 

  • 앞서 살펴봤던 Box형 배열에 인스턴스의 값을 저장하고 참조하는 방법도 위와 동일합니다.
  • 앞서 봤던 Box형 배열의 코드를 이용해 값을 저장하고 참조하는 방법을 살펴봅시다.

 

💻 예시 코드

class Box{
		private String conts;
		
		Box(String cont){
			this.conts = cont;
  }
		public String toString(){
			return conts;
  }
}

public class BoxArray {
    public static void main(String[]args){
        Box[] array = new Box[3];

        //Box 배열에 인스턴스의 값을 저장
        array[0] = new Box("First");
        array[1] = new Box("Second");
        array[2] = new Box("Third");

        //저장된 인스턴스의 참조
        System.out.println(array[0]);
        System.out.println(array[1]);
        System.out.println(array[2]);
    }
}

 

📸 출력 결과

First
Second
Third

 

  • 위의 코드를 살펴보면 Box형 배열의 생성 이후에 다음과 같이 인스턴스를 생성하고 값을 저장했습니다.
array[0] = new Box("First");
array[1] = new Box("Second");
array[2] = new Box("Third");

 

  • 그리고 저장된 Box형 배열의 인스턴스에 있는 값들은 다음과 같이 참조합니다.
   System.out.println(array[0]);
   System.out.println(array[1]);
   System.out.println(array[2]);

 

  • 이와 관련하여 한가지 코드를 더 살펴봅시다. String형 배열에 문자열을 저장하고 참조하는 코드입니다.

 

public class StringArray {
    public static void main(String[]args){
        String[] sr = new String[7];
        sr[0] = new String("Java");
        sr[1] = new String("System");
        sr[2] = new String("Compiler");
        sr[3] = new String("Park");
        sr[4] = new String("Tree");
        sr[5] = new String("Dinner");
        sr[6] = new String("Brunch Cafe");

        int cnum = 0;
        for(int i = 0; i< sr.length; i++)
            cnum += sr[i].length();

        System.out.println("총 문자의 수: " + cnum);
    }
}

 

출력 결과

총 문자의 수: 43

 

위의 코드를 통해 주의 깊게 살펴보야 할 코드는 다음과 같습니다.

for(int i = 0; i < sr.length;i++)
	cnum += sr[i].length(); //String 인스턴스의 length 메소드 순차적 호출!
  • 반복문에서 변수i를 이용하여 모든 배열의 요소에 접근하였습니다.
  • 이렇게 반복문을 이용하면 ‘배열의 순차적 접근’을 진행할 수 있는 문장를 구성할 수 있습니다.
  • 단 두줄의 코드만을 이용해서 모든 문자열에 접근하는 배열이 아니면 불가능합니다.

 

배열을 생성과 동시에 초기화하기

배열도 변수와 마찬가지로 생성과 동시에 초기화가 가능합니다.

올바른 예 1)

int[] array = new int[] {1,2,3}; //배열의 생성과 동시에 초기화
  • 초기화할 값들의 수를 배열의 길이 정보를 계산할 수 있으므로 배열의 길이 정보를 생략하도록 약속하였습니다.

올바른 예 2)

int [] arr = {1,2,3); 
  • 위와 같이 문장을 줄여서 표현할 수도 잇습니다.

잘못된 예

int[] array3 = new int[3] {1,2,3}; //컴파일 오류가 발생함

 

배열의 참조 변수 선언

이번에는 배열의 참조 변수 선언에 대해 알아봅시다.

배열의 참조 변수 선언에는 다음과 같이 두 가지 방법이 있습니다.

참조 변수 선언 1)

int [] arr = new int[3]; //좀 더 자주 사용되는 방법

 

참조 변수 선언 2)

int arr[] = new int[3];

 

배열의 참조 값과 메소드

배열도 인스턴스(객체)이므로 메소드를 호출할 때 참조 값을 전달하는 것이 가능합니다.

이와 관련하여 다음의 코드를 살펴봅시다.

public static void main(String[] args) {
		int [] ar = {1,2,3,4,5,6,7};
		int sum = sumOfAry(ar); //배열의 참조 값 전달
      ....
}

위에서 호출한 메소드에 대해서도 살펴봅시다.

  • 호출된 메소드의 배개변수는 배열의 참조변수가 되어야 합니다.
static int sumOfAry(int[] ar) {
		int sum = 0;
		for(int i = 0;i<ar.length;i++){
			sum += ar[i];
		return sum;
}

 

또한 다음과 같이 배열의 참조값을 반환하는 메소드를 정의하는 것도 가능합니다.

static int[] makeNewIntAry(int len){
		int[] ar = new int[len];
		return ar;
}
🔥 배열도 인스턴스임으로 우리가 사용하던 인스턴스의 참조 값을 전달하고 반환했듯이
      배열의 참조 값도 전달 및 반환하는 방법또한 동일합니다.

 

배열의 초기화 및 복사

배열은 생성되면 모든 요소의 값이 0 또는 null로 초기화 됩니다.

예시1)

  • 다음과 같이 처음에 배열이 생성되면 그 안의 요소들은 0으로 초기화됩니다.
int [] array = new int[10]; //생성된 배열의 모든 요소 0으로 초기화된다.

 

예시2)

  • 다음과 같이 인스턴스(객체)의 배열을 생성하면 모든 요소들은 null로 초기화 됩니다.
String[] array = new String[10];//생성된 배열의 모든 요소는 null로 초기화된다.

 

그런데 int형 배열 등 기본 자료형의 배열을 생성할 때 0이외의 값을 초기화해야 할 경우가 있습니다.

이럴 경우에는 반복문을 이용해서 원하는 값을 배열에 저장할 수도 있지만

다음과 같이 메소드를 호출해서 원하는 값을 배열에 저장할 수도 있습니다.

public static void fill(int[]a, int val); //val로 전달되는 값으로 배열 a를 초기화한다.
public static void fill(int []a, int fromIndex, int toIndex,int val); //인덱서 fromIndex에서 부터 toIndex -1까지 val의 값으로 배열 a를 초기화한다.
  • 위의 두 메소드는 java.util.Arrays 클래스에 정의되어 있으며 각 기본 자료형마다 별도의 메소드가 오버로딩되어 있습니다.

 

또한 배열을 복사해야 하는 상황도 종종 생기는데 이때에도 반복문을 구성해서 복사를 진행할 수도 있지만

java.lang.System 클래스의 메소드를 통해서 복사할 수 있습니다.

public static void arraycopy(Object src, int srcPos,Object dest, int destPos, int length)
-> 복사 원본의 위치: arc의 인덱스 scrPos
-> 복사 대상의 위치: 배열 dest의 인덱스 destPos
-> 복사할 요소의 수: length

 

지금까지 알아본 메소드들에 대해서 코드를 통해 자세히 살펴봅시다.

import java.util.Arrays;

public class ArrayUtils {
    public static void main(String[]args){
        int[] ar1 = new int[10];
        int[] ar2 = new int[10];

				//배열 ar1의 요소 값을 7로 설정함
        Arrays.fill(ar1,7);
				//배열 ar의 요소 0의 값을 배열 ar2의 요소 3번째부터 4개까지(6번째까지)복사함
        System.arraycopy(ar1,0,ar2,3,4);

        for(int i = 0; i< ar1.length;i++){
            System.out.print(ar1[i] + " ");
        }
        System.out.println();

        for(int i = 0; i< ar2.length;i++){
            System.out.print(ar2[i] + " ");
        }
    }
}

 

출력 결과

7 7 7 7 7 7 7 7 7 7 
0 0 0 7 7 7 7 0 0 0

 

enhanced for문


  • enhanced for문은 자바 5버전에서 추가되었습니다.
  • 그리고 지금까지 많이 사용되는 반복문 중 하나입니다.

❓ enhanced for문이란?

🔥 배열에 저장된 모든 요소의 값 중에서 연산을 하거나 특정 조건에 따른 값 등을 찾을 때 사용하는 편리한 반복분이다.

 

이해하기 위해 그동안 사용한 for문과 enhanced for문에 대해 비교해 보겠습니다.

배열의 저장된 모든 값을 출력하는 요구조건에 따른 for 반복문과 enhanced for문에 대해서 비교하겠습니다.

for문의 경우

int[] array = {1,2,3,4,5};
for(int i = 0;i<array.length;i++){
	System.out.println(array[i]);
}

 

enhanced for문의 경우

for(int e: array) {
	System.out.println(e);
}

enhanced for문은 기존 for문에 비해서 다음과 같은 두가지 장점이 있습니다.

💡 1. 코드의 양이 줄어든다.
      2. 반복문의 구성 과정에서 배열의 길이를 직접 확인하고 입력할 필요가 없다.

 

enhanced for문의 구성

enhanced for는 다음과 같이 구성되어 있습니다.

for(요소 : 배열){
	반복할 문장들
}
  • 배열에서는 반복의 대상인 배열의 참조변수가 오게 됩니다.
  • 요소부분에서는 배열의 요소가 하나씩 담기게 됩니다.

 

enhanced for문의 과정

다음과 같이 배열 array가 있고 배열의 모든 요소들을 enhance for문으로 출력한다고 가정하겠습니다.

int [] array = {1,2,3,4,5};
for(int e : array) {
		System.out.println(e);
}

 

첫번째 반복의 상항

  • 첫번째의 요소가 변수 e에 담겨 문장을 실행합니다.
//첫 번째 반복의 상황
for(int e: array{
	e = array[0];
	System.out.println(e);
}

 

두번째 반복의 상황

  • 배열 array의 두 번째 요소가 변수 e에 담겨 실행됩니다.
//두 번째 반복의 상황
for(int e: array) {
	e = array[1];
	System.out.println(e);
}

이렇게 배열 array의 요소들이 마지막까지 변수 e에 담겨서 출력됩니다.

 

인스턴스(객체) 배열을 대상으로 하는 enhanced for문

다음과 같이 배열에 저장된 내용이 ‘인스턴스의 참조 값’인 경우에도 enhanced for문을 활용할 수 있습니다.

  • 먼저 Box라는 클래스를 정의했다고 가정하겠습니다.

다음의 코드를 살펴보겠습니다.

Box[] ar = new Box[10];
for(Box e : ar){
 ~~~
}

 

enhanced for문의 과정

첫번째 반복의 상황

// 첫 번째 반복의 상황
for(Box e : array) {
		e = array[0]; //첫 번째 요소에 저장된 참조 값을 e에 대입
    ~~
}

 

두번째 반복의 상황

// 두 번째 반복의 상황
for(Box e : array) {
		e = array[1]; //두 번째 요소에 저장된 참조 값을 e에 대입
    ~~
}

 

이와 관련하여 다음의 코드를 통해 자세히 살펴보겠습니다.

  • 상자에 부여된 번호를 확인하고 enhanced for문을 통해 번호 505번의 박스를 찾아 내용물을 출력하는 코드입니다.
class Box2{
    private String contents;
    private int boxNum;

    public Box2(int boxNum, String contents) {
        this.contents = contents;
        this.boxNum = boxNum;
    }
    public int getBoxNum(){
        return boxNum;
    }
    public String toString(){
        return contents;
    }
}

public class EnhancedForInst {
    public static void main(String[]args){
        Box2[] ar = new Box2[5];
        ar[0] = new Box2(101,"Coffee");
        ar[1] = new Box2(202,"Computer");
        ar[2] = new Box2(303,"Apple");
        ar[3] = new Box2(404,"Dress");
        ar[4] = new Box2(505,"Fairy-tale book");

        // 배열에서 번호가 505인 Box를 찾아 그 내용물을 출력하는 반복문
        for(Box2 e: ar){
            if(e.getBoxNum() == 505)
                System.out.println(e);
        }
    }
}

 

출력 결과

Fairy-tale book

이렇게 배열에 ‘인스턴스 참조 값’을 대상으로 한 배열에도 enhanced for문을 사용할 수 있습니다.

 

다차원 배열


❓ 다차원 배열이란?

 🔥 배열의 구조가 2차원 이상의 형태를 보이는 배열을 가리켜 다차원 배열이라고 합니다.

 

2차원 배열의 생성과 접근

  • 1차원 배열은 둘 이상의 변수가 ‘선의 형태’로 존재하는 배열입니다.
  • 반면 2차원 배열은 다수의 변수가 ‘면의 형태’로 존재하는 배열입니다.

 

보다 쉬운 이해를 위해 아래의 그림을 살펴봅시다.

1차원 배열

2차원 배열

2차원 배열의 생성

int[][] array = new int [3][4]; //세로의 길이가 3, 가로의 길이가 4인 2차원 배열의 생성
  • int[ ] [ ]은 2차원 배열의 참조변수 형을 의미합니다.
  • new int[3][4]에서 2차원 배열의 세로 길이는 3을, 가로 길이는 4임을 의미합니다.

 

2차원 배열의 생성의 코드를 몇 개 더 살펴봅시다.

int[][] array1 = new int [7][2]; //세로의 길이가 7, 가로의 길이가 2인 int형 2차원 배열의 생성
double[][] array2 = new double[3][5]; //세로의 길이가 3, 가로의 길이가 5인 double형 2차원 배열의 생성
String[][] array3 = new String[3][7]//세로의 길이가 3, 가로의 길이가 7인 String형 2차원 배열의 생성

 

다음의 코드를 통해 2차원 배열을 살펴봅시다.

public class TwoDimenArray {
    public static void main(String[]args){
        int[][] arr = new int[3][4];//세로의 길이가 3, 가로의 길이가 4인 2차원 배열의 생성
        int num = 1;

        //배열에 값을 저장
        for(int i = 0; i<3; i++){
            for(int j = 0; j<4; j++){
                arr[i][j] = num;
                num++;
            }
        }

        //배열에 저장된 값을 출력
        for(int i = 0; i<3; i++){
            for(int j = 0;j <4; j ++){
                System.out.print(arr[i][j] + "\\t");
            }
            System.out.println();
        }
    }
}

 

출력 결과

1	2	3	4	
5	6	7	8	
9	10 11	12

 

2차원 배열의 구조

  • 이번에는 2차원 배열의 구조를 좀 더 자세하게 뜯어봅시다.

아래의 코드를 통해 2차원 배열을 살펴봅시다.

public class TwoDimenArray2 {
    public static void main(String[]args){
        int[][] arr = new int[3][4]; //세로가 3, 가로가 4인 2차원 배열의 생성
        int num = 1;

        for(int i = 0; i< arr.length; i++) {
            for (int j = 0; j < arr[i].length;j++){
                arr[i][j] = num;
                num++;
            }
        }

        for(int i = 0; i< arr.length;i++){
            for(int j = 0;j<arr[i].length;j++){
                System.out.print(arr[i][j] + "\\t");
            }
            System.out.println();
        }
    }
}

 

출력 결과

1	2	3	4	
5	6	7	8	
9	10 11 12

 

분석

위의 코드를 뜯어서 분석해 봅시다.

  • 위의 코드에서 2차원 배열을 생성하였습니다.
int[][] arr = new int[3][4];

 

  • 이때 참조 변수 arr의 실제 형태는 다음과 같습니다.
    (세로로 되어 있으나 1차원 배열의 형태를 띄고 있습니다.)

 

  • 배열의 요소는 arr[0],arr[1],arr[2]이고 이 셋 모두 다 참조 변수입니다.
    (그러나 그냥 참조 변수가 아닌 ‘1차원 배열을 참조하는 참조변수’입니다)
  • 이들 참조 변수는 각각 길이가 4인 1차원 배열을 다음과 같이 참조합니다.

 

  • 따라서 arr[0].length, arr[1].length,arr[2].lengtyh로 각 참조변수가 참조하는 배열의 길이를 확인할 수 있습니다.

 

정리

 🔥 2차원 배열은 다수의 1차원 배열들이 묶여서 만들어집니다.

 

위와 같은 구조를 알고 잇음으로 보다 다양한 코드를 사용할 수 있습니다.

public static void main(String[] args){
		int[][] arr = new int[3][4]; //세로의 길이가 3,가로의 길이가 4인 int형 2차원 배열을 생성
		....
		arr[1] = new int [7]; //두번째 줄의 배열을 교체
}

 

따라서 2차원 배열은 다음과 같은 모습으로 변경됩니다.

 

2차원 배열의 초기화

2차원 배열도 1차원 배열처럼 초기화가 가능합니다.

방법1

int[][] arr = new int[][]{
		{11,22,33}, //1행 초기화
		{44,55,66}, //2행 초기화
		{77,88,99}  //3행 초기화
};

방법2

int[][] arr = {
		{11,22,33}, //1행 초기화
		{44,55,66}, //2행 초기화
		{77,88,99}  //3행 초기화

};

 

❓ 그럼 다음과 같이 2차원 배열을 초기화하면 어떤 배열이 만들어질까요?

int[][] arr = {
		{11},
		{22,33}, 
		{44,55,66} 
};

 

코드를 통해 살펴봅시다.

public class PartiallyFilledArray {
    public static void main(String[]args){
        int[][] arr = {
                {11},{22,33},{44,55,66}
        };

        //배열의 구조대로 내용 출력
        for(int i = 0; i<arr.length;i++){
            for(int j = 0;j<arr[i].length;j++){
                System.out.print(arr[i][j] + "\\t");
            }
            System.out.println();
        }
    }
}

 

출력 결과

11	
22	33	
44	55	66

 

정리

 🔥 “초기화 하는 값의 수”에 따른 길이의 배열이 생성됩니다.
  • 2차원 배열의 가로 길이가 행 별로 다른 2차원 배열이 생성됩니다.
  • 따라서 초기화할 때는 잘못하여 원치 않는 길이의 배열이 만들어지지 않도록 주의해야 합니다.

 

📒 Reference (참고 자료)


  1. 윤성우의 열혈 자바

 

profile

제이제이

@아사비치즈스틱

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!