List 컬렉션은 인덱스로 관리하고 중복해서 객체 저장이 가능합니다.

구현 클래스는 'ArrayList', 'Vector', 'LinkedList'가 있습니다.

 


 

List 컬렉션에서 사용되는 주요 메서드는 다음과 같습니다.

 

 

  • boolean add(E e) : 주어진 객체를 맨 끝에 추가
  • void add(int index, E element) : 주어진 인덱스에 객체를 추가
  • set(int index, E element) : 주어진 인덱스에 저장된 객체를 주어진 객체로 변경

  • boolean contains(Object o) : 주어진 객체가 저장되어 있는지의 여부
  • get(int index) : 주어진 인덱스에 저장된 객체를 리턴
  • isEmpty() : 컬렉션이 비어 있는지 확인
  • int size() : 저장되어있는 젠체 객체 수를 리턴

  • void clear() : 저장된 모든 객체를 삭제
  • remove(int index) : 주어진 인덱스에 저장된 객체를 삭제
  • boolean remove(Object o) : 주어진 객체를 삭제

 


 


 

1. 어레이리스트( ArrayList )

ArrayList는 순서를 보장하고, 중복을 허용하고, 인덱스 번호로 관리합니다.

 

다음 코드는 객체를 추가하는 방법입니다.

 

@Log4j2
public class ArrayListExample {

	
    // 1. 순서보장
    // 2. 중복 허용
    // 3. 인덱스
    public static void main(String[] args) {
       List<String> list = new ArrayList<>();
		
        // ================================
        // 요소(객체) 추가
        // ================================
		
        list.add("java");           // 컬렉션의 맨 끝에 추가
        list.add("JDBC");
        list.add("Servlet/JSP");
        list.add(2, "Database");    // 지정된 인덱스 번호 위치에 추가
        list.add("iBATIS");
		
    } // main
	
} // end class

 

 

List는 인덱스 배열이기 때문에 대부분의 메서드가 인덱스 기반으로 되어 있습니다.

 

add() 메서드의 소괄호에 데이터 외에 숫자가 들어간다면, 그 숫자는 List의 인덱스 번호입니다.

즉, 인덱스 번호에 데이터를 할당한다는 의미입니다.

 

만약 메서드의 시그니처(선언부)가 궁금하다면 해당 메서드에 마우스를 호버링(hovering, 올려놓기)하면 됩니다.

 

 

메서드 시그니처

 

 

여기서 list 객체를 log.info로 출력해보시면 다음과 같은 내용이 출력됩니다.

 

log.info("list : {}", list);

 

List

 

 

그런데, add() 메서드로 인덱스 번호를 지정하고 데이터를 할당하면,

기존의 데이터들은 뒤로 밀려나게 되고 데이터를 삭제하면 삭제된 데이터의 후순위 데이터는 당겨지게 됩니다.

 

이러한 밀고 당겨지는 현상때문에 빅데이터에서의 List 컬렉션 사용은 지양해야 합니다.

 

 

2. 벡터( Vector )

벡터는 thread-safe하기 때문에 ArrayList보다 많이 사용됩니다.

 

게시판 글에 대한 예제입니다.

먼저 Borad 클래스입니다.

 

@ToString
@AllArgsConstructor
@Getter @Setter
public class Board {
    private String subject;		// 제목
    private String content;		// 내용
    private String writer;		// 작성자
	
	
} // end Board

 

다음은 Board 클래스를 기반으로 한 Vector 실행 클래스 코드입니다.

 

@Log4j2
public class VectorExample {

	
    public static void main(String[] args) {
        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(int i = 0; i < list.size(); i++) {
            Board board = list.get(i);

			
            // StringBuffer => Thread - Safe
            String boardLog = 
                    new StringBuffer().
                    append(board.getSubject()).append('\t').
                    append(board.getContent()).append('\t').
                    append(board.getWriter()).
                    toString();
			
            log.info(boardLog);
         } // Classical For
		
        // 남아있는 요소를 가진 컬렉션을 순회(Traverse) #2
        for(Board board : list) {
            log.info(board);
        } // enhanced for
		
        // 남아있는 요소를 가진 컬렉션을 순회(Traverse) #3 
        list.forEach(log::info);
		
    } // main
	
} // end class

 

Vector는 멀티 스레드가 동시에 Vector에 접근해서 객체를 추가, 삭제하더라도 thread-safe합니다.

 

 

3. 링크 리스트( LinkedList )

LinkedList는 thread-unsafe하지만,  ArrayList와 Vector의 요소를 저장하는 구조와 다릅니다.

근처의 참조를 링크해서 체인처럼 관리하고, 특정 인덱스에서 객체를 삭제하거나 추가하게 되면 바로 앞뒤 링크만 재설정합니다.

그렇기 때문에, 실질적인 자리이동이 없습니다.

 

하지만, 다른 레퍼런스를 참조할 때, Vector나 ArrayList 보다 속도가 느리다는 것이 단점입니다.

 

다음은 ArrayList와 LinkedList의 속도 비교입니다.

 

@Log4j2
public class LinkedListExample {
	
	
    public static void main(String[] args) {
        // 1. ArrayList 컬렉션
        List<String> list1 = new ArrayList<String>();
        // 2. LinkedList 컬렉션
        List<String> list2 = new LinkedList<String>();
		
        long startTime;
        long endTime;
		
        startTime = System.nanoTime();
        for(int i = 0; i < 100000; i++) {
            // 미는 현상을 일부러 발생시키기 위해,
            // 리스트의 가장 처음 요소로 무조건 추가
            list1.add(0, String.valueOf(i));
        } // Classical For
		
        endTime = System.nanoTime();
        log.info("ArrayList Elased Time : {}", (endTime - startTime));
		
        // ===========================================================
		
        startTime = System.nanoTime();
		
        for(int i = 0; i < 100000; i++) {
            // 0번 인덱스에 새로운 요소를 추가하지만 미는 현상이 발생 안함
            list2.add(0, String.valueOf(i));
        } // Classical For
		
        endTime = System.nanoTime();
        log.info("ArrayList Elased Time : {}", (endTime - startTime));
        
    } // main
	
} // end class

 

다음은 코드의 결과입니다.

 

LinkedList

 

위의 결과에서도 알 수 있듯이, LinkedList는 ArrayList보다 훨씬 빠른 속도를 보여주고 있습니다.

 

인터페이스의 성질 뿐만 아니라 구현 클래스의 성질과 차이도 잘 알고있어야, 코드를 효율적으로 구축할 수 있습니다.

 

 

 

 

 

 

 

 

'Java > Collection Framework' 카테고리의 다른 글

트리 컬렉션  (0) 2023.08.04
맵 컬렉션  (0) 2023.08.03
셋 컬렉션  (0) 2023.08.03
컬렉션 프레임워크 개요  (0) 2023.08.02

+ Recent posts