Categories: Java

Java에서 ArrayList 사용법과 실전 예제

안녕하세요! 여러분, Java 프로그래밍의 재미있는 세계에 오신 걸 환영해요! 오늘 우리가 함께 탐험할 주제는 바로 ArrayList입니다. Java에서 데이터를 효율적으로 다루는 데 필수적인 ArrayList! 초보자분들도 쉽게 이해할 수 있도록 제가 친절하게 설명해 드릴게요.

ArrayList 생성과 초기화부터 시작해서, 주요 메서드 활용법까지 차근차근 알아볼 거예요. 실전 예제를 통해 데이터 추가와 삭제도 직접 해보면서 감을 잡아보도록 하죠! 마지막으로 ArrayList 활용 성능 향상 팁까지 알려드릴 테니 기대해 주세요. 자, 그럼 ArrayList의 매력 속으로 함께 빠져볼까요?

 

 

ArrayList 생성과 초기화

자, 이제 본격적으로 Java의 ArrayList에 대해 알아볼까요? ArrayList크기가 동적으로 변하는 배열이라고 생각하면 이해하기 쉬워요! 일반 배열은 한 번 크기를 정하면 바꿀 수 없지만, ArrayList는 데이터가 추가될 때마다 자동으로 크기가 조정된답니다. 얼마나 편리한지 몰라요!

ArrayList 생성

ArrayList를 생성하는 방법은 몇 가지가 있는데, 가장 기본적인 방법은 다음과 같아요.

ArrayList<String> names = new ArrayList<>();

여기서 <String> 부분은 ArrayList에 저장할 데이터의 타입을 지정하는 거예요. String 대신 Integer, Double, 또는 직접 만든 클래스 등 다양한 타입을 사용할 수 있답니다. 이렇게 타입을 명시하는 것을 “제네릭(Generics)“이라고 부르는데, 덕분에 코드가 더 안전하고 효율적이게 된대요!

ArrayList 초기화

초기값을 가지는 ArrayList를 만들고 싶다면? 걱정 마세요! 다음처럼 생성하면서 바로 초기화할 수도 있어요.

ArrayList<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5)); 

Arrays.asList() 메서드를 사용하면 여러 개의 값을 한 번에 넣을 수 있어서 정말 편리해요!

초기 용량 설정

만약 초기 용량(capacity)을 지정하고 싶다면, 다음과 같이 생성자에 용량 값을 넣어주면 돼요. 초기 용량은 ArrayList가 내부적으로 배열을 생성할 때 사용하는 크기랍니다.

ArrayList<Double> prices = new ArrayList<>(10);

초기 용량을 지정하면 ArrayList의 크기가 변경될 때마다 새로운 배열을 생성하는 횟수를 줄일 수 있어서 성능 향상에 도움이 된대요! 하지만 너무 큰 용량을 지정하면 메모리 낭비가 발생할 수 있으니, 적절한 크기를 선택하는 것이 중요해요!

ArrayList 용량 증가

ArrayList의 초기 용량은 10이지만, 요소를 추가하면 자동으로 용량이 늘어나요. 예를 들어 11번째 요소를 추가하면 ArrayList는 내부적으로 새로운 배열을 생성하고 기존 요소들을 복사한 후 새로운 요소를 추가한답니다. 이 과정에서 시간이 조금 걸릴 수 있지만, 걱정하지 마세요! ArrayList는 최대한 효율적으로 용량을 조절하도록 설계되어 있으니까요!

ArrayList 활용

자, 이제 ArrayList를 생성하고 초기화하는 방법을 알았으니, 다음 단계로 넘어가 볼까요? ArrayList에는 다양한 메서드들이 준비되어 있어서 데이터를 자유자재로 다룰 수 있답니다. ArrayList를 사용하면 데이터를 추가하고 삭제하는 것은 물론이고, 특정 위치에 있는 데이터를 가져오거나 수정할 수도 있어요. 또한, ArrayList의 크기를 확인하거나, ArrayList가 비어 있는지 확인하는 등 다양한 작업을 수행할 수 있답니다.

 

ArrayList 주요 메서드 활용

자, 이제 본격적으로 ArrayList가 가진 다양한 메서드들을 살펴볼까요? 마치 요리사가 칼을 다루듯이, 이 메서드들을 자유자재로 활용하면 데이터를 효율적으로 관리하고 원하는 결과를 끌어낼 수 있답니다! 어떤 메서드들이 있는지, 하나씩 같이 탐험해 보아요~?

1. 데이터 추가 (add)

ArrayList에 새로운 데이터를 추가하는 건 정말 쉬워요! add() 메서드를 사용하면 되는데요, add(E element)처럼 요소를 바로 추가할 수도 있고, add(int index, E element)처럼 특정 위치에 쏙! 넣어줄 수도 있답니다. 예를 들어, myList.add("apple")이라고 하면 “apple”이라는 문자열이 리스트 맨 끝에 추가되고, myList.add(1, "banana")는 “banana”를 인덱스 1번 위치에 삽입한답니다. 참 쉽죠~?!

2. 데이터 조회 (get)

특정 위치에 있는 데이터를 꺼내 보고 싶을 땐 get(int index) 메서드를 사용하면 돼요. 예를 들어, myList.get(0)이라고 하면 리스트의 첫 번째 요소를 가져올 수 있어요. 만약 없는 인덱스를 요청하면 IndexOutOfBoundsException이 발생하니 조심해야 해요! 마치 보물상자에서 없는 보물을 찾으려는 것과 같으니까요!

3. 데이터 삭제 (remove)

ArrayList에서 데이터를 삭제하는 방법은 크게 두 가지가 있어요. remove(int index)는 특정 위치의 요소를 삭제하고, remove(Object o)는 특정 객체와 동일한 요소를 삭제해요. 예를 들어, myList.remove(2)는 인덱스 2번 요소를 삭제하고, myList.remove("apple")은 “apple”이라는 문자열을 찾아서 삭제한답니다. 마치 정원에서 잡초를 뽑는 것처럼 깔끔하게 데이터를 관리할 수 있어요!

4. 데이터 수정 (set)

기존 데이터를 다른 값으로 바꾸고 싶을 땐 set(int index, E element) 메서드를 사용하면 돼요. myList.set(0, "orange")처럼 하면 첫 번째 요소를 “orange”로 변경할 수 있답니다. 마치 옷을 갈아입듯이 데이터를 새롭게 단장시킬 수 있어요!

5. 리스트 크기 확인 (size)

ArrayList에 몇 개의 요소가 있는지 궁금하다면 size() 메서드를 사용하면 돼요. myList.size()는 현재 리스트의 크기를 반환해준답니다. 마치 줄자로 길이를 재듯이 리스트의 크기를 측정할 수 있어요!

6. 리스트 비우기 (clear)

ArrayList의 모든 요소를 한 번에 삭제하고 싶을 땐 clear() 메서드를 사용하세요! myList.clear()를 실행하면 리스트가 텅! 비게 된답니다. 마치 칠판을 깨끗하게 지우는 것처럼 간편하게 리스트를 초기화할 수 있어요!

7. 리스트가 비어있는지 확인 (isEmpty)

리스트가 비어있는지 확인하려면 isEmpty() 메서드를 사용하면 돼요. myList.isEmpty()는 리스트가 비어있으면 true, 아니면 false를 반환해준답니다. 마치 빈 상자를 확인하듯이 간단하게 확인할 수 있어요!

8. 특정 요소가 있는지 확인 (contains)

리스트에 특정 요소가 있는지 확인하고 싶을 땐 contains(Object o) 메서드를 사용하면 돼요. myList.contains("apple")처럼 사용하면 “apple”이라는 문자열이 리스트에 있는지 확인하고, 있다면 true, 없다면 false를 반환해준답니다. 마치 숨바꼭질하듯이 원하는 요소를 찾을 수 있어요!

9. 특정 요소의 인덱스 찾기 (indexOf)

특정 요소가 리스트의 몇 번째 위치에 있는지 알고 싶을 땐 indexOf(Object o) 메서드를 사용하세요! myList.indexOf("banana")처럼 사용하면 “banana”의 인덱스를 반환해주고, 만약 해당 요소가 없다면 -1을 반환한답니다. 마치 지도에서 위치를 찾는 것처럼 정확한 인덱스를 알 수 있어요!

10. 하위 리스트 가져오기 (subList)

리스트의 일부분을 추출하고 싶을 땐 subList(int fromIndex, int toIndex) 메서드를 사용하면 된답니다! myList.subList(2, 5)처럼 사용하면 인덱스 2부터 4까지의 요소를 포함하는 새로운 리스트를 만들어줘요. fromIndex는 포함, toIndex는 제외라는 점을 기억해두세요! 마치 케이크를 조각내듯이 원하는 부분만 쏙! 가져올 수 있어요!

이 외에도 다양한 메서드들이 존재하지만, 위에 소개된 메서드들만 잘 활용해도 ArrayList를 마스터하는데 큰 도움이 될 거예요! 각 메서드의 시간 복잡도(Time Complexity)를 이해하고 사용하면 더욱 효율적인 코드를 작성할 수 있답니다. 예를 들어, get() 메서드는 O(1)의 시간 복잡도를 가지지만, add(int index, E element)처럼 중간에 요소를 삽입하는 경우에는 최악의 경우 O(n)의 시간 복잡도를 가질 수 있다는 점! 꼭 기억해두세요! 다음에는 실전 예제를 통해 배운 내용을 직접 활용해보도록 할게요! 기대해주세요~!

 

실전 예제: 데이터 추가 및 삭제

자, 이제까지 ArrayList의 기본적인 생성과 초기화, 그리고 주요 메서드들을 살펴봤어요. 이론만으론 감이 잘 안 잡힐 수도 있으니, 실제로 데이터를 추가하고 삭제하는 예제를 통해 좀 더 깊이 있게 이해해 보도록 할까요? ^^ 실제 코드를 보면서 익히는 게 가장 효과적이니까요!

빈 ArrayList 생성

먼저, 빈 ArrayList를 하나 만들어 볼게요. 이 ArrayList에는 String 타입의 데이터를 저장할 거예요. 마치 빈 상자를 준비하는 것과 같다고 생각하면 돼요.

ArrayList<String> fruits = new ArrayList<>();

이렇게 하면 fruits라는 이름의 빈 ArrayList가 생성되었어요! 이제 여기에 과일 이름들을 하나씩 추가해 볼게요. add() 메서드를 사용하면 돼요. 참 쉽죠?

데이터 추가

fruits.add("Apple");
fruits.add("Banana");
fruits.add("Orange");
fruits.add("Grape");

add() 메서드를 사용해서 “Apple”, “Banana”, “Orange”, “Grape”를 차례대로 추가했어요. fruits 리스트에는 이제 네 개의 과일 이름이 저장되어 있겠죠? 이 상태에서 fruits 리스트를 출력해보면 어떤 결과가 나올까요? 궁금하시죠?! 한번 해볼까요?

System.out.println(fruits); // 출력 결과: [Apple, Banana, Orange, Grape]

짜잔~! 예상대로 네 개의 과일 이름이 예쁘게 출력되었네요! ArrayList는 이렇게 데이터를 순서대로 저장하고, 출력할 때도 순서대로 보여준답니다. ArrayList가 얼마나 편리한지 느껴지시나요? ^^

특정 위치에 데이터 삽입

자, 이제 “Mango”를 추가해볼게요. add() 메서드를 사용하면 되는데, 이번에는 특정 위치에 삽입해 보도록 하죠! “Orange”와 “Grape” 사이에 넣고 싶다고 가정해 봅시다. ArrayList의 인덱스는 0부터 시작한다는 것을 기억하면서, “Orange”의 인덱스인 2번 위치에 “Mango”를 삽입해 볼게요.

fruits.add(2, "Mango");
System.out.println(fruits); // 출력 결과: [Apple, Banana, Orange, Mango, Grape]

보시는 것처럼 “Mango”가 “Orange” 앞에 쏙 들어갔네요! add(index, element) 메서드를 사용하면 원하는 위치에 데이터를 삽입할 수 있어요. 정말 유용하죠?

데이터 삭제

이제 데이터를 삭제하는 방법을 알아볼까요? “Banana”가 갑자기 싫어졌다고 가정하고, “Banana”를 삭제해 보도록 하죠. remove() 메서드에는 객체를 직접 삭제하는 방법과 인덱스를 이용해 삭제하는 방법, 두 가지가 있어요.

객체 직접 삭제

fruits.remove("Banana");
System.out.println(fruits); // 출력 결과: [Apple, Orange, Mango, Grape]

“Banana”가 삭제된 것을 확인할 수 있죠? 참 쉽죠잉~?

인덱스를 이용한 삭제

이번에는 인덱스를 이용해서 삭제해 볼게요. “Mango”를 삭제한다고 가정하고, “Mango”의 인덱스인 2를 사용해서 삭제해 보겠습니다.

fruits.remove(2);  // 인덱스 2에 위치한 "Mango" 삭제
System.out.println(fruits); // 출력 결과: [Apple, Orange, Grape]

이렇게 인덱스를 사용해서도 데이터를 삭제할 수 있어요. 상황에 따라 편한 방법을 사용하면 된답니다.

ArrayList 성능 향상 팁

ArrayList는 데이터를 추가하고 삭제하는 작업이 정말 빈번하게 일어나는데, 내부적으로 어떻게 동작하는지 알고 있으면 성능 최적화에 도움이 돼요! ArrayList는 배열 기반으로 구현되어 있어서, 데이터를 추가하거나 삭제할 때 배열의 크기를 조정해야 하는 경우가 발생해요. 이때 배열 복사 작업이 일어나기 때문에 시간이 꽤 걸릴 수 있답니다. 따라서 처음 ArrayList를 생성할 때 예상되는 데이터의 크기를 initialCapacity 인자로 넘겨주면 불필요한 배열 복사를 줄여 성능을 향상시킬 수 있어요! 예를 들어, 1000개 정도의 데이터를 저장할 예정이라면 new ArrayList<>(1000) 처럼 생성하는 것이 좋답니다. 작은 팁이지만, 실제로 큰 차이를 만들 수 있으니 꼭 기억해 두세요! 다음에는 ArrayList 활용 성능 향상 팁에 대해 좀 더 자세히 알아보도록 할게요!

 

ArrayList 활용 성능 향상 팁

자, 이제 드디어 Java ArrayList 활용의 꽃이라고 할 수 있는 성능 향상 팁에 대해 알아볼 시간이에요! 지금까지 잘 따라오셨다면 이미 여러분은 ArrayList의 기본적인 사용법은 물론, 다양한 메서드까지 익히셨을 거예요. 하지만! 진정한 ArrayList 마스터가 되려면 성능 최적화는 필수겠죠? ^^ ArrayList를 사용할 때 어떤 부분을 신경 써야 성능을 극대화할 수 있는지, 숨겨진 꿀팁들을 대방출할게요!

ArrayList의 작동 방식과 성능

자바에서 ArrayList는 동적으로 크기가 조정되는 배열 기반의 리스트입니다. 이 말인즉슨, ArrayList 내부적으로는 배열을 사용하여 요소들을 저장하고 관리한다는 의미죠. 배열은 메모리 상에 연속적으로 할당되기 때문에 인덱스를 이용한 접근(get) 속도가 굉장히 빠르다는 장점이 있어요. Big O 표기법으로는 O(1)의 시간 복잡도를 가진다고 하죠! 하지만, 배열의 크기를 변경해야 할 때는 어떨까요? 예를 들어, ArrayList의 용량이 부족해서 새로운 요소를 추가해야 하는 상황을 생각해 보세요. 이때는 새로운 크기의 배열을 할당하고 기존 배열의 모든 요소를 복사해야 합니다. 이러한 작업은 시간이 꽤 걸리는 작업이에요. 특히, ArrayList의 크기가 클수록 더욱더 그렇죠. 이런 경우 시간 복잡도는 최악의 경우 O(n)까지 증가할 수 있어요. (n은 ArrayList의 크기!)

초기 용량 설정

그렇다면 어떻게 이러한 성능 저하를 막을 수 있을까요? 가장 효과적인 방법 중 하나는 바로 초기 용량(initial capacity)을 설정하는 거예요. ArrayList를 생성할 때 예상되는 요소의 개수를 미리 지정해 주면, 불필요한 배열 크기 조정 횟수를 줄일 수 있죠. 예를 들어, 1000개의 요소를 저장할 ArrayList가 필요하다면, ArrayList<String> list = new ArrayList<>(1000); 과 같이 초기 용량을 지정해주면 돼요. 이렇게 하면 ArrayList는 처음부터 1000개의 요소를 저장할 수 있는 크기의 배열을 할당하기 때문에, 중간에 배열 크기를 조정하는 오버헤드를 줄일 수 있답니다.

trimToSize() 메서드 활용

초기 용량 설정 외에도 trimToSize() 메서드를 활용하는 것도 좋은 방법이에요. ArrayList에 요소를 추가하고 삭제하는 과정을 반복하다 보면, 실제 저장된 요소의 개수보다 배열의 크기가 더 커지는 경우가 발생할 수 있어요. 이럴 때 trimToSize() 메서드를 호출하면, 배열의 크기를 현재 저장된 요소의 개수에 맞게 줄여서 메모리 사용량을 최적화할 수 있답니다. 물론, 이후에 요소를 추가하게 되면 다시 배열 크기 조정이 발생할 수 있으니, 더 이상 요소가 추가되지 않을 시점에 사용하는 것이 효율적이에요.

ensureCapacity() 메서드 활용

또 다른 팁은 바로 ensureCapacity() 메서드를 활용하는 거예요! 만약 초기 용량을 지정하지 않았거나, 예상보다 더 많은 요소를 추가해야 하는 경우, ensureCapacity() 메서드를 사용하여 ArrayList의 용량을 늘릴 수 있어요. 이 메서드는 내부적으로 배열 크기 조정 작업을 수행하는데, 미리 용량을 늘려줌으로써 잦은 크기 조정으로 인한 성능 저하를 방지할 수 있답니다. 예를 들어, 현재 ArrayList의 용량이 100인데, 앞으로 500개의 요소를 추가해야 한다면, list.ensureCapacity(600); 과 같이 호출하여 용량을 확보할 수 있어요.

적절한 데이터 구조 선택

마지막으로, 가장 중요한 팁은 바로 적절한 데이터 구조 선택이에요! ArrayList는 인덱스를 이용한 접근에는 매우 효율적이지만, 중간에 요소를 삽입하거나 삭제하는 작업은 상대적으로 느려요. 만약 ArrayList의 중간에서 빈번하게 요소를 삽입하거나 삭제해야 한다면, LinkedList와 같은 다른 자료구조를 고려해 보는 것이 좋습니다. LinkedList는 요소의 삽입/삭제에 O(1)의 시간 복잡도를 가지지만, 인덱스를 이용한 접근에는 O(n)의 시간 복잡도를 가진다는 점을 유의해야 해요. 데이터 접근 패턴을 분석하고, 상황에 맞는 최적의 자료구조를 선택하는 것이 성능 향상의 핵심이랍니다!

이처럼 ArrayList의 성능을 향상시키는 방법은 여러 가지가 있어요. 초기 용량 설정, trimToSize(), ensureCapacity() 활용, 그리고 적절한 자료구조 선택까지! 이러한 팁들을 잘 활용한다면 여러분의 Java 코드는 훨씬 더 효율적이고 빠르게 동작할 수 있을 거예요. 이제 여러분은 ArrayList 마스터를 넘어 성능 최적화 전문가로 한 걸음 더 나아갔어요! 축하합니다! 🎉

 

자, 이렇게 ArrayList에 대해서 알아봤어요! 어때요, 이제 좀 친해진 것 같나요? 처음엔 낯설게 느껴졌을 수도 있지만, 막상 써보면 정말 편리한 친구라는 걸 알게 될 거예요. 데이터를 다루는 데 ArrayList만큼 든든한 지원군도 드물다는 걸 알게 될 거예요. 앞으로 여러분의 코딩 여정에서 ArrayList가 얼마나 큰 도움을 줄지 기대되네요! 배운 내용을 토대로 직접 코드를 작성하고 다양한 실험을 해보면서 ArrayList 활용 능력을 쑥쑥 키워보세요. 혹시 궁금한 점이 생기면 언제든지 다시 찾아와서 함께 고민해 봐요. 즐거운 코딩하세요!

 

Itlearner

Share
Published by
Itlearner

Recent Posts

SSH 프로토콜 기초 및 활용

안녕하세요! 오늘은 저와 함께 SSH 프로토콜에 대해 알아보는 시간을 가져보려고 해요. 마치 마법의 문처럼, SSH는…

30분 ago

FTP 설정 및 사용법

안녕하세요, 여러분! 오늘은 웹사이트 관리나 파일 공유할 때 정말 유용한 FTP에 대해 알아보려고 해요. 혹시…

5시간 ago

HTTP와 HTTPS의 차이

인터넷을 돌아다니다 보면 주소창에 http와 https가 붙어있는 걸 본 적 있죠? 별 생각 없이 지나쳤을…

9시간 ago

UDP란? TCP와의 차이점

안녕하세요! 오늘은 컴퓨터 네트워크에서 중요한 역할을 하는 UDP에 대해 함께 알아보는 시간을 가져보려고 해요. 마치…

13시간 ago

TCP/IP 프로토콜 완벽 가이드

안녕하세요! 오늘은 인터넷 세상의 핵심, 바로 TCP/IP 프로토콜에 대해 함께 알아보는 시간을 가져보려고 해요. 마치…

17시간 ago

라우팅이란? 초보자 가이드

안녕하세요! 혹시 인터넷 서핑을 하다가, 갑자기 궁금해진 적 없으세요? 내가 보내는 이 메시지, 어떻게 정확히…

21시간 ago

This website uses cookies.