반응형
Vector or ArrayList -- which is better and why?

Sometimes Vector is better; sometimes ArrayList is better; sometimes you don't want to use either. I hope you weren't looking for an easy answer because the answer depends upon what you are doing. There are four factors to consider:

Vector가 더 나을 때도 있고, ArrayList가 더 나을 때도 있다. 또는, 둘 다 사용하길 원하지 않을 수도 있다. 나는 당신이 쉬운 답을 찾으려 하지 않기를 바란다. 왜냐하면 답은 당신이 하는 방식에 따라 달라질 테니까 말이다. 고려해야 할 다음 4가지 요인이 있다.

API
In The Java Programming Language (Addison-Wesley, June 2000) Ken Arnold, James Gosling, and David Holmes describe the Vector as an analog to the ArrayList. So, from an API perspective, the two classes are very similar. However, there are still some major differences between the two classes.

The Java Programming Language 에 Ken Arnold, James Gosling, and David Holmes는 Vector를 ArrayList의 상사형(서로 형이 같은)이라고 묘사한다. 그래서 API를 보면 두 개의 클래스는 매우 유사하다. 하지만 여전히 두 클래스 사이에는 중요한 차이점이 존재한다.

Synchronization
Vectors are synchronized. Any method that touches the Vector's contents is thread safe. ArrayList, on the other hand, is unsynchronized, making them, therefore, not thread safe. With that difference in mind, using synchronization will incur a performance hit. So if you don't need a thread-safe collection, use the ArrayList. Why pay the price of synchronization unnecessarily?

Vector는 동기화 되어있다. Vector의 내용에 접근하는 어떤 메소드는 thread safe1 하다. 반면에ArrayList는 동기화 되어있지 않다. 그러므로 ArrayList로 만들어진 것은 thread safe하지 않다. thread safe가 필요하지 않는데도 동기화를 사용하면, performance hit2 을 초래할 것이다. 만약 당신이 thread-safe 컬렉션을 필요로 하지 않는다면, ArrayList를 사용하라. 왜 불필요하게 synchronization의 비용을 지불하려 하는가?

Data growth
Internally, both the ArrayList and Vector hold onto their contents using an Array. You need to keep this fact in mind while using either in your programs. When you insert an element into an ArrayList or a Vector, the object will need to expand its internal array if it runs out of room. A Vector defaults to doubling the size of its array, while the ArrayList increases its array size by 50 percent. Depending on how you use these classes, you could end up taking a large performance hit while adding new elements. It's always best to set the object's initial capacity to the largest capacity that your program will need. By carefully setting the capacity, you can avoid paying the penalty needed to resize the internal array later. If you don't know how much data you'll have, but you do know the rate at which it grows, Vector does possess a slight advantage since you can set the increment value.

내부적으로 ArrayList와 Vector둘 다 Array를 사용하면서 그들의 컨텐츠를 유지한다. 당신은 당신의 프로그램에서 둘 중에 하나를 사용하는 동안에 이 사실을 명심할 필요가 있다. ArrayList 또는 Vector의 요소를 삽입할 때, 만약 그 용량을 다 써버린다면, object는 자신의 내부array를 확장시킬 필요가 있다. Vector는 자신의 array 크기의 배수만큼 초기화 한다. 반면에 ArrayList는 자신의 array 크기의 50%만큼 씩 증가시킨다. 당신이 이러한 클래스들을 사용하는데 의존한다면, 당신은 새로운 요소들을 추가하는 동안에 결국 대량의 performance hit을 초래할 것이다. 당신의 프로그램이 필요로 하는 최대의 용량만큼 객체의 초기화 용량을 정하는 것이 최선이다. 신중하게 용량을 셋팅해라. 그러면, 당신은 후에 내부 array를 resize하는데 필요한 요금 지불을 피할 있다. 만약 당신이 얼마나 데이터를 가지게 될지는 모른지만, 그것이 증가하는 비율을 안다면 , Vector는 당신이 증가값을 정할 수 있기 때문에 근소한 이점을 가진다.(아래 글 참조)

Usage patterns
Both the ArrayList and Vector are good for retrieving elements from a specific position in the container or for adding and removing elements from the end of the container. All of these operations can be performed in constant time -- O(1). However, adding and removing elements from any other position proves more expensive -- linear to be exact: O(n-i), where n is the number of elements and i is the index of the element added or removed. These operations are more expensive because you have to shift all elements at index i and higher over by one element. So what does this all mean?

ArrayList와 Vector 둘 다 컨테이너의 특정 위치에서 요소들을 되찾거나, 컨테이너의 끝에서 요소들을 더하거나, 삭제할때 유용하다. 이러한 모든 기능은 constant time-- O(1)(맨 아래 글을 참조하세요.)에서 수행될 수 있다. 하지만, 어떤 다른 자리에서 요소들을 더하거나 제거하는 것은 더 많은 비용을 발생시킨다. 정확하게 직선위에서..-ㅅ-?? n은 요소들의 수이고, i는 더해지거나 제거되는 요소의 인덱스다. 당신이 하나의 요소에 때문에 모든 요소들을 index i에 그 이상의 값으로 옮겨야만 하기때문에 이러한 operation들은 더 많은 비용이 든다. 그렇다면 이러한 것은 무엇을 의미하는가?

It means that if you want to index elements or add and remove elements at the end of the array, use either a Vector or an ArrayList. If you want to do anything else to the contents, go find yourself another container class. For example, the LinkedList can add or remove an element at any position in constant time -- O(1). However, indexing an element is a bit slower -- O(i) where i is the index of the element. Traversing an ArrayList is also easier since you can simply use an index instead of having to create an iterator. The LinkedList also creates an internal object for each element inserted. So you have to be aware of the extra garbage being created.

그것은 만약 당신이 요소들을 검색하거나, Array의 끝에서 요소들을 더하거나 제거하기를 원한다면 Vector나 ArrayList 둘 중에 하나를 사용하라는 것을 의미한다. 만약 당신이 그 밖의 무엇인가를 하길 원한다면, 스스로 또다른 콘테이너 클래스를 찾아라. 예를들어, LikedList는 constant time -- O(1) 에서 어디서든지 요소를 더하거나 제거할 수 있다. 하지만, 요소를 찾는 것은 조금 느리다. ArrayList을 왔다갔다 하는 것은 또한 당신이 iterator을 만들어야만 하는 대신에 인덱스를 더욱 간편하게 사용할 수 있기 때문에 더 쉽다. LinkedList는 또한 삽인된 각각의 요소에 대한 내부 객체를 만든다. 그래서 당신은 만들어지는 여분의 garbage에 대해서 알아야만 한다.

Finally, in "PRAXIS 41" from Practical Java (Addison-Wesley, Feb. 2000) Peter Haggar suggests that you use a plain old array in place of either Vector or ArrayList -- especially for performance-critical code. By using an array you can avoid synchronization, extra method calls, and suboptimal resizing. You just pay the cost of extra development time.

마지막으로 Practical Java "PRAXIS 41"에 Peter Haggar은 당신이 Vector 나 ArrayList 둘 중의 하나 대신에 명백한 old array를 사용할 것을 제안한다. -특히 비판적인 코드에서??? array를 사용함으로써, 당신은 동기화, 여분의 메소드를 부르는 것. 그리고 차선의 resizing을 피할 수 있다. 당신은 단지 여분의 개발시간비용만을 지불할 것이다.

어허...ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 해석하는데 무지 오래걸렸습니다..-ㅅ-
하지만 해놓고보니.. 뿌듯하군요.
그러니까, ArrayList와 Vector의 가장 큰 차이점으로 꼽을 수 있는 것은 "동기화"입니다.
하지만, 여러 문서를 찾아보니 ArrayList가 동기화되는 Vector보다 퍼포먼스가 좋다는
이야기가 많더라구요. 즉, 적절한 곳에 ArrayList를 동기화 해서 사용하는게 더 좋다는 의견이
많았습니다. 저는 아직 Vector를 한번 더 사용해 본적도 없고, 개발 경험이 거의 전무해서
잘 와닿지는 않고, 공감할래야 공감할 수도 없지만... 이해했다는 것에 만족해야겠습니다.
-ㅅ-... 화잇힝...ㅋㅋ

Vector - Data Growth 추가사항(API문서)
The Vector class implements a growable array of objects. Like an array, it contains components that can be accessed using an integer index. However, the size of a Vector can grow or shrink as needed to accommodate adding and removing items after the Vector has been created.

Vector 클래스는, 오브젝트의 가변장 배열을 구현합니다. 여기에는 배열과 같이, 정수 인덱스를 사용해 액세스 할 수 있는 요소가 격납되고 있습니다. 그러나, Vector 의 사이즈는 작성 후에 추가 및 삭제된 객체를 격납할 수 있듯이 필요에 따라서 늘리거나 줄이거나 할 수가 있습니다.

Each vector tries to optimize storage management by maintaining a capacity and a capacityIncrement. The capacity is always at least as large as the vector size; it is usually larger because as components are added to the vector, the vector's storage increases in chunks the size of capacityIncrement. An application can increase the capacity of a vector before inserting a large number of components; this reduces the amount of incremental reallocation.

각 Vector 는,capacity (용량)와 capacityIncrement (증가량)를 관리하는 것으로써 기억 관리를 최적화하려고 합니다.capacity 는 항상 Vector 의 요소수에 가까운 값이며, 통상은 요소수부터 커집니다. 이것은 Vector 에 요소가 더해질 때, Vector 의 기억 영역은 capacityIncrement 만 늘려지기 때문입니다. 많은 요소를 삽입하기 전에 애플리케이션으로 용량을 필요한 값으로 설정해 두면, 메모리의 재배분의 회수를 줄일 수가 있습니다.


Constant Time : TimeComplexity 단위의 하나로, 입력 n의 크기의 증감과 상관 없이 주어진 문제를 푸는데에 걸리는 시간(See DiscreteTime)이 동일한 것을 말하며, BigONotation으로는 O(1)이라고 표시합니다. 예를 들어 배열의 i번째 원소를 가져오는 연산은 배열의 크기 n과 무관하게 동일한 속도로 수행됩니다.
TimeComplexity : 시간 복잡도. Automaton으로 어떠한 문제를 풀기 위해 소모되는 이산시간(See DiscreteTime)의 크기를 말합니다.
Automaton : 물리적/논리적인 자동기계-ㅅ-.. 라는데... 그냥 컴퓨터로 이해하겠습니다.
BigONotation : 아.. 이건 진짜 모르겠습니다-ㅅ-;;;;;;;;;;;;;;;;;;;;;;; 살려주세요 ㅠ
출처 : http://jania.pe.kr/wiki/jwiki/moin.cgi
반응형
일단, LikedList에 대하여 살펴봐야겠군요.
1학년때 교재로 썼던 <<Absolute Java>>를 보면,
Liked Data Strutures라는 챕터가 있습니다.
아래는 Introduction에 있는 내용인데요. 야심차게 해석을..-ㅅ-;

A linked data structure consists of capsules of data, known as nodes, that are connected via things called links. These links can be viewed as arrows and thought of as ane-way passages from one node to another. The simplest kind of liked data structure consists of a single chain of nodes, each connected to the next by a link; this is known as a linked list.

linked data structure은 node라고 알려져 있는 data의 캡슐로 구성되어 있다.
이는 link라 불리우는 것을 매개로 하여 연결된다. 이러한 link는 하나의 node에서 다른 node로 가는 한방향의 통로로 간주 될 수 있다. (화살표로 표시된다.)
linked data structure의 가장 간단한 종류는 일련의 단일 node로 구성되어 있다.
각각은 다음 link까지 연결된다. 이러한 것을 linked list라 한다.

워... 큰일났다... 무지하게.. 난해하네요..-ㅅ-;
이걸 이해하려면.. 자료구조를 공부해야겠는데요...-_ㅠ

그러는 와중에.. 저의 구세주 zerry82님께서 등장하셨습니다.!!!
친절한 설명 감사드립니다 ^ ^
그림으로 표현해보면,

사용자 삽입 이미지

멋진 것이었군요+ㅁ+
그렇다면, ArrayList와 LinkedList의 차이점 쯤은 금방 알 수 있겠군요.

여러가지 문서가 있었는데.. '속도'부분에서 많은 논란이 있더라구요.
일단은 괜찮은 영어문서가 있길래.. 무턱대고 해석 들어갔습니다-ㅅ-;

There are two general-purpose List implementations in the Collection Framework, ArrayList and LinkedList, which of the two List implementations you use depends on your specific needs. If you need to support random access, without inserting or removing elements from any place to other than the end, then ArrayList offers you the optimal collection, the LinkedList class provides uniformly named methods to get, remove and insert an element at the beginning and end of the list.

콜렉션 프레임워크에는 ArrayListLinkedList를 병용하는 List implementations1 이 있다.
이것은 당신이 특정한 필요에 의해서 사용하는 두가지 List implementations이다.
만약 당신이 끝 이외에 어디에서든지 요소를 제거하거나 삽입하는 것 없이 자유롭게 접근하는 것이 필요하다면, 그땐, ArrayList가 당신에게 최적의 콜렉션을 제공한다.
LinkedList
클래스는 리스트의 처음과 끝에 요소을 제거하거나 삽입하는 메소드를 제공한다.

Each ArrayList instance has a capacity. The capacity is the size of the array used to store the elements in the list. It is always at least as large as the list size. As elements are added an ArrayList, its capacity grows automatically. The details of the growth policy are not specified beyond the fact that adding an element has constant amortized time cost.

각각의 ArrayList 인스턴스는 용량을 가지고 있다. 용량은 리스트에서 요소들을 저장하기 위해 사용되는 array 크기이고, 언제나 적어도 리스트의 크기만큼 커야한다. 요소들이 ArrayList 추가될 , 그것의 용량은 자동으로 증가한다. 증가방법에 대한 자세한 사항은 지속적으로 상환되는 시간비용을 가진 요소를 더하는 사실 이외에는 기술되어지지 않는다.

An application can increase the capacity of an ArrayList instance before adding a large number of elements using the ensureCapacity operation. This may reduce the amount of incremental reallocation.

에플리케이션은 ensureCapacity 기능을 사용하여 많은 수의 요소들을 추가하기 전에ArrayList 인스턴스의 용량을 증가시킬 있다.
이러한 것은 많은량의 재배치 증가를 감소시킨다.

그렇지요!! 정리를 해보자면,

more..


출력은 다음과 같습니다.
                    [뎅뎅이, 붉은돼지, zerry, Real Study, java, jsp, html/css]
                    첫번째 : 뎅뎅이
                    [Real Study, 뎅뎅이, 붉은돼지, zerry, java, jsp, html/css]
                    [Real Study, 뎅뎅이, 붉은돼지, zerry, java, jsp]
                    첫번째 : Real Study

소스코드를 보면 아시겠지만, addFirst()라던지.. removeLast()라던지
LinkedList에는 ArrayList의 메소드 이외에 추가, 삭제하는 메소드가 추가되어있습니다.
(API 참조 !!)
제가 작성한 코드는 간단한 코드라 아직까지는 그 중요성이 와닿지 않지만,
이러한 것들이 모이다보면..-ㅅ-;
LinkedList가 ArrayList보다 훨씬 빠른성능을 보여주겠지요??
(스택,큐,양방향큐 를 만들 때 편리하게 사용된다는데요. 이건 뭔지 잘 몰라서-ㅅ-;)

< 출처: http://happystory.tistory.com >

+ Recent posts