[Java 필수 문법] 4. 배열(Array)과 리스트(List)

2025. 2. 17. 21:15·Java

Java에서 데이터를 저장하는 방법 중 대표적인 두 가지는 배열(Array)과 리스트(List)이다.

배열은 고정된 크기의 연속된 메모리 공간, 리스트는 크기가 동적으로 변할 수 있는 컬렉션이다.

 

1️⃣ 배열(Array)

배열은 같은 타입의 여러 개의 데이터를 저장하는 자료구조다.

 

배열 선언 및 초기화

📌 1차원 배열 선언 및 초기화

// 배열 선언
int[] arr1;       // 일반적인 선언 방식
int arr2[];       // C 스타일의 선언 방식 (비추천)

// 배열 선언 + 크기 지정 (초기값: 0)
int[] arr3 = new int[5]; // [0, 0, 0, 0, 0]

// 배열 선언 + 초기화
int[] arr4 = {1, 2, 3, 4, 5}; // 크기는 자동 설정
int[] arr5 = new int[]{10, 20, 30}; // new int[] 필요 (메서드 내부에서 사용 시)

📌 2차원 배열 선언 및 초기화

// 2차원 배열 선언
int[][] matrix1 = new int[3][4]; // 3행 4열 배열 (초기값: 0)

// 2차원 배열 선언 + 초기화
int[][] matrix2 = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

 

배열의 데이터 추가, 접근, 삭제

📌 요소 접근 및 변경

int[] arr = {10, 20, 30, 40, 50};
System.out.println(arr[2]); // ✅ 30 (0부터 시작)

// 값 변경
arr[1] = 100; // arr = [10, 100, 30, 40, 50]

📌 요소 추가 및 삭제 (배열은 크기 고정 → 추가 및 삭제 개념 없음)

배열의 요소를 삭제하는 방법은 없고, 특정 인덱스를 null이나 기본값으로 설정하는 방식으로 처리한다.

arr[2] = 0; // 해당 위치 값을 0으로 설정 (완전한 삭제는 아님)

 

배열의 크기 확인

System.out.println(arr.length); // ✅ 5

 

배열 요소 출력

📌 1차원 배열 출력

  • Arrays.toString() 활용
import java.util.Arrays;

int[] arr = {10, 20, 30, 40};
System.out.println(Arrays.toString(arr)); 
// 출력: [10, 20, 30, 40]
  • for문
int[] arr = {10, 20, 30, 40};
for (int i = 0; i < arr.length; i++) {
    System.out.print(arr[i] + " ");
} 
// 출력: 10 20 30 40

for (int num : arr) {
    System.out.print(num + " ");
}
// 출력: 10 20 30 40

 

📌 2차원 배열 출력

  • Arrays.deepToString() 활용
import java.util.Arrays;

System.out.println(Arrays.deepToString(matrix2));
  • for문
for (int[] row : matrix2) {
    System.out.println(Arrays.toString(row));
}

 

배열 정렬

📌 오름차순 정렬

1. Arrays.sort() 사용

import java.util.Arrays;

int[] arr = {5, 1, 3, 2, 4};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr)); 
// 출력: [1, 2, 3, 4, 5]

2. Stream API 사용 (Java 8+)

import java.util.Arrays;
import java.util.stream.IntStream;

int[] arr = {5, 3, 8, 1, 2};
arr = Arrays.stream(arr).sorted().toArray();
System.out.println(Arrays.toString(arr));  
// 출력: [1, 2, 3, 5, 8]

3. 람다식 사용 (Java 8+)

import java.util.Arrays;

Integer[] arr = {5, 3, 8, 1, 2};
Arrays.sort(arr, (a, b) -> a - b);
System.out.println(Arrays.toString(arr));  
// 출력: [1, 2, 3, 5, 8]
  • Arrays.sort()를 사용할 때, 람다식 정렬은 Comparator<T>를 활용하는 방식이다. Comparator<T>는 참조 타입에 대해서만 동작하기 때문에 기본 자료형인 int[] 배열은 람다식을 사용할 수 없다.

 

📌 내림차순 정렬

1. Arrays.sort() 사용

import java.util.Arrays;
import java.util.Comparator;

Integer[] arr = {5, 3, 8, 1, 2};
Arrays.sort(arr, Comparator.reverseOrder());
System.out.println(Arrays.toString(arr));  
// 출력: [8, 5, 3, 2, 1]
  • Integer[]로 변환해야 Comparator.reverseOrder()를 사용할 수 있음.

2. Stream API 사용 (Java 8+)

import java.util.Arrays;
import java.util.Comparator;
import java.util.stream.IntStream;

int[] arr = {5, 3, 8, 1, 2};
arr = Arrays.stream(arr)
           .boxed()
           .sorted(Comparator.reverseOrder())
           .mapToInt(Integer::intValue)
           .toArray();
System.out.println(Arrays.toString(arr));  
// 출력: [8, 5, 3, 2, 1]
  • int[]는 Comparator.reverseOrder()를 사용할 수 없으므로 boxed()를 사용해 변환해야 함.

3. 람다식 사용 (Java 8+)

import java.util.Arrays;

Integer[] arr = {5, 3, 8, 1, 2};
Arrays.sort(arr, (a, b) -> b - a);
System.out.println(Arrays.toString(arr));  
// 출력: [8, 5, 3, 2, 1]
  • Arrays.sort()를 사용할 때, 람다식 정렬은 Comparator<T>를 활용하는 방식이다. Comparator<T>는 참조 타입에 대해서만 동작하기 때문에 기본 자료형인 int[] 배열은 람다식을 사용할 수 없다.

 

배열의 유용한 메서드

1. Arrays.copyOf()

배열을 복사할 때 사용한다. 새로운 배열을 만들고, 기존 배열의 일부 또는 전부를 복사할 수 있다.

import java.util.Arrays;

int[] arr = {1, 2, 3, 4, 5};
int[] copiedArr = Arrays.copyOf(arr, 3); // 배열의 처음 3개 요소 복사
System.out.println(Arrays.toString(copiedArr)); 
// 출력: [1, 2, 3]

2. Arrays.fill()

배열을 특정 값으로 채우는 메서드이다.

int[] arr = new int[5];
Arrays.fill(arr, 10);  // 모든 요소를 10으로 채움
System.out.println(Arrays.toString(arr)); 
// 출력: [10, 10, 10, 10, 10]

3. Arrays.equals()

두 배열이 같은지 비교할 때 사용한다.

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

System.out.println(Arrays.equals(arr1, arr2));  // ✅ true
System.out.println(Arrays.equals(arr1, arr3));  // ✅ false

4. Arrays.sort()

배열을 오름차순으로 정렬할 때 사용한다.

int[] arr = {5, 3, 8, 1, 2};
Arrays.sort(arr); 
System.out.println(Arrays.toString(arr)); 
// 출력: [1, 2, 3, 5, 8]

5. Arrays.binarySearch()

배열에서 이진 탐색을 통해 특정 값의 인덱스를 찾을 때 사용한다. 배열은 정렬되어 있어야 한다.

int[] arr = {1, 2, 3, 4, 5};
int index = Arrays.binarySearch(arr, 3);
System.out.println(index);  // 출력: 2 (3은 인덱스 2에 위치)

6. Arrays.deepEquals()

2차원 이상의 배열에 대해 배열의 내용이 동일한지 비교할 때 사용한다.

int[][] arr1 = {{1, 2}, {3, 4}};
int[][] arr2 = {{1, 2}, {3, 4}};
System.out.println(Arrays.deepEquals(arr1, arr2));  // ✅ true

 

배열 사용 시 주의점

  • 크기가 고정됨 → 크기를 변경하려면 새 배열을 만들어야 함.
  • IndexOutOfBoundsException 발생 가능 → 범위를 초과하는 인덱스 접근 주의.
  • 요소 추가 및 삭제 불가 → 추가 및 삭제하려면 List를 사용하는 것이 좋음.

 

2️⃣ 리스트(List)

배열과 달리 크기가 동적으로 변하는 자료구조다.

ArrayList, LinkedList 등 다양한 구현체가 있으며, 가장 많이 쓰이는 것은 ArrayList다.

 

리스트 선언 및 초기화

import java.util.ArrayList;
import java.util.List;

List<Integer> list1 = new ArrayList<>(); // Integer 리스트
List<String> list2 = new ArrayList<>();  // String 리스트

// 리스트 초기화
List<Integer> list3 = new ArrayList<>(List.of(1, 2, 3, 4, 5));

 

리스트 데이터 추가, 접근, 삭제

📌 데이터 추가 (add())

List<Integer> list = new ArrayList<>();
list.add(10); // [10]
list.add(20); // [10, 20]
list.add(1, 15); // [10, 15, 20] (1번 인덱스에 15 삽입)

📌 데이터 접근 (get())

System.out.println(list.get(1)); // ✅ 15

📌 데이터 삭제 (remove())

list.remove(1); // 인덱스 1의 값(15) 삭제 → [10, 20]
list.remove(Integer.valueOf(20)); // 값 20 삭제 → [10]

 

리스트 크기 확인

System.out.println(list.size()); // ✅ 2

 

리스트 요소 출력

  • 기본 출력
System.out.println(list); // 리스트 출력 → [10, 20]
  • String.join() 활용
System.out.println(String.join(", ", list));
  • for문
for (int num : list) {
    System.out.print(num + " ");
}

 

리스트 정렬

📌 오름차순 정렬

1. Collections.sort() 사용

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

List<Integer> list = new ArrayList<>(Arrays.asList(5, 3, 8, 1, 2));
Collections.sort(list);
System.out.println(list);  
// 출력: [1, 2, 3, 5, 8]

2. List.sort() 사용 (Java 8+)

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

List<Integer> list = new ArrayList<>(Arrays.asList(5, 3, 8, 1, 2));
list.sort(Integer::compareTo);
System.out.println(list);  
// 출력: [1, 2, 3, 5, 8]

3. Stream API 사용 (Java 8+)

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

List<Integer> list = new ArrayList<>(Arrays.asList(5, 3, 8, 1, 2));
list = list.stream().sorted().collect(Collectors.toList());
System.out.println(list);  
// 출력: [1, 2, 3, 5, 8]

4. 람다식 사용 (Java 8+)

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

List<Integer> list = new ArrayList<>(Arrays.asList(5, 3, 8, 1, 2));
list.sort((a, b) -> a - b);
System.out.println(list);  
// 출력: [1, 2, 3, 5, 8]

 

📌 내림차순 정렬

1. Collections.sort() 사용

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

List<Integer> list = new ArrayList<>(Arrays.asList(5, 3, 8, 1, 2));
Collections.sort(list, Collections.reverseOrder());
System.out.println(list);  
// 출력: [8, 5, 3, 2, 1]

2. List.sort() 사용 (Java 8+)

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Comparator;

List<Integer> list = new ArrayList<>(Arrays.asList(5, 3, 8, 1, 2));
list.sort(Comparator.reverseOrder());
System.out.println(list);  
// 출력: [8, 5, 3, 2, 1]

3. Stream API 사용 (Java 8+)

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Comparator;
import java.util.stream.Collectors;

List<Integer> list = new ArrayList<>(Arrays.asList(5, 3, 8, 1, 2));
list = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
System.out.println(list);  
// 출력: [8, 5, 3, 2, 1]

4. 람다식 사용 (Java 8+)

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

List<Integer> list = new ArrayList<>(Arrays.asList(5, 3, 8, 1, 2));
list.sort((a, b) -> b - a);
System.out.println(list);  
// 출력: [8, 5, 3, 2, 1]

 

리스트 유용한 메서드

1. add()

리스트에 요소를 추가하는 가장 기본적인 메서드다.

List<Integer> list = new ArrayList<>();
list.add(10); 
list.add(20); 
System.out.println(list); // 출력: [10, 20]

2. addAll()

리스트에 다수의 요소를 한 번에 추가하는 메서드다.

List<Integer> list = new ArrayList<>();
list.addAll(List.of(1, 2, 3, 4));
System.out.println(list); // 출력: [1, 2, 3, 4]

3. remove()

리스트에서 요소를 삭제할 때 사용한다.

List<Integer> list = new ArrayList<>(List.of(10, 20, 30, 40));
list.remove(Integer.valueOf(20));  // 값 20을 삭제
System.out.println(list);  // 출력: [10, 30, 40]

4. set()

리스트에서 특정 인덱스의 값을 수정할 때 사용한다.

List<Integer> list = new ArrayList<>(List.of(1, 2, 3));
list.set(1, 100); // 인덱스 1의 값(2)을 100으로 수정
System.out.println(list);  // 출력: [1, 100, 3]

5. get()

리스트에서 특정 인덱스의 값을 가져올 때 사용한다.

List<Integer> list = new ArrayList<>(List.of(10, 20, 30));
System.out.println(list.get(1));  // 출력: 20

6. contains()

리스트에 특정 값이 포함되어 있는지 확인할 때 사용한다.

List<Integer> list = new ArrayList<>(List.of(1, 2, 3, 4));
System.out.println(list.contains(3));  // ✅ true
System.out.println(list.contains(5));  // ✅ false

7. indexOf()

리스트에서 특정 값의 인덱스를 찾을 때 사용한다.

List<Integer> list = new ArrayList<>(List.of(10, 20, 30, 40));
System.out.println(list.indexOf(30));  // ✅ 2 (인덱스 2)

8. isEmpty()

리스트가 비어있는지 확인할 때 사용한다.

List<Integer> list = new ArrayList<>();
System.out.println(list.isEmpty());  // ✅ true

list.add(1);
System.out.println(list.isEmpty());  // ✅ false

9. clear()

리스트의 모든 요소를 삭제할 때 사용한다.

List<Integer> list = new ArrayList<>(List.of(1, 2, 3));
list.clear();
System.out.println(list);  // 출력: []

10. sort()

리스트의 요소들을 정렬할 때 사용한다.

List<Integer> list = new ArrayList<>(List.of(5, 3, 8, 1));
list.sort(Comparator.naturalOrder());  // 오름차순 정렬
System.out.println(list);  // 출력: [1, 3, 5, 8]

11. reverse()

리스트의 요소 순서를 뒤집을 때 사용한다.

import java.util.Collections;

List<Integer> list = new ArrayList<>(List.of(1, 2, 3));
Collections.reverse(list);
System.out.println(list);  // 출력: [3, 2, 1]

12. subList()

리스트에서 일부분을 잘라낸 서브리스트를 반환한다.

List<Integer> list = new ArrayList<>(List.of(1, 2, 3, 4, 5));
List<Integer> subList = list.subList(1, 4); // 인덱스 1부터 3까지
System.out.println(subList);  // 출력: [2, 3, 4]

 

리스트 사용 시 주의점

  • ArrayList는 배열 기반이므로 중간 삽입/삭제가 느림 → LinkedList를 고려.
  • remove(int index) vs remove(Object obj) 주의 → 값이 Integer인 경우 remove(index)가 호출될 수 있음.
  • NullPointerException 주의 → 리스트가 null이면 메서드 호출 시 예외 발생.

 

3️⃣ 배열과 리스트 정렬

어떤 정렬 방법을 사용해야 할까?

방법 배열(Array) 리스트(List) Java 버전 성능
Arrays.sort() ✅ 가능 ❌ 불가능 Java 1.2+ 빠름 (Dual-Pivot QuickSort)
Arrays.sort() ✅ 가능 ❌ 불가능 Java 1.2+ 빠름 (Dual-Pivot QuickSort)
Arrays.sort() ✅ 가능 ❌ 불가능 Java 1.2+ 빠름 (Dual-Pivot QuickSort)
Arrays.sort() ✅ 가능 ❌ 불가능 Java 1.2+ 빠름 (Dual-Pivot QuickSort)
Arrays.sort() ✅ 가능 ❌ 불가능 Java 1.2+ 빠름 (Dual-Pivot QuickSort)

📌 배열(Array) 정렬

  • 일반적인 정렬 → Arrays.sort()
  • 내림차순 정렬 → Arrays.sort(arr, Comparator.reverseOrder())
  • Stream API 사용 (배열 변환 포함) → Arrays.stream(arr).sorted()

📌 리스트(List) 정렬

  • 일반적인 정렬 → Collections.sort(list)
  • 내림차순 정렬 → Collections.sort(list, Collections.reverseOrder())
  • Java 8 이상이면? → list.sort(Comparator.naturalOrder())
  • Stream API 사용 (메모리 비용 감수 가능하면) → list.stream().sorted()
  • 람다식 사용 → list.sort((a, b) -> a - b)

👉 결론

  • 배열 정렬은 Arrays.sort()를 가장 많이 사용
  • 리스트 정렬은 List.sort()가 가장 직관적
  • Stream API는 일회성 정렬이 필요한 경우 사용 (가독성은 좋지만 성능 저하 가능)
  • 람다식을 활용하면 코드가 더 간결해짐 (Java 8 이상이라면 적극 활용 가능)

 

Comparator.reverseOrder() vs Collections.reverseOrder()

📌 Comparator.reverseOrder()

  • Comparator의 정적 메서드
  • 기본 정렬 순서(오름차순)를 반대로(내림차순) 정렬
  • null을 허용하지 않음 (널 값을 비교하면 NullPointerException 발생)
  • Comparator.naturalOrder()와 함께 사용 가능
  • Java 8부터 사용 가능
import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>(Arrays.asList(5, 3, 8, 1, 2));
        
        list.sort(Comparator.reverseOrder());  // 내림차순 정렬
        System.out.println(list);  
        // 출력: [8, 5, 3, 2, 1]
    }
}

📌 Collections.reverseOrder()

  • Collections의 정적 메서드
  • 기본적으로 Comparable을 구현한 객체들만 정렬 가능
  • null을 허용하며, null이 포함된 경우에도 예외 없이 동작
  • Java 1.2부터 사용 가능 (훨씬 이전부터 존재)
  • 기본 정렬 기준(오름차순)을 반대로(내림차순) 뒤집는 Comparator를 반환
import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>(Arrays.asList(5, 3, 8, 1, 2));
        
        list.sort(Collections.reverseOrder());  // 내림차순 정렬
        System.out.println(list);  
        // 출력: [8, 5, 3, 2, 1]
    }
}

📌 두 메서드의 차이점 비교

구분 Comparator.reverseOrder() Collections.reverseOrder()
정의 위치 Comparator 인터페이스의 정적 메서드 Collections 클래스의 정적 메서드
사용 가능 버전 Java 8 이상 Java 1.2 이상
기본 정렬 기준 기본 정렬 순서(오름차순)를 반대로(내림차순) Comparable을 기준으로 정렬을 반대로(내림차순)
null 허용 여부 ❌ null을 허용하지 않음 (예외 발생) ✅ null을 허용
반환 타입 Comparator<T> Comparator<T>

📌 어떤 걸 써야 할까?

  • Java 8 이상을 사용하고 null이 포함되지 않은 데이터라면? → Comparator.reverseOrder()를 쓰는 게 더 간결하고 직관적!
  • Java 1.2 이상의 모든 버전에서 동작하고, null을 포함한 리스트를 정렬해야 한다면? → Collections.reverseOrder()를 쓰는 게 더 안정적!
저작자표시 (새창열림)
'Java' 카테고리의 다른 글
  • [Java 필수 문법] 6. 입출력
  • [Java 필수 문법] 5. 문자열
  • [Java 필수 문법] 3. Java에서 데이터 비교 (== vs equals())
  • [Java 필수 문법] 2. Primitive Type vs. Reference Type
김행만
김행만
이모저모 다 적기
  • 김행만
    hyeinisfree
    김행만
  • 전체
    오늘
    어제
    • 분류 전체보기 (41)
      • AWS (0)
      • Network (6)
      • CICD (1)
      • Spring (0)
      • Ruby on Rails (0)
      • Java (12)
      • Python (1)
      • Computer Science (6)
        • Algorithm (2)
        • Data Structure (3)
        • Database (0)
        • Design Pattern (1)
      • Solving Algorithm Problem (12)
        • LeetCode (12)
        • Programmers (0)
      • 자격증 (1)
      • Tip (1)
      • Etc (1)
        • 도서, 강의 (1)
        • Talk (0)
  • 블로그 메뉴

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

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    java
    Packet Tracer
    CISCO
    cisco packet tracer
    java 필수 문법
    Network
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
김행만
[Java 필수 문법] 4. 배열(Array)과 리스트(List)
상단으로

티스토리툴바