Programming Language/자바(JAVA)

Do it! 자바 프로그래밍 입문 / 7장 배열과 ArrayList

토자맨 2022. 12. 31. 11:13

7.1 배열이란?

배열에 대해 알고 있으니 간단하게 문법만 정리하겠다.

배열 선언 방법

자료형[] 배열 이름 = new 자료형[배열 크기];  
자료형 배열 이름[] = new 자료형[배열 크기];

int[] tmp = new int[5];

// 선언과 동시에 초기화하는 경우 
int[] tmp = new int[] {1,2,3,4,5]; // 크기를 설정해줘도 되고
int[] tmp = new int[5] {1,2,3,4,5}; // 설정 안해줘도 됨
int[] tmp = {1,2,3,4,5}; // new int[] 부분을 생략해도 됨

// 선언 먼저 한 후 나중에 초기화하는 경우
int[] tmp;
tmp = new int[5]; // new int[] 부분이 필수

배열 길이 나타내는 속성

배열 이름.length
int[] tmp = new int[5];
int length = tmp.length; // length == 5

객체 배열

클래스 이름[] tmp = new 클래스 이름[배열 크기];
Poeple[] tmp = new Poeple[5];
System.out.println(tmp[i]); // null 출력

위와 같이 선언만 하는 경우
생성자를 이용해서 인스턴스를 생성하는 경우 인스턴스 변수는 힙에 저장된 클래스 변수가 있는 공간의 주소를 갖게 된다.(힙의 특정 공간을 가리킴)
생성자를 이용해서 힙의 공간을 생성하지 않고 객체 배열을 선언하는 경우엔 힙의 주소를 저장할 수 있는 객체 배열만 생성되는 것이다.
따라서, 객체 배열 공간에 생성자를 이용해서 힙의 주소를 넣어줘야 한다.

클래스 이름[] tmp = new 클래스 이름[배열 크기];
Poeple[] tmp = new Poeple[5];

for (int i = 0; i < tmp.length; i++)
{
    tmp[i] = new Poeple();
    System.out.println(tmp[i]); // tmp[i]의 주소값 출력
 }

배열 복사하기

System.arraycopy(복사할 배열, 복사할 첫 위치, 붙여넣을 배열, 붙여넣을 첫 위치, 복사할 요소 개수);

public class ArrayCopy {

    public static void main(String[] args) {

        int[] array1 = {10 ,20, 30, 40, 50};
        int[] array2 = {1, 2, 3, 4, 5};

        System.arraycopy(array1, 0, array2, 1, 4); // array1의 0~3자리 요소를 복사해서 array2의 1~4자리에 붙여넣기

        for(int i=0; i<array2.length; i++){
            System.out.println(array2[i]); // 1, 10, 20, 30, 40 출력
        }
    }
}

객체 배열 복사하기

1. 얕은 복사

객체 배열을 System.arraycopy를 이용해서 복사할 경우 힙의 주소가 복사돼서 붙여넣기 된다.
따라서, 한 저장 공간을 두 객체 배열이 공유하게 되므로 한 객체 배열을 수정하면 다른 객체 배열도 같이 수정된다. 같은 공간을 가리키고 있으므로

public class ObjectCopy2 {
    public static void main(String[] args) {
        Book[] bookArray1 = new Book[3];
        Book[] bookArray2 = new Book[3];

        bookArray1[0] = new Book("태백산맥", "조정래");
        bookArray1[1] = new Book("데미안", "헤르만 헤세");
        bookArray1[2] = new Book("어떻게 살 것인가", "유시민");
         System.arraycopy(bookArray1, 0, bookArray2, 0, 3);

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

        bookArray1[0].setBookName("나목");
        bookArray1[0].setAuthor("박완서");

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

        System.out.println("=== bookArray2 ===");
        for(int i=0; i<bookArray2.length; i++){
            bookArray2[i].showBookInfo();
        }
    }
}
2. 깊은 복사

객체 배열을 공유하지 않고 각자 따로따로 공간을 갖길 원하면 아래처럼 직접 객체 배열 공간에 하나하나 복사해줘야한다.
System.arraycopy을 사용하면 얕은 복사가 되므로 깊은 복사를 원할 떈 아래처럼 작성

public class ObjectCopy3 {

    public static void main(String[] args) {
        Book[] bookArray1 = new Book[3];
        Book[] bookArray2 = new Book[3];

        bookArray1[0] = new Book("태백산맥", "조정래");
        bookArray1[1] = new Book("데미안", "헤르만 헤세");
        bookArray1[2] = new Book("어떻게 살 것인가", "유시민");

        bookArray2[0] = new Book(); //객체 직접 생성
        bookArray2[1] = new Book();
        bookArray2[2] = new Book();

        for(int i=0; i<bookArray1.length; i++){   // 각각의 요소를 복사
            bookArray2[i].setBookName(bookArray1[i].getBookName());
            bookArray2[i].setAuthor(bookArray1[i].getAuthor());
        }

        for(int i=0; i<bookArray2.length; i++){  //복사된 내용 확인
            bookArray2[i].showBookInfo();
        }

        bookArray1[0].setBookName("나목");   //bookArray1 의 내용 수정
        bookArray1[0].setAuthor("박완서");

        System.out.println("=== bookArray1 ===");    //bookArray1 출력
        for(int i=0; i<bookArray1.length; i++){
            bookArray1[i].showBookInfo();
        }

        System.out.println("=== bookArray2 ===");    //bookArray2 출력
        for(int i=0; i<bookArray2.length; i++){
            bookArray2[i].showBookInfo();   // bookArray1 과 다른 내용으로 출력됨
        }
    }
}

향상된 for문(배열을 위한 for문 변형)

for (변수 : 배열)
초기화와 종료 조건이 없어서 배열의 처음부터 끝까지 전부 실행한다.

public class EnhancedForLoop {

    public static void main(String[] args) {

        String[] strArray = {"Java", "Android", "C", "JavaScript", "Python"};

        for(String lang : strArray
        {
            System.out.println(lang);
        }
    }
}

7.2 다차원 배열

개념은 알고 있으니 넘어가고 문법만

자료형[][] 배열 이름 = new 자료형[행 개수][열 개수]

public class TowDimension {

    public static void main(String[] args) {

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

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

7.3 ArrayList 클래스 사용하기

일반 배열과 차이점 : ArrayList를 선언할 때 배열 크기를 지정하지 않고 필요할 때 add 메소드로 생성할 수 있다.

ArrayList<자료형> 배열 이름 = new 배열 이름<자료형>()

ArrayList 주요 메소드(E == 제너릭 자료형(일단은 그냥 자료형이라 생각하면 됨))

boolean add(E e) 배열에 요소 하나 추가
int size() 배열 요소의 개수 반환
E get(int index) 배열 index 위치에 있는 값 반환
E remove(int index) 배열 index 위치에 있는 요소 값 제거하고 반환
boolean isEmpty() 배열 비어 있으면 -> true / 비어 있지X -> false

 

public class ArrayListTest {

    public static void main(String[] args) {

        ArrayList<Book> library = new ArrayList<Book>();

        // add 메소드로 library 배열에 요소를 추가
        library.add( new Book("태백산맥", "조정래") );
        library.add( new Book("데미안", "헤르만 헤세") );
        library.add( new Book("어떻게 살 것인가", "유시민") );
        library.add( new Book("토지", "박경리") );
        library.add( new Book("어린왕자", "생텍쥐페리") );

        for(int i=0; i<library.size(); i++){

            // get 메소드를 이용해요 library의 i번째 index에 있는 요소의 값을 반환
            Book book = library.get(i);
            book.showBookInfo();
        }

        System.out.println();
        System.out.println("=== 향상된 for문 사용 ===");
        for(Book book : library){
            book.showBookInfo();
        }
    }
}

7.4 배열 응용 프로그램

앞에서 배운 내용 활용하는 부분이다. -> 생략