[Java] 기초 - List

이지연·2025년 12월 12일

개요

아래의 내용은 java_grammer 레파지토리 C01Basic 디렉터리에 저장되어있는 내용을 정리하였다.


List의 특징

List는 배열이랑 다르게 값을 추가하거나 삭제할 수 있음.
즉, 길이가 고정된 배열과 달리 유연하게 데이터 조작이 가능하다는 점이 제일 큼.

List 자체는 인터페이스(일종의 카테고리)임. 실제 구현체로는 ArrayList, LinkedList 등이 있음.
결국 List는 껍데기일 뿐이고, 진짜 동작은 구현체가 함.

List, Map, Set은 모두 컬렉션 프레임워크(Collection Framework)에 속함.
그래서 contains, equals, isEmpty, size, toArray 같은 공통 메서드를 공유함.

이 때 주의할 점

  • 컬렉션 프레임워크에서는 기본형 타입 사용 불가, 반드시 래퍼 클래스(Wrapper class) 써야 함.
    → 객체 일관성을 맞추고, 래퍼 클래스가 제공하는 기능들을 활용하기 위함임.
    → 자바 초창기 설계는 기본형+배열 중심이었는데, 컬렉션은 이후에 객체지향적으로 추가된 개념임.
  • Arrays 클래스는 컬렉션에 속하지 않지만, 배열 ↔ 컬렉션 간 변환을 도와주는 유틸 클래스임.
    (Arrays.asList(), Arrays.sort() 같은 메서드 제공)

List선언 방법

(1) ArrayList 직접 사용

ArrayList<String> myList = new ArrayList<String>();
ArrayList<String> myList2 = new ArrayList<>(); // 오른쪽 제네릭은 생략 가능

(2) 가장 일반적인 방식 (인터페이스 타입으로 선언)
인터페이스는 실체가 없고, 그저 카테고리일 뿐임 → 구현체를 오른쪽에 둬야 함.

List<String> myList3 = new ArrayList<>();

초기값 세팅 (1) : add()로 하나씩 추가

myList3.add("java");
myList3.add("js");
myList3.add("c++");
System.out.println("List 초기값 세팅1 : " + myList3);

초기값 세팅 (2) : 배열 → 리스트 변환

String[] arr = {"java", "js", "c++"};
List<String> myList4 = new ArrayList<>(Arrays.asList(arr));
System.out.println("List 초기값 세팅2 : " + myList4);

기본형 자료 사용 불가

리스트 안에는 기본형 타입(int, double 등)을 바로 못 담음.
그래서 반드시 Wrapper 타입(Integer, Double 등)을 써야 함.

int[] intArr = {10, 20, 30};
List<Integer> myList5 = new ArrayList<>();
for (int i : intArr) {
    myList5.add(i);
}
System.out.println("for문으로 기본자료형 삽입 : " + myList5);

List의 출력 구조

참조형은 원래 힙 메모리 주소가 찍혀야 하는데,
List는 내부적으로 toString() 메서드가 미리 구현되어 있어서 값이 출력됨.

→ 직접 들어가 보면 ArrayListAbstractListAbstractCollection 순으로 상속되어 있고,
AbstractCollectiontoString()이 구현되어 있음.

즉, 우리가 만든 클래스 객체라면 별도로 toString() 오버라이딩을 해줘야함.


주요 메서드

add()

리스트에 값 추가.
중간 index 지정하면 나머지 요소들이 한 칸씩 밀리기 때문에 성능은 살짝 손해임.

List<Integer> test_list = new ArrayList<>();
test_list.add(10);
test_list.add(20);
test_list.add(0, 30);
System.out.println("add : " + test_list);

get(index) → 해당 인덱스의 요소 조회
size() → 리스트 길이 반환
set(index, element) → 해당 위치 값 대체

리스트 값 출력

System.out.println("=== 일반 for문 ===");
for (int i = 0; i < test_list.size(); i++) {
    System.out.println(test_list.get(i));
}

System.out.println("=== 향상된 for문 ===");
for (int a : test_list) {
    System.out.println(a);
}

remove() → 특정 index나 값 삭제
index 기준으로 삭제 시 인덱스 밀림 있음.

List<Integer> remove_list = new ArrayList<>();
remove_list.add(10);
remove_list.add(20);
remove_list.add(30);
remove_list.remove(0);
remove_list.remove(remove_list.size() - 1);

indexOf(value) → 해당 값의 첫 index 반환
contains(value) → 값 존재 여부 반환

List<Integer> index_list = new ArrayList<>();
index_list.add(10);
index_list.add(20);
index_list.add(30);
index_list.add(30);
System.out.println("indexOf 30 : " + index_list.indexOf(30));
System.out.println("contains 20 : " + index_list.contains(20));

정렬

리스트 정렬은 두 가지 방법이 있음.

  1. Collections.sort() → 클래스 메서드로 정렬
  2. list.sort() → 객체 자기 자신의 메서드로 정렬
List<Integer> sort_list = new ArrayList<>(Arrays.asList(5, 3, 2, 1, 4));
Collections.sort(sort_list); // 오름차순
Collections.sort(sort_list, Comparator.reverseOrder()); // 내림차순
System.out.println("클래스메서드 오름→내림 : " + sort_list);

sort_list.sort(Comparator.naturalOrder());
sort_list.sort(Comparator.reverseOrder());
System.out.println("객체메서드 오름→내림 : " + sort_list);

이중 리스트 (리스트 안리스트)

이중 리스트는 간단히 말해 리스트 안에 또 다른 리스트가 들어있는 구조임.
빈 외부 리스트만 만들면 내부에 데이터를 바로 넣을 수 없고,
new ArrayList<>()내부 껍데기를 먼저 만들어야 함.

List<List<Integer>> multi_list = new ArrayList<>();

List<Integer> m1 = new ArrayList<>();
multi_list.add(m1);
multi_list.add(new ArrayList<>());

m1.add(1);
m1.add(2);
m1.add(3);
multi_list.get(1).add(4);
multi_list.get(1).add(5);
multi_list.get(1).add(6);

System.out.println(multi_list);

메모리 구조 요약

  • multi_list는 내부 리스트들의 주소값만 저장함.
  • m1을 add하면 그 객체의 참조(주소)를 multi_list가 기억함.
  • 결국 참조 타입이기 때문에 어느 쪽에서 add하든 같은 객체가 수정됨.

리스트 안에 배열

배열도 객체라서 리스트 안에 들어갈 수 있음.

List<int[]> m_list = new ArrayList<>();
int[] arr1 = new int[2];
arr1[0] = 1;
arr1[1] = 2;
m_list.add(arr1);

m_list.add(new int[3]);
m_list.get(1)[0] = 1;
m_list.get(1)[1] = 2;
m_list.get(1)[2] = 3;

m_list.add(new int[]{4, 3, 2, 1});

배열은 toString()이 구현되어 있지 않기 때문에, 그냥 출력하면 주소값이 나옴.
값을 보기 위해서는 Arrays.toString()을 써야 함.

StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < m_list.size(); i++) {
    sb.append(Arrays.toString(m_list.get(i)));
    if (i != m_list.size() - 1) sb.append(", ");
}
sb.append("]");
System.out.println("리스트 안 배열 값 출력 : " + sb);

실습예제

이중 리스트 만들기

[[1,2,3],[4,5,6],...,[58,59,60]] 형태로 만들기

List<List<Integer>> my_list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
    my_list.add(new ArrayList<>());
    for (int j = 1; j < 4; j++) {
        my_list.get(i).add(3 * i + j);
    }
}
System.out.println(my_list);
profile
Eazy하게

1개의 댓글

comment-user-thumbnail
2025년 12월 14일

래퍼 클래스
음유시인 클래스
버서커 클래스
암흑사제 클래스

답글 달기