yooniiverse
개발 블로그
yooniiverse
전체 방문자
오늘
어제
  • 분류 전체보기
    • 운영체제
    • 네트워크
    • ~2023.02
      • 외부교육
      • 대외활동
      • 스터디
      • 동아리
      • TIL
      • IT지식
      • 기타
      • 트러블 슈팅
      • 프로그래밍
      • Python
      • Java
      • JS
      • DB(SQL)
      • JSP
      • Spring
      • 기술면접
      • 자바
      • 코딩테스트
      • 자료구조
      • 알고리즘
      • 백준 문제풀이
      • 인공지능
      • 머신러닝
      • 프로젝트
      • 안드로이드 앱개발
      • 웹개발
      • 웹 서비스
      • 웹퍼블리싱
      • Node.js 백엔드 개발
      • CS
      • 1일 1CS지식
      • 운영체제
      • 네트워크
      • 데이터베이스
      • 정보처리기사
      • 도서 리뷰
      • 개발 관련 도서
      • 기타 도서

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
yooniiverse

개발 블로그

자바 기초 _ [토픽1] 자바 왕기초 _ 배열
~2023.02/Java

자바 기초 _ [토픽1] 자바 왕기초 _ 배열

2021. 12. 29. 21:49
배열 정리

배열을 쓰면 변수 하나에 값을 여러 개 담을 수 있다. 자바의 배열을 만들고 사용하는 방법을 간단하게 살펴보자.

배열 생성

더보기

배열을 만드는 방법은 몇 가지가 있다.

(1) 선언과 동시에 빈 배열 생성

int[] intArray = new int[5]; // 크기 5의 빈 배열

(2) 선언 후, 배열 생성

int[] intArray;
intArray = new int[5]; // 크기 5의 빈 배열

위 두 개는 사실 거의 똑같다고 볼 수 있다.

(3) 리터럴로 생성

int[] intArray = {1, 2, 3, 4, 5};

이렇게 하면 5개의 원소가 있으니까 intArray는 자동으로 크기 5의 배열이 된다.

그런데 이 방식은 변수를 정의할 때만 할 수 있다. 밑에 코드처럼 두 줄에 나누어서 하면 오류가 나온다.

int[] intArray;
intArray = {1, 2, 3, 4, 5}; // 오류

배열 사용

더보기

이제 배열을 사용하는 방법을 보자. 먼저 값을 대입하는 방법을 보도록 하겠다.

intArray[0] = 1;
intArray[1] = 2;
intArray[2] = 3;
intArray[3] = 4;
intArray[4] = 5;

이렇게 하면 0번 인덱스에는 정수 1을 넣어주고, 1번 인덱스에는 정수 2를 넣어주고, 이런 식으로 intArray 배열을 채우게 된다. 여기서 중요한 점: 인덱스는 0부터 시작한다! 5칸 짜리 배열이라면 인덱스가 0부터 4까지이다.

아래와 같이 범위에서 벗어나면

intArray[5] = 6;

런타임에 이런 에러가 나온다:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5

그러니 배열을 사용할 때에는 인덱스를 조심히 다루어야겠다.

런타임?
런타임이란, 코드 작성 시점이 아니라 실제 실행될 때를 뜻한다. intArray[5] = 6; 을 적었을 때는 오류가 없다. 문법적으로 오류가 없기 때문이다. 그런데 실제 실행을 해서 접근하려고 하면 문제가 생기는 것이다. 강의 후반부에 예외처리를 배울 때 '컴파일 시점', '런타임 시점' 등에 대한 이야기를 더 깊게 나눠 보자.

변수명 뒤에 인덱스가 들어간다는 것 말고는 일반적인 변수와 사용법이 같다.

값을 대입할 때는 아까처럼:

intArray[0] = 1;
intArray[1] = 2;

값을 읽을 때는:

System.out.println(intArray[0] + intArray[1]); // 1 + 2
3

이렇게 사용할 수 있겠다.

앨리어싱(Aliasing)

더보기

이렇게 배열을 통째로 넘길 수도 있는데,

int[] arr1 = {1, 2, 3, 4, 5};
int[] arr2 = arr1;

아래 코드의 출력값은 뭘까?

arr1[0] = 100;
System.out.println(arr2[0]);
100

100이다. arr1을 arr2에 지정해줬을 때, 두 변수는 같은 주소를 가리키게 된다. 사실 arr1과 arr2는 아예 똑같은 값인 것이다. arr2를 arr1의 'Alias(가명)'이라고 할 수 있다.

그럼 만약 arr1을 arr2에 새롭게 복사하고 싶으면 어떻게 해야할까?

int[] arr1 = {1, 2, 3, 4, 5};
int[] arr2 = arr1.clone();

arr1[0] = 100;
System.out.println(arr1[0]);
System.out.println(arr2[0]);
100
1

이렇게 clone 라는 메소드를 사용하면 된다. 메소드의 사용은 나중에 천천히 배울테니 문법적인 어려움이 있어도 걱정하지 말고, '이런게 있구나' 정도만 확인하면 된다.

이렇게 배열이 복사가 된 것이라, arr1과 arr2는 서로 다른 배열이다. 그래서 arr1[0]을 수정해도 arr2[0]에는 영향을 미치지 않고, 1이 출력된다!

예제 1

더보기

100개 짜리 배열을 만들고 첫 번째 칸은 1, 두 번째 칸은 2, ..., 마지막 칸은 100으로 채워보자.

int[] intArray = new int[100];
for (int i = 0; i < 100; i++) {
    intArray[i] = i + 1;
}

여기서 코드를 더 직관적으로 바꾸려면 100 대신 intArray.length를 쓰면 된다. length를 쓰면 우리가 배열의 크기를 몰라도 사용할 수 있고, 코드를 읽는 입장에서도 의미를 쉽게 해석할 수 있어서 좋다.

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

위에서 만든 배열에 값이 제대로 들어갔는지 확인해 보자.

for (int i = 0; i < intArray.length; i++) {
    System.out.println(intArray[i]);
}
1
2
3
4
...
99
100

배열이 아닌 일반 변수를 읽는 것과 거의 똑같다.

for-each

더보기

자바에는 'for-each'라는 문법이 있다. (파이썬에도 있었다.) 자바에서 for-each를 쓰는 방법이다.:

for (int i : intArray) {
    System.out.println(i);
}

이렇게 쓰면, 처음에 수행 부분으로 들어갈 때 i는 intArray의 0번 인덱스의 값(원소)을 갖게 되고, 그 다음 들어갈 때는 1번 인덱스의 값(원소)을 갖게 되고... 이런 식으로 배열의 마지막 값(원소)까지 갖게 된다. 직접 확인해보자.

for (double i : intArray) {
    System.out.println(i);
}

'형 변환' 강의에서 봤듯이, double에 int 값을 넣으면 자동으로 형 변환이 되기 때문에 위의 식처럼 써도 문제 없다.

예제 2

더보기

문자열을 담는 fruitsArray을 만든 후, 원소를 저장하고, for - each문을 활용하여 원소들을 출력해주었다.

String[] = fruitsArray = new String[5];

fruitsArray[0] = "딸기";
fruitsArray[1] = "당근";
fruitsArray[2] = "수박";
fruitsArray[3] = "참외";
fruitsArray[4] = "메론";

for (String fruit : fruitsArray) {
    System.out.println(fruit);
}
딸기
당근
수박
참외
메론

실습과제: 배열 연습

(1) 크기가 30인 정수형 배열 intArray를 만들어라.

(2) 배열의 첫 번째(0번 인덱스) 칸부터 1001, 1002, 1003, ..., 1029, 1030을 순서대로 넣어라.

(3) 크기가 4인 문자열형 배열 remainders를 만들어 "Zero", "One", "Two", "Three"를 순서대로 넣어라.

(4) intArray 배열에 담긴 각 값을 4로 나눈 나머지를 인덱스로 생각하고, remainders 배열에서 그 인덱스에 위치한 단어를 출력해라. 이 때 반드시 '배열 정리' 노트에 있는, for- each문을 활용해라.

아래와 같은 출력 결과가 나올 것이다.

One
Two
Three
Zero
...
One
Two
더보기
public class Main {
    public static void main(String[] args) {
        // 여기에 코드를 작성하세요.
        int[] intArray = new int[30];
        
        for (int i = 0; i < intArray.length; i++) {
            intArray[i] = 1000 + (i+1);
        }
        
        String[] remainders = {"Zero", "One", "Two", "Three"};
        
        for (int i : intArray) {
            System.out.println(remainders[i % 4]);
        }
    }
}

실습과제: DNA 염기 서열 분석

DNA 염기 서열은 생물의 유전 성질을 결정하는 매우 중요한 역할을 가지고 있다. 템플릿에 주어진 염기 서열에서 TAGG, CCAG, AGCC가 총 몇 번 등장하는지 세어보자.

만약 TAGG가 2번, CCAG가 4번, AGCC가 3번 등장한다면 아래와 같은 출력 값이 나온다:

TAGG: 2
CCAG: 4
AGCC: 3

힌트

문자열의 toCharArray() 메소드(함수)를 사용하면 char[] 배열을 얻을 수 있다.

char[] sequence = "abc".toCharArray();

반대로 char[] 배열을 문자열로 바꾸려면 이렇게 하면 된다:

String stringFromCharArr = new String(charArr);
TAGG: 1
CCAG: 12
AGCC: 15
더보기
public class Main {
    public static void main(String[] args) {
        String dna = "GATCCGCCCGCCTCGGCCTCCCAAAGTGCTGGGATTACAGGTGTGAGCCA"
                + "CCACGCCCGGCTAATTTTTATTTATTTATTTAAAGACAGAGTCTCACTCT"
                + "GTCACTCAGGCTAGAGTGCAGTGGCACCATCTCAGCTCACTGCAGCCTTG"
                + "ACCTCCCTGGGCTCCGGTGATTTCACCCTCCCAAGTAGCTAGGACTACAG"
                + "GCACATGCCACGACACCCAGCTAATTTTTTATTTTCTGTGAAGTCAAGGT"
                + "CTTGCTACGTTGCCCATGCTGGTATCAAACCCCTGGGCTCAATCAATCCT"
                + "TCCACCTCAGCCTCCCCAAGTATTGGGGTTACAGGCATGAGCTACCACAC"
                + "TCAGCCCTAGCCTACTTGAAACGTGTTCAGAGCATTTAAGTTACCCTACA"
                + "GTTGGGCAAAGTCATCTAACACAAAGCCCTTTTTATAGTAATAAAATGTT"
                + "GTATATCTCATGTGATTTATTGAATATTGTTACTGAAAGTGAGAAACAGC"
                + "ATGGTTGCATGAAAGGAGGCACAGTCGAGCCAGGCACAGCCTGGGCGCAG"
                + "AGCGAGACTCAAAAAAAGAAAAGGCCAGGCGCACTGGCTCACGCCTGTAA"
                + "TCCCAGCATTTCGGGAGGCTGAGGCGGGTGGATCACCTGAGGTCAGGAGT"
                + "TCAAGACCAGCCTAGCCAACATGGTGAAACCCCGTCTCTACTAAAATACA"
                + "AAAATTAACCGGGCGTGATGGCAGGTGCCTGTAATCCCAGCTACTTGGGA"
                + "GGCTGAGGCAGGAGAATCGCTTGAACCAGGAGGCGGAGGTTGCAGGGAGC"
                + "CAAGATGGCGCCACTGCACTCCAGCCTGGGCGATAGAGTGAGACTCCGTC"
                + "TCAGAAAAAAAAGAAAAGAAACGAGGCACAGTCGCATGCACATGTAGTCC"
                + "CAGTTACTTGAGAGGCTAAGGCAGGAGGATCTCTTGAGCCCAAGAGTTTG"
                + "AGTCCAGCCTGAACAACATAGCAAGACATCATCTCTAAAATTTAAAAAAG"
                + "GGCCGGGCACAGTGGCTCACACCTGTAATCCCAGCACTTTGGGAGGTGGA"
                + "GGTGGGTAGATCACCTGACGTCAGGAGTTGGAAACCAGCCTGGCTAACAT";
        char[] charArray = dna.toCharArray();

        // TAGG, CCAG, AGCC
        int tagg = 0, ccag = 0, agcc = 0;

        char[] current = new char[4];

        for (int i = 0; i < charArray.length - 3; i++) {
            for (int j = 0; j < current.length ; j++) {
                current[j] = charArray[i + j];
            }

            // char[]을 String으로 변환
            // 예: ['a', 'b', 'c', 'd'] => "abcd"
            String seq = new String(current);

            switch (seq) {
                case "TAGG":
                    tagg++;
                    break;
                case "CCAG":
                    ccag++;
                    break;
                case "AGCC":
                    agcc++;
                    break;
            }
        }

        // 테스트
        System.out.println("TAGG: " + tagg);
        System.out.println("CCAG: " + ccag);
        System.out.println("AGCC: " + agcc);
    }
}
TAGG: 1
CCAG: 12
AGCC: 15

 

다중 배열
더보기

동일한 자료형 여러 개를 묶어 사용하기 위해 배열을 사용한다.

int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

위의 배열은 정수 자료를 아래처럼 보관하고 있다.

1 2 3 4 5 6 7 8 9 10

혹은 세로로 볼 수도 있다.

1
2
3
4
5
6
7
8
9
10

다중 배열

그렇다면 2차원 구조는 배열로 어떻게 나타낼 수 있을까?

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

'다중 배열'을 선언하면 된다.

int[][] multiArray;

위 표의 내용으로 초기값을 바로 설정하기 위해서는 이렇게 써야 한다.

int[][] multiArray = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
};

'int[4] 배열 세 개가 묶인 배열'이라고 볼 수 있다. 즉, multiArray[0]의 자료형은 int[4]이고 내용은 {1, 2, 3, 4}인 것이다.

생성

위에서는 배열의 초기값을 바로 설정해주었는데, 만약 선언과 생성만 하기 위해서는 어떻게 해야 할까?

3x4 사이즈의 빈 배열을 만들어보자.

int[][] multiArray = new int[3][4];

각 대괄호 사이에 사이즈를 넣어준다. 일반적으로 '행(줄)'을 첫 번째 대괄호에, '열(칸)'을 두 번째 대괄호에 넣는다.

사용

앞서 보았듯, multiArray[0]은 이제 int[4]의 자료형을 갖게 된다. 마찬가지로 multiArray[1], multiArray[2] 모두 int[4]의 자료형을 갖게 된다. 그렇기 때문에 multiArray[0]을 일반적인 배열 탐색법으로 탐색할 수 있다.

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

마찬가지 방법으로 위의 표 내용처럼 multiArray를 이렇게 채울 수 있다.

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

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

for (int i = 0; i < multiArray[2].length; i++) {
    multiarray[2][i] = 9 + i;
}

중첩 반복문(Nested Loops)

하지만 위의 방법도 너무 반복적이다. 중첩 반복문을 사용하면 깔끔하게 쓸 수 있다.

for (int i = 0; i < multiArray.length; i++) {
    for (int j = 0; j < multiArray[i].length; j++) {
        multiArray[i][j] = (i * 4 + 1) + j;
    }
}

여기서 multiArray.length는 전체 자리 수 12가 아닌, 행(줄)의 수인 3이다.

'~2023.02 > Java' 카테고리의 다른 글

자바 기초 _ [토픽2] 자바 객체 지향 프로그래밍 _ 객체 설계하기  (0) 2021.12.30
자바 기초 _ [토픽2] 자바 객체 지향 프로그래밍 _ 객체 만들기  (0) 2021.12.29
자바 기초 _ [토픽1] 자바 왕기초 _ 조건문과 반복문  (0) 2021.12.29
자바 기초 _ [토픽1] 자바 왕기초 _ 변수와 연산  (0) 2021.12.26
자바 기초 _ [토픽1] 자바 왕기초 _ Hello, Java!  (0) 2021.12.25
    '~2023.02/Java' 카테고리의 다른 글
    • 자바 기초 _ [토픽2] 자바 객체 지향 프로그래밍 _ 객체 설계하기
    • 자바 기초 _ [토픽2] 자바 객체 지향 프로그래밍 _ 객체 만들기
    • 자바 기초 _ [토픽1] 자바 왕기초 _ 조건문과 반복문
    • 자바 기초 _ [토픽1] 자바 왕기초 _ 변수와 연산
    yooniiverse
    yooniiverse

    티스토리툴바