1+ package io .github .gunkim .datastructure .list ;
2+
3+ import java .util .Arrays ;
4+ import java .util .Collection ;
5+ import java .util .Iterator ;
6+ import java .util .List ;
7+ import java .util .ListIterator ;
8+ import java .util .NoSuchElementException ;
9+
10+ public class ArrayList <T > implements List <T > {
11+ private static final int DEFAULT_ARRAY_SIZE = 10 ;
12+ private static final int DEFAULT_ARRAY_EXPANSION_FACTOR = 2 ;
13+ private static final int INDEX_NOT_FOUND = -1 ;
14+
15+ private T [] array ;
16+ private int size ;
17+
18+ @ SuppressWarnings ("unchecked" )
19+ public ArrayList () {
20+ array = (T []) new Object [DEFAULT_ARRAY_SIZE ];
21+ }
22+
23+ @ Override
24+ public boolean add (T data ) {
25+ expandArrayIfFull (size * DEFAULT_ARRAY_EXPANSION_FACTOR );
26+ addData (data );
27+ return true ;
28+ }
29+
30+ @ Override
31+ public void add (int index , T element ) {
32+ addAll (index , List .of (element ));
33+ }
34+
35+ @ Override
36+ public boolean addAll (Collection <? extends T > collection ) {
37+ addAll (size , collection );
38+ return true ;
39+ }
40+
41+ @ Override
42+ public boolean addAll (int index , Collection <? extends T > collection ) {
43+ if (index > size || index < 0 ) {
44+ throw new IndexOutOfBoundsException ();
45+ }
46+
47+ int requiredSize = (size + collection .size ()) - (size - index );
48+ if (requiredSize >= array .length ) {
49+ expandArrayIfFull (requiredSize * DEFAULT_ARRAY_EXPANSION_FACTOR );
50+ }
51+
52+ System .arraycopy (array , index , array , index + collection .size (), collection .size ());
53+ size += collection .size ();
54+
55+ var i = index ;
56+ for (T element : collection ) {
57+ array [i ++] = element ;
58+ }
59+
60+ return true ;
61+ }
62+
63+ @ Override
64+ public boolean remove (Object o ) {
65+ var index = indexOf (o );
66+ if (index == INDEX_NOT_FOUND ) {
67+ return false ;
68+ }
69+
70+ remove (index );
71+
72+ return true ;
73+ }
74+
75+
76+ @ Override
77+ public T remove (int index ) {
78+ if (index >= size || index < 0 ) {
79+ throw new IndexOutOfBoundsException ();
80+ }
81+ var beforeValue = array [index ];
82+ System .arraycopy (array , index + 1 , array , index , size - index );
83+ return beforeValue ;
84+ }
85+
86+ @ Override
87+ public boolean removeAll (Collection c ) {
88+ for (Object o : c ) {
89+ remove (o );
90+ }
91+ return true ;
92+ }
93+
94+ @ Override
95+ public void clear () {
96+ Arrays .fill (array , null );
97+ size = 0 ;
98+ }
99+
100+ @ Override
101+ public T get (int index ) {
102+ if (index >= size || index < 0 ) {
103+ throw new IndexOutOfBoundsException ();
104+ }
105+
106+ return array [index ];
107+ }
108+
109+ @ Override
110+ public T set (int index , T element ) {
111+ if (index >= size || index < 0 ) {
112+ throw new IndexOutOfBoundsException ();
113+ }
114+
115+ var beforeValue = array [index ];
116+ array [index ] = element ;
117+
118+ return beforeValue ;
119+ }
120+
121+ @ Override
122+ public int indexOf (Object o ) {
123+ for (int i = 0 ; i < array .length ; i ++) {
124+ var element = array [i ];
125+
126+ if (element .equals (o )) {
127+ return i ;
128+ }
129+ }
130+ return INDEX_NOT_FOUND ;
131+ }
132+
133+ @ Override
134+ public int lastIndexOf (Object o ) {
135+ for (int i = array .length - 1 ; i >= 0 ; i --) {
136+ var element = array [i ];
137+
138+ if (element .equals (o )) {
139+ return i ;
140+ }
141+ }
142+ return INDEX_NOT_FOUND ;
143+ }
144+
145+ @ Override
146+ public int size () {
147+ return size ;
148+ }
149+
150+ @ Override
151+ public boolean isEmpty () {
152+ return size == 0 ;
153+ }
154+
155+ @ Override
156+ public boolean contains (Object o ) {
157+ return indexOf (o ) != INDEX_NOT_FOUND ;
158+ }
159+
160+ @ Override
161+ public boolean containsAll (Collection c ) {
162+ for (Object o : c ) {
163+ if (!contains (o )) {
164+ return false ;
165+ }
166+ }
167+ return true ;
168+ }
169+
170+ @ Override
171+ public Iterator <T > iterator () {
172+ return new MyIterator ();
173+ }
174+
175+ @ Override
176+ @ SuppressWarnings ("unchecked" )
177+ public T [] toArray () {
178+ var arr = new Object [size ];
179+
180+ System .arraycopy (array , 0 , arr , 0 , size );
181+
182+ return (T []) arr ;
183+ }
184+
185+ @ Override
186+ @ SuppressWarnings ("unchecked" )
187+ public T [] toArray (Object [] a ) {
188+ return (T []) new Object [0 ];
189+ }
190+
191+ @ Override
192+ public String toString () {
193+ return "MyArrayList{" +
194+ "array=" + Arrays .toString (toArray ()) +
195+ ", size=" + size +
196+ '}' ;
197+ }
198+
199+ @ Override
200+ public ListIterator listIterator () {
201+ throw new RuntimeException ("Not implemented" );
202+ }
203+
204+ @ Override
205+ public ListIterator listIterator (int index ) {
206+ throw new RuntimeException ("Not implemented" );
207+ }
208+
209+ @ Override
210+ public List <T > subList (int fromIndex , int toIndex ) {
211+ throw new RuntimeException ("Not implemented" );
212+ }
213+
214+ @ Override
215+ public boolean retainAll (Collection c ) {
216+ throw new RuntimeException ("Not implemented" );
217+ }
218+
219+ private void addData (T data ) {
220+ array [size ++] = data ;
221+ }
222+
223+ @ SuppressWarnings ("unchecked" )
224+ private void expandArrayIfFull (int sizeUp ) {
225+ if (array .length == size ) {
226+ var originalArray = array ;
227+ var newArray = new Object [sizeUp ];
228+
229+ System .arraycopy (originalArray , 0 , newArray , 0 , originalArray .length );
230+
231+ array = (T []) newArray ;
232+ }
233+ }
234+
235+ private class MyIterator implements Iterator <T > {
236+ private int currentIndex = 0 ;
237+
238+ @ Override
239+ public boolean hasNext () {
240+ return currentIndex < size ;
241+ }
242+
243+ @ Override
244+ public T next () {
245+ if (!hasNext ()) {
246+ throw new NoSuchElementException ();
247+ }
248+ return array [currentIndex ++];
249+ }
250+ }
251+ }
0 commit comments