세로형
Recent Posts
Recent Comments
Link
04-27 05:03
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Archives
Today
Total
관리 메뉴

꿈 많은 사람의 이야기

자바 컬렉션 프레임워크(Collection Framework)소개 및 List 컬렉션(Array List, Vector, LinkedList) 본문

java

자바 컬렉션 프레임워크(Collection Framework)소개 및 List 컬렉션(Array List, Vector, LinkedList)

이수진의 블로그 2017. 8. 18. 08:49

배열은 쉽게 생성하고 사용할 수 있지만, 저장할 수 있는 객체 수가 생성할 때 결정되기 때문에 지속적으로 변화하는 객체를 저장하기엔 부족한 면이 있다. 배열의 크기를 크게 생성하면 되지만 이것은 좋지 못한 방법이다. 특히 객체를 삭제 했을 때 해당 인덱스가 비게 되는 문제가 있다. 아래의 그림을 보자

 

이렇게 듬성듬성 빠져 공간 낭비가 될 수도 있고 저장 하는 구조도 썩 좋지 않다. 

자바는 이러한 문제점을 해결하기 위해 자료구조(Data Structure)를 바탕으로 객체들을 효율적으로 추가, 삭제, 검색할 수 있도록 java.util 패키지에 컬렉션과 관려뇐 인터페이스와 클래스들을 포함시켰다. 이것을들 컬렉션 프레임워크(Collection Framework)라고 부른다.

컬렉션은 요소를 수집해서 저장하는 것이고 프레임워크는 사용 방법을 정해 놓은 라이브러리를 말한다.
밑의 그림은 컬렉션 클래스이다.(List, Set, Map은 인터페이스이다.)

 


ArrayList, Vector, LinkedList는 List 인터페이스를 구현한 클래스이고 마찬가지로 HashSet, TreeSet은 Set 인터페이스를 구현한 클래스로 Set 인터페이스로 사용 가능한 컬렉션이고 Map도 마찬가지이다.

List와 Set은 추가, 삭제, 검색하는 방법에 많은 공통점이 있기 때무에 이 인터페이스들의 공통된 메소드들만 모아 Collection 인터페이스로 정의해 두고 있다. Map은 키와 값을 하나의 쌍으로 묶어서 관리하는 구조로 되어 있어, List 및 Set 과는 사용 방법이 완전히 다르다.
밑의 표는 컬렉션의 특징을 정리한 것이다.

인터페이스 분류
특징
구현 클래스
Collection
List
-순서로 유지하고 저장
-중복 저장 가능
ArrayList, Vector, LinkedList
Set
-순서를 유지하지 않고 저장
-중복 저장 안됨
HashSet, TreeSet
Map
-키와 값의 쌍으로 저장
-키는 중복 저장 안됨
HashMap, Hashtable,
TreeMap, Properties


List 컬렉션

List 컬렉션은 객체를 일렬로 늘어놓은 구조를 가지고 있다. 객체를 저장하면 자동 인덱스가 부여되고 인덱스로 객체를 검색, 삭제할 수 있는 기능을 제공한다. List는 객체 번지를 저장한다. (객체 자체를 저장하지 않음)
동일한 객체를 중복 저장할 수 있는데, 이 경우 동일한 번지가 참조된다. null도 저장이 가능한데 이 경우 해당 인덱스는 객체를 참조하지 않는다.

 

위 그림과 같은 구조가 List 컬렉션이다.

밑의 표는 List 컬렉션에서 공통적으로 사용 가능한 List 인터페이스의 메소드들이다.

기능
메소드
설명
객체 추가
boolean add(E e)
주어진 객체를 맨 끝에 추가
void add(int index, E element)
주어진 인덱스에 객체를 추가
set(int index, E element)
주어진 인덱스에 저장된 객체를 주어진 객체로 바꿈
객체 검색
boolean contains(Object o)
주어진 객체가 저장되어 있는지 여부
E get(int index)
주어진 인덱스에 저장된 객체를 리턴
isEmpty( )
컬렉션이 비어 있는지 조사
int size( )
저장되어 있는 전체 객체 수를 리턴
객체 삭제
void clear( )
저장된 모든 객체를 삭제
E remove(int index)
주어진 인덱스에 저장된 객체를 삭제
boolean remove(Object o)
주어진 객체를 삭제

표에서 E 라는 타입 파라미터가 있는데 이것은 List 인터페이스가 제네릭 타입이라서 그렇다.
객체 추가는 add() 메소드 사용, 값을 받아올 때는 get(), 삭제는 remove() 메소드를 사용한다.

1
2
3
4
5
6
List<String> list = ...;
list.add("홍길동");    //맨끝에 객체 삽입
list.add(1"김길동"); // 지정된 인덱스에 객체 삽입
String str = list.get(1); //인덱스로 객체 찾기
list.remove(0); //인덱스로 객체 삭제
list.remove("신용권");  //객체 

만약 전체 객체를 대상으로 하나씩 반복해서 저장된 객체를 얻고 싶다면 다음과 같이 for문을 사용할 수 있다.

1
2
3
4
5
List<String> list = ..;
for(int i = 0 ; i < list.size() ;  i++)
{
    String str = list.get(i);  //i 인덱스에 저장된 String 객체를 
}
Colored by Color Scripter


위와 같이 사용할 수 있다. size()만큼 돈다. 배열은 length()이지만 List에선 size()메소드이다.

ArrayList

ArrayList는 List 인터페이스의 구현 클래스로 ArrayList에 객체를 추가하면 객체가 인덱스로 관리된다. 일반 배열과의 차이점은 배열은 생성할 때 크기가 고정되고 사용 중에 크기를 변경할 수 없지만, ArrayList는 자동으로 용량이 늘어난다.

String을 저장하는 ArrayList는 다음과 같이 생성할 수 있다.

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

기본 생성자로 ArrayList 객체를 생성하면 10개를 저장할 수 있는 초기 용량을 가지게 된다. 객체 수가 늘어나면 용량이 자동으로 증가하지만 개발자가 처음부터 용량을 크게 잡고 싶으면 용량의 크기를 매개값으로 받는 생성자를 이용하면 된다.

List<String> list = new ArrayList<String>(30);

처럼 말이다.

그리고 
list.add("홍길동");
String name = list.get(0); 과 같이 값을 가져오고 추가할 수 있다.

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


 

이런식으로 말이다
따라서 빈번한 객체 삭제와 삽입이 일어나는 곳에서는 ArrayList를 사용하는것은 별로 좋지 않다. 이런 경우라면 LinkedList가 더 좋다.
그러나 인덱스 검색, 맨 마지막에 객체를 추가하는 경우에는 ArrayList가 더 좋은 성능을 발휘한다.

아래는 예제 소스이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
 
 
import java.util.ArrayList;
import java.util.List;
 
public class P728 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        
        list.add("java");
        list.add("Servlet");
        list.add("jdbc");
        list.add(2"db");  //인덱스로 추가
        list.add("test");
        
        int size = list.size();
        System.out.println("객체 수 : "+size);
        System.out.println();
        
        String s = list.get(2);  //인덱스 객체 얻기
        System.out.println("2 : "+s);
        System.out.println();
        
        for(int i = 0 ; i < list.size() ; i++)
        {
            System.out.println(list.get(i));
        }
        System.out.println();
        
        list.remove(2);  //2번 객체 삭제 (db삭제)
        list.remove(2); //2번 인덱스 객체 test삭제
        for(int i = 0 ; i < list.size() ; i++)
        {
            System.out.println(list.get(i));
        }
        
    }
 
}
 
Colored by Color Scripter

 

와 같이 사용한다

Vector

Vector는 ArrayList와 동일한 내부 구조를 가지고 있다. Vector를 생성하기 위해서는 저장할 객체 타입을 타입 파라미터로 표기하고 기본 생성자를 호출하면 된다.

List<E> list = new Vector<E>();

처럼 말이다.

ArrayList와 다른 점은 Vector는 동기화된(synchronized) 메소드로 구성되어 있기 때문에 멀티 스레드가 동시에 이 메소드들을 실행할 수 없고 하나의 스레드가 실행을 완료해야만 다른 스레드를 실행시킬 수 있다.
이것은 Thread Safe(스레드에 안전) 하다고 말한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
 
import java.util.List;
import java.util.Vector;
 
class Board
{
    String subject;
    String content;
    String writer;
    
    Board(String s, String c, String w)
    {
        this.subject = s;
        this.content = c;
        this.writer = w;
    }
}
 
public class P730 {
 
    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.remove(2); //2번 인덱스 (제목3) 삭제 -> 뒤에있는게 앞으로 당겨짐
        
        for(int i = 0 ; i < list.size() ; i++)
        {
            Board b = list.get(i);
            System.out.println(b.subject+", "+b.content+", "+b.writer);
        }
 
    }
 
}
 
 
Colored by Color Scripter

 


위와 같이 사용할 수 있다.

LinkedList

LinkedList는 List 구현 클래스이므로 ArrayList와 사용 방법은 똑같지만 내부 구조는 완전 다르다.

 


연결리스트는 인접 참조를 링크해서 체인처럼 관리한다. ArrayList는 배열에 객체를 저장한다. 이것이 차이점이다.

LinkedList는 특정 인덱스의 객체를 제거하면 앞 뒤 링크만 변경되고 나머지 링크는 변겨되지 않는다. 그래서 제거 측면에선 ArrayList보다 성능이 좋다.

 


그리고 대체적으로 ArrayList보다 LinkedList가 더 빠르다 다음 예제를 보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 
 
import java.util.*;
 
public class P732 {
 
    public static void main(String[] args) {
        List<String> list1 = new ArrayList<String>();
        List<String> list2 = new LinkedList<String>();
        
        long startTime;
        long endTime;
        
        startTime = System.nanoTime();
        for(int i = 0 ; i < 10000 ; i++)
        {
            list1.add(0String.valueOf(i));
        }
        endTime = System.nanoTime();
        System.out.println("ArrayList 걸린 시간 : "+(endTime - startTime)+" ns");
        
        startTime = System.nanoTime();
        for(int i = 0 ; i < 10000 ; i++)
        {
            list2.add(0String.valueOf(i));
        }
        endTime = System.nanoTime();
        System.out.println("LinkedList 걸린 시간 : "+(endTime - startTime)+" ns");
 
    }
 
}
 
Colored by Color Scripter

결과는 다음과 같다

 

다음 장에서 Set 컬렉션을 보겠다


반응형
그리드형
Comments