배열(Array)과 리스트(List), ArrayList와 Linked List

2024. 11. 5. 09:18·Computer Science/Data Structure
반응형

배열(Array)

배열은 동일한 데이터 타입의 요소들이 연속된 메모리 공간에 저장된 자료 구조이다.

특징 : 

  • 배열 선언 시 크기가 고정된다.
  • 한번 결정된 크기는 변경할 수 없다.
  • 인덱스를 사용하여 요소에 빠르게 접근할 수 있으며, 인덱스는 0부터 시작한다.
  • 배열 안의 모든 요소가 동일한 데이터 타입을 가진다.
  • 연속된 메모리 공간에 할당 된다.

 

Java에서 배열 다루기

// 배열 만들기
int[] arr1;

// 배열 만들면서 크기 지정
int[] arr2 = new int[5];

// 배열 만들면서 크기+값 지정
int[] arr3 = {1, 2, 3, 4, 5};

// arr3 배열에서 index 0인 요소에 접근
System.out.println(arr3[0]); // 1

 

 

 

Java의 Arrays 클래스
Java에서 배열 자체에는 메서드가 없지만, 배열을 다룰 때 Arrays 클래스가 유용한 메서드들을 제공한다.
import java.util.Arrays;

int[] array = {5, 2, 8, 1, 3};

// 배열을 문자열로 출력
System.out.println(Arrays.toString(array)); // [5, 2, 8, 1, 3]

// 배열 정렬
Arrays.sort(array);
System.out.println(Arrays.toString(array)); // [1, 2, 3, 5, 8]

// 배열 복사
int[] newArray = Arrays.copyOf(array, array.length);
System.out.println(Arrays.toString(newArray)); // [1, 2, 3, 5, 8]

// 배열의 특정 값으로 채우기
Arrays.fill(array, 10);
System.out.println(Arrays.toString(array)); // [10, 10, 10, 10, 10]

// 배열 이진 탐색 (정렬된 배열에서만 사용 가능)
int index = Arrays.binarySearch(newArray, 5);
System.out.println(index); // 3

 

 

 

리스트(List)

리스트는 요소의 데이터 제한이 없고, 크기가 가변적인 자료구조이다.

특징 : 

  • 가변 크기이다. 필요에 따라 크기를 늘리거나 줄일 수 있다.
  • 다양한 데이터 타입의 요소들을 포함할 수 있다.
  • (Linked List의 경우) 비연속적 메모리 공간에 할당될 수 있다.
  • 배열과 비교했을 때 삽입, 삭제 등의 연산이 배열보다 유연하게 수행될 수 있다.

Java에서 List 인터페이스를 통해 ArrayList, LinkedList 등의 여러 구현체를 만들 수 있다.

이 둘의 공통적 특징은 요소의 순서를 유지하고, 중복을 허용한다는 점이다.

 

❗️ Python 에서는 리스트 타입이 배열 기능을 제공한다.

 

 

 

ArrayList

ArrayList는 가변 크기의 배열 기반 리스트이다.

특징 : 

  • 초기 용량을 지정할 수도 있고, 필요에 따라 크기를 자동으로 증감할 수 있다. 즉 크기가 동적이다.
  • 요소의 추가, 삭제, 검색, 순회 등의 작업을 효율적으로 수행할 수 있다.
  • 배열과 마찬가지로 인덱스를 사용해 요소에 접근한다. 즉, 빠른 접근이 가능하다.
  • 배열과 마찬가지로 연속된 메모리 공간에 할당된다.

 

Java에서 ArrayList 다루기

import java.util.ArrayList;

public class ArrayListExample {
    public static void main(String[] args) {
    	// ArrayList 생성
        ArrayList<String> fruits = new ArrayList<>(); // 기본 생성자 (초기용량 10)
        // 초기 용량을 20으로 정해주고 싶으면 new ArrayList<>(20)으로 해주면 됨.

        // 요소 추가
        fruits.add("Apple"); // 리스트 끝에 추가
        fruits.add("Orange");
        fruits.add(1, "Banana"); // 지정된 index에 요소 삽입

        // 요소 접근
        String fruit = fruits.get(1); // "Banana"

        // 요소 변경
        fruits.set(1, "Pineapple");

        // 요소 제거
        fruits.remove("Apple");

        // 리스트 크기 확인
        int size = fruits.size();

        // 리스트의 모든 요소 출력
        for (String item : fruits) {
            System.out.println("Fruit: " + item);
        }
        
        // 리스트 안에 요소 포함되어 있는지 확인
        fruits.contains("Pineapple"); // true
        
        // 리스트 모든 요소 제거
        fruits.clear();
        
        // 리스트가 비어있는지 확인
        fruits.isEmpty(); // true
        
    }
}

 

 

연속된 메모리 공간을 할당해주는데 어떻게 동적으로 크기 조절을 해주지?

ArrayList는 초기 용량을 초과하여 요소를 추가할 경우 내부적으로 더 큰 배열을 생성하고 기존 배열의 요소를 복사한다. 이 과정이 자동으로 처리되어 개발자는 배열 크기나 복사 작업에 대해 신경 쓸 필요가 없다.

 

ex) 초기 용량 10인 ArrayList에 11번째 요소를 추가할 경우

더 큰 배열을 생성 -> 기존 배열 요소들을 복사함 -> ArrayList의 내부 배열 참조를 새로운 배열로 변경

 

 

 

 

LinkedList

List, Deque, Queue 인터페이스를 구현하여 다양한 방식으로 사용될수 있다.

특징 :

  • 각 요소(Node)는 자신과 뒤의 요소를 가리키는 참조(포인터)를 가지고 있다.
  • 요소 삽입과 삭제가 배열이나 ArrayList보다 효율적이다. 노드 참조만 변경해주면 된다.
  • 반면 요소 접근은 비교적 비효율적이다. head 노드부터 순차적으로 찾아야하기 때문에.
  • 메모리 할당이 비연속적이다.

 

Java에서 LinkedList는 앞/뒤 요소를 가리키는 2개의 포인터를 갖고있다.
즉, 이중 연결 리스트(doubly linked list)를 기반으로 한다. 
이를 통해 양방향으로 리스트 순회가 가능하다.

 

 

Java에서 LinkedList 다루기

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();

        // 요소 추가 (리스트 끝에 요소가 추가됨)
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Orange");

        // 첫 번째 위치에 요소 추가
        fruits.addFirst("Strawberry");

        // 마지막 위치에 요소 추가
        fruits.addLast("Watermelon");

        // 요소 접근
        // get(int index): 지정된 위치의 요소를 반환
        String firstFruit = fruits.getFirst(); // 첫번째 요소 반환 : "Strawberry"
        String lastFruit = fruits.getLast(); // 마지막 요소 반환 : "Watermelon"

        // 요소 변경
        fruits.set(2, "Pineapple"); // Index 2의 요소 Banana를 Pineapple로 변경

        // 요소 제거
        // remove(Object o): 지정된 요소를 리스트에서 제거
        // remove(int index): 지정된 위치의 요소를 제거
        fruits.removeFirst(); // 첫 번째 요소 제거
        fruits.removeLast(); // 마지막 요소 제거

        // 리스트 크기 확인
        int size = fruits.size();
        System.out.println("Size of the list: " + size);

        // 리스트의 모든 요소 출력
        for (String item : fruits) {
            System.out.println("Fruit: " + item);
        }
        
        // 리스트 안에 요소 포함되어 있는지 확인
        fruits.contains("Pineapple"); // true
        
        // 리스트 모든 요소 제거
        fruits.clear();
        
        // 리스트가 비어있는지 확인
        fruits.isEmpty(); // true
        
    }
}

 

 

 

Array vs ArrayList vs LinkedList

특성/기능 Array ArrayList LinkedList
기본 구조 고정 크기의 배열 동적 크기의 배열 기반 리스트 연결 리스트
메모리 할당 연속된 메모리 공간 연속된 메모리 공간 비연속적인 메모리 공간
초기 크기 지정 필요 필요 없음(기본 10) 필요 없음
크기 조절 불가능 자동 조절
(새 배열 생성 및 복사)

자동 조절
인덱스를 통한 접근 시간 O(1) O(1) O(n)
삽입/삭제 시간 O(n)
맨 끝은 O(1)
O(n)
맨 끝은 O(1)
O(1)

요소 검색 시간 O(n) O(n) O(n)
메모리 사용량 요소 크기에 비례 요소 크기 + 배열의 여유 공간 요소 크기 + 참조 크기
순차적 데이터 접근 빠름 빠름 느림
임의 데이터 접근 빠름 빠름 느림
적용 예 고정 크기의 데이터, 빈번한 읽기 동적 크기의 데이터, 빈번한 읽기 빈번한 삽입/삭제 작업

 

 

참고
배열은 동일한 데이터 타입, 리스트는 다양한 데이터 타입을 넣을 수 있다고 했지만
Java에서 리스트 뿐만 아니라 배열도 요소 타입을 Object로 선언하면 다양한 타입의 데이터 요소를 넣을 수 있다.
그럼에도, 컬렉션의 리스트는 더 높은 유연성과 타입 안전성을 제공한다. 
(배열은  런타임 타입 오류 가능. 리스트는 제네릭을 통해 컴파일 타임 타입 안전성 제공.)
상황에 따라 적절한 자료 구조를 선택하는 것이 중요하다.
728x90
반응형

'Computer Science > Data Structure' 카테고리의 다른 글

이진탐색트리(Binary Search Tree, BST)  (0) 2024.11.16
트리(tree)  (0) 2024.11.15
해시(Hash) - 특징, 충돌 현상 원인과 해결 기법  (0) 2024.11.11
큐(Queue) - Array와 LinkedList로 구현, 원형큐, 덱/데크(Deque)  (0) 2024.11.07
스택(Stack) - Array와 LinkedList로 구현  (1) 2024.11.07
'Computer Science/Data Structure' 카테고리의 다른 글
  • 트리(tree)
  • 해시(Hash) - 특징, 충돌 현상 원인과 해결 기법
  • 큐(Queue) - Array와 LinkedList로 구현, 원형큐, 덱/데크(Deque)
  • 스택(Stack) - Array와 LinkedList로 구현
settong
settong
    250x250
  • settong
    개 발 자 국
    settong
  • 전체
    오늘
    어제
    • 전체보기 (202)
      • Computer Science (50)
        • Network (7)
        • Operating System (18)
        • Data Structure (9)
        • Database (11)
        • Algorithm (5)
      • Language (17)
        • Java (17)
        • Javascript (0)
        • Python (0)
      • Devops (20)
        • AWS (0)
        • Naver Cloud (16)
        • CICD (3)
        • 웹 서버 관리 (1)
      • Front (0)
        • React (0)
      • Backend (5)
        • Spring (5)
      • 코딩 테스트 정복기 (110)
        • 백준 (51)
        • 프로그래머스 (53)
        • 기타 (6)
      • etc (0)
      • 경제 상식 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    github actions
    완전탐색
    ncp
    Spring Boot
    BFS
    Network
    DFS
    ncp202
    벨만포드
    CI/CD
    다익스트라
    프로그래머스
    ncp200
    백준
    백트래킹
    분할정복
    집합
    lcs
    해시
    다이나믹프로그래밍
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
settong
배열(Array)과 리스트(List), ArrayList와 Linked List
상단으로

티스토리툴바