본문 바로가기
개발 공부/JAVA

[JAVA] 컬렉션 프레임 워크 (1) (ArrayList / Vector / LinkedList)

by sngynhy 2021. 7. 24.

Collection(컬렉션)

 객체를 수집해서 저장하는 역할

   => 객체들을 효율적으로 추가, 삭제, 검색할 수 있도록 해줌

 

List 컬렉션

1. ArrayList

List 인터페이스의 구현 클래스로 데이터를 객체로 저장하여 관리.

배열과의 차이점은 크기가 고정돼있지 않다는 점!

리스트의 크기를 초기화 하더라도 저장 용량을 초과한 객체들이 추가되면 자동적으로 저장 용량이 늘어난다.

(ArrayList에서 특정 인덱스의 객체를 제거하면 바로 뒤 인덱스부터 마지막 인덱스까지 모두 앞으로 1씩 당겨진다.

마찬가지로 특정 인덱스에 객체 삽입 시 뒤로 1씩 밀려난다.)

 

import java.util.ArrayList;

class Student {
	String name;
	
	public Student() {
		this.name = "학생";
	}
	
	// 객체의 주소가 아닌 데이터가 나오도록 재정의!
	@Override
	public String toString() {
		return  "Student [name=" + name + "]";

	}
	
}
public class Arraylist {
	
	public static void main(String[] args) {
	
		// 프레임워크 ★☆★☆★
		// 뼈대, 골격, 구조, 틀
		// 동일한 구조(메뉴얼) 필요 - 섬세할수록 좋음.
		
		// 컬렉션(여러가지 관련된 데이터를 한 공간에 저장할 수 있는 공간)
		//  ㄴ 리스트, 스택, 큐, 맵, 집합(set) ...
		// 크기의 제한이 없음
		// 다양한 데이터를 관리할 수 있는 관련 메소드가 구현되어있음
		
		// [배열 리스트]
		// 리스트는 데이터를 객체로 저장함!
		ArrayList al = new ArrayList();  // 길이를 굳이 넣지 않음 어차피 계속 추가가 가능하기 때문에
		System.out.println(al.size());
		al.add(10);
		al.add(20);
		al.add(0, 30);  // 만약 해당 인덱스에 값이 있다면 데이터들이 오른쪽으로 한 칸씩 밀려남
		al.add(2, 40);
		al.add(4, 10);
		System.out.println(al + " " + al.size());
		System.out.println("3번 인덱스 값: " + al.get(3));
		System.out.println("삭제된 2번 인덱스 값: " + al.remove(2));
		System.out.println(al + " " + al.size());
		System.out.println("20의 인덱스: " + al.indexOf(20));
		System.out.println("1의 인덱스: " + al.indexOf(1)); // 만약 찾는 값이 리스트에 없으면 -1 출력
		System.out.println("10이 있니? " + al.contains(10)); // 10이 리스트에 포함되어 있는지
		System.out.println(al.lastIndexOf(10)); // 해당 값의 배열 내 마지막 인덱스
		
		if (al.indexOf(100) == -1) {
			System.out.println("100 없어");
		} 
		if (al.contains(20)) {
			System.out.println("20 있어");
		}
		
		for (Object obj : al) {
			System.out.print(obj + " ");
		}
		System.out.println();
		
		// 리스트는 데이터를 객체로 저장하므로 객체 추가 가능!
		al.add(new Student());
		System.out.println(al);
		
		al.clear(); // 리스트 요소 모두 제거
		System.out.println(al);
		
		if (al.isEmpty()) {
			System.out.println("텅텅~");
		}
		
	}
}

 

 

2. Vector

Vector는 동기화된(synchronized) 메소드로 구성되어 있기 때문에 멀티 스레드가 동시에 이 메소드를 실행할 수 없다.

따라서 멀티 스레드 환경에서 안전하게 객체를 추가, 삭제할 수 있다.

 

import java.util.*;

public class Board {
	
	String subject;  // 게시물 제목
	String content;  // 게시물 내용
	String writer;  // 게시물 작성자
	
	public Board(String subject, String content, String writer) {
		this.subject = subject;
		this.content = content;
		this.writer = writer;
	}
	
	@Override
	public String toString() {
		return this.subject + " " + this.content + " " + this.writer;
	}
}

public class VectorExample {

	public static void main(String[] args) {

		// Vector를 생성하려면
		// 저장할 객체 타입을 타입 파라미터로 표기하고 기본생성자를 호출!
		List<Board> list = new Vector<Board>();
		
		list.add(new Board("제목1", "내용1", "글쓴이1"));
		list.add(new Board("제목2", "내용2", "글쓴이2"));
		list.add(new Board("제목3", "내용3", "글쓴이3"));
		list.add(new Board("제목4", "내용4", "글쓴이4"));
		list.add(new Board("제목5", "내용5", "글쓴이5"));
		
		list.remove(2);
		list.remove(3);
		
		for (Board board : list) {
			System.out.println(board);
		}
	}

}

 

 

3. LinkedList

ArrayList와 마찬가지로 List 인터페이스의 구현 클래스로 데이터를 객체로 저장하여 관리.

차이점은 LinkedList는 객체를 인접 참조를 링크해서 체인으로 관리한다.

즉, 노드의 형태가 [값 | 다음 연결할 값의 주소]로 각 요소들이 연결되는 형태이므로
리스트의 크기를 초기화할 수 없다 => 기본생성자로 객체 생성!

import java.util.LinkedList;

public class Linkedlist {

	public static void main(String[] args) {
		
		LinkedList ll = new LinkedList();
		
		ll.add(10);
		ll.add("apple");
		System.out.println(ll);
		
	}
}

 

ArrayList와 LinkedList에 10000개의 객체를 삽입할 때 걸린 시간 측정 비교

import java.util.*;

public class LinkedListExample {

	public static void main(String[] args) {
		
		List<String> list1 = new ArrayList<String>();
		List<String> list2 = new LinkedList<String>();
		
		long startTime;
		long endTime;
		
		// ArrayList와 LinkedList에 10000개의 객체를 삽입할 때 걸린 시간 측정 비교
		// 0번 인덱스에 10000번 추가
		
		startTime = System.nanoTime();
		for (int i=0; i<10000; i++) {
			list1.add(0, String.valueOf(i)); // 
		}
		endTime = System.nanoTime();
		
		System.out.println("ArrayList 걸린 시간: " + (endTime - startTime) + "ns");
		
		startTime = System.nanoTime();
		for (int i=0; i<10000; i++) {
			list2.add(0, String.valueOf(i)); // 
		}
		endTime = System.nanoTime();
		
		System.out.println("LinkedList 걸린 시간: " + (endTime - startTime) + "ns");
		
	}

}

결과!

끝에서부터(순차적으로) 추가/삭제하는 경우는 ArrayList가 빠르지만,
중간에 추가/삭제할 경우는 앞뒤 링크만 변경하면 되는 LinkedList가 더 빠르다.
(ArrayList는 뒤쪽 인덱스들을 모두 1씩 증가 or 감소시키는 시간이 필요하므로 처리속도가 느리다!)

 

 

[결론]

ArrayList 배열 기반 리스트

  • 데이터의 잦은 이동. 추가/삭제 등에 불리
  • 인덱싱 방식을 사용 -> 검색(탐색)에 유리

 

LinkedList 연결 리스트

  • 노드를 기반으로 한 리스트를 컬렉션 화
  • 각 요소들이 서로 연결되어 있어 잦은 추가/삭제 등에 유리
  • 노드 방식 사용 -> 검색(탐색)에 불리