프로그래밍 언어&프레임워크/java

[Java/자바] 배열과 ArrayList

Coblin 2021. 8. 23. 00:51
반응형

들어가기 전에

본 글은 제가 참여하고 있는 자바 기초 스터디에서 제가 발표한 내용으로 위의 책 Chapter 07 배열과 ArrayList 파트를 정리한 글입니다.


배열이란?

연관된 데이터를 하나의 변수에 담을 수 있는 자료구조

자료형이 같은 여러 데이터를 한번에 관리할 수 있는 자료형

int num1 = 1;
int num2 = 2;
int num3 = 3;
...
int num10 = 10;

int[] array = new int[] {1, 2, 3, ... 10};

1차원 배열

자료구조(Data Structure)란?

원소들이 논리적으로 정의된 규칙에 의해 나열되며 자료에 대한 처리를 효율적으로 수행할 수 있도록 자료를 구분하여 표현한 것이라고 합니다.

자료를 더 효율적으로 저장 및 관리하기 위해 사용

자료구조를 사용하면 실행시간을 단축시켜주거나 메모리 절약 등의 효과를 볼 수 있음

배열의 장단점

장점

  • 구현이 쉽다.
  • 검색 성능이 좋다.
    인덱스(index)를 이용한 무작위 접근이 가능하므로 검색에서 빠른 성능을 기대할 수 있다.
  • 연속된 메모리 공간에 할당하기 때문에 연결 리스트(Linked List)보다 빠른 성능을 보인다.
  • 참조를 위한 추가적인 메모리 할당이 필요 없다.

단점

  • 크기를 변경할 수 없다.
    배열은 생성할 때 지정한 크기를 바꿀 수 없기 때문에 너무 크게 설정하면 메모리가 낭비되고 너무 작게 설정하면 그 이상의 자료를 저장할 수 없음
  • 메모리 재사용이 불가능하다.(메모리 낭비)
    배열은 설정된 사이즈 만큼의 메모리를 할당받아 사용하기 때문에 데이터의 존재 유무와 관계없이 일정한 크기의 메모리를 점유하고 있습니다. 즉 배열 요소를 삭제하더라도 해당 메모리를 재사용할 수 없습니다.
  • 배열 중간에 데이터를 삽입하거나 삭제할때 비효율적이다.

배열 사용방법

선언 및 초기화

배열을 선언하면 선언한 자료형과 배열 길이에 따라 메모리가 할당

자바에서 배열을 선언하면 그와 동시에 각 요소의 값이 초기화

정수: 0

실수: 0.0

객체 배열: null

// 선언
자료형[] 배열이름 = new 자료형[개수]; // 주로 이방법으로 사용
자료형 배열이름[] = new 자료형[개수];

// 선언과 동시에 초기화
자료형[] 배열이름 = new 자료형[] {1, 2, 3};
자료형[] 배열이름 = {1, 2, 3};

// 배열 자료형 선언 후 초기화
int[] array;

array = new int[] {1, 2, 3, 4, 5}; // new int[] 생략 불가

// int요소가 10개인 배열 선언 및 사용
int[] array = new int[10];

array[0] = 1; // 0번째(첫번째) 요소에 1 저장
array[1] = 2; // 1번째(두번째) 요소에 2 저장

/*
 * array 출력시 0, 1번째를 제외한 2~9번째는 기본값인 0출력
 * 1
 * 2
 * 0
 * 0
 * ...
 * 0
 */

배열 복사

이미 존재하는 배열을 자료형 및 배열 크기가 같은 배열을 새로 만들거나 더 큰 배열을 만들어 기존 배열에 저장된 자료를 가져오려 할 때 배열 복사를 사용

System.arraycopy(src, srcPos, dest, destPos, length);
/*
 * src: 복사할 배열
 * srcPos: 복사할 첫 위치
 * dest: 대상 배열
 * destPos: 붙여 넣을 첫 위치
 * length: 복사할 요소 개수
 */

// 10개의 공간을 가진 배열을 선언하고 5번째부터 5개의 요소를 복사
int[] array = new int[] {1, 2, 3, 4, 5};

int[] array2 = new int[10];
int[] array3 = array.clone();
int[] array4 = Arrays.copyOf(array, array.length);
int[] array5 = Arrays.copyOfRange(array, 0, 5);

System.arraycopy(array, 0, array2, 5, 5);

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

/*
 * array2 출력시 0~4번째는 기본값인 0출력
 * 0
 * 0
 * 0
 * 0
 * 0
 * 1
 * 2
 * 3
 * 4
 * 5
 */

객체 배열 복사

객체 배열의 경우 배열 안에 인스턴스 자체가 아닌 인스턴스의 주소값을 가리키고 있기 때문에 원본 배열의 값을 변경하면 복사된 배열의 값도 변경

  • 얕은 복사
Book[] bookArray1 = new Book[3];
bookArray1[0] = new Book("객체지향의 사실과 오해", "조영호");
bookArray1[1] = new Book("자바 ORM 표준 JPA 프로그래밍", "김영한");
bookArray1[2] = new Book("Two Scoops of Django", "대니얼 로이 그린펠드");

for(Book book : bookArray1) {
  System.out.println(book);
}

bookArray1[0].setName("name");
bookArray1[0].setAuthor("author");

Book[] bookArray2 = bookArray1.clone();
Book[] bookArray3 = Arrays.copyOf(bookArray1, bookArray1.length);
Book[] bookArray4 = Arrays.copyOfRange(bookArray1, 0, 3);

/*
* bookArray2, bookArray3, bookArray4 출력시 아래와 같이 0번째 요소가 test로 변경
* Book [name=test, author=test]
* Book [name=자바 ORM 표준 JPA 프로그래밍, author=김영한]
* Book [name=Two Scoops of Django, author=대니얼 로이 그린펠드]
*/

 

  • 복사된 배열이나 원본 배열이 변경될 때 서로 간의 값이 같이 변경됩니다.
  • 깊은 복사
Book[] bookArray1 = new Book[3];
bookArray1[0] = new Book("객체지향의 사실과 오해", "조영호");
bookArray1[1] = new Book("자바 ORM 표준 JPA 프로그래밍", "김영한");
bookArray1[2] = new Book("Two Scoops of Django", "대니얼 로이 그린펠드");

for(Book book : bookArray1) {
  System.out.println(book);
}

Book[] bookArray2 = new Book[3];

for(int i=0;i<bookArray1.length;i++) {
  bookArray2[i] = new Book(); // 비어있는 인스턴스 생성
  bookArray2[i].setName(bookArray1[i].getName());
  bookArray2[i].setAuthor(bookArray1[i].getAuthor());
}

bookArray1[0].setName("name");
bookArray1[0].setAuthor("author");

for(Book book : bookArray2) {
  System.out.println(book);
}

  /*
   * bookArray2 출력시 값 변경 없이 출력
   * Book [name=객체지향의 사실과 오해, author=조영호]
   * Book [name=자바 ORM 표준 JPA 프로그래밍, author=김영한]
   * Book [name=Two Scoops of Django, author=대니얼 로이 그린펠드]
   */

 

  • 복사된 배열이나 원본 배열이 변경될 때 서로 간의 값은 바뀌지 않습니다.

다차원 배열

다차원 배열은 평면이나 공간 개념을 구현하는 데 사용합니다.

이차원 배열

바둑, 체스, 네비게이션 지도 등을 구현할 때 사용

2차원 배열

// 선언 및 초기화 방법은 일차원 배열과 동일하나 차원이 늘어날 수록 []가 추가됨
자료형[][] 배열이름 = new 자료형[행 개수][열 개수];

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

// 이차원 배열 출력
for (int i=0;i<array.length;i++) { // array.length 행 길이
    for (int j=0;j<array[i].length;j++) { // array.length 열 길이
        System.out.print(array[i][j] + "\t");
    }
    System.out.println();
}

ArrayList란?

기본 배열의 단점을 보완한 자료 구조

크기가 가변적으로 변함

내부적으로 저장이 가능한 메모리 용량(Capacity)이 있으며 현재 사용 중인 공간의 크기(Size)가 있음

현재 가용량(Capacity) 이상을 저장하려고 할 때 더 큰 메모리 공간을 새롭게 할당

ArrayList 사용방법

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

ArrayList<Integer> array1 = new ArrayList<Integer>();
ArrayList<Integer> array2 = new ArrayList<>(10); // 초기 용량(Capacity) 설정
ArrayList<Integer> array4 = new ArrayList<>(array3); // 다른 Collection값으로 초기화

// ArrayList에 요소 추가
array1.add(1);
array1.add(2);
array1.add(3);
array1.add(4);
array1.add(5);

// ArrayList에 추가된 요소 개수 반환
array1.size(); // 5

// ArrayList의 index 위치에 있는 요소값 반환
array1.get(0); // 1

// ArrayList의 index위치에 있는 요소값 제거후 반환
array1.remove(4); // 5

// ArrayList가 비어있는지 확인
array1.isEmpty(); // false

// ArrayList 안에 값이 존재 하는지 확인
array1.contains("A"); // false
array1.indexOf("Hello") // -1

/*
 * contains는 값이 존재하는 경우 true 없는경우 false 리턴
 * indexOf는 값이 존재하는 경우 해당 인덱스값 없는경우 -1 리턴
 * 두 메소드 모두 대소문자를 구분
 */
반응형