๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Java

[Java DeepDive] - List (ArrayList)

by ์ฃผ๋ฐœ2 2022. 10. 29.
๋ฐ˜์‘ํ˜•

๐Ÿ“Ž List (ArrayList)

์•ˆ๋…•ํ•˜์„ธ์š”, ์ด๋ฒˆ ์‹œ๊ฐ„์—๋Š” Java์˜ Collection Framework ์ค‘ ํ•˜๋‚˜์ธ List์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

https://www.geeksforgeeks.org/how-to-learn-java-collections-a-complete-guide/

List ์ธํ„ฐํŽ˜์ด์Šค๋Š” Collection ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์†๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Collection ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋ฐ์ดํ„ฐ์˜ ์ €์žฅ, ์‚ญ์ œ, ์‚ฝ์ž… ๊ธฐํƒ€ ๋“ฑ๋“ฑ์˜ ๋กœ์ง์„ ๋ณด๋‹ค ํŽธํ•˜๊ฒŒ API๋กœ ์ž‘์„ฑํ•˜์—ฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ณด๋‹ค ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ๋” ๋„์™€์ฃผ๋Š” ์ž๋ฐ”์˜ ์ปฌ๋ ‰์…˜ ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค.

 

์œ„ ์‚ฌ์ง„๊ณผ ๊ฐ™์ด Collection์€ collection hierarchy์˜ ์ตœ์ƒ์œ„ ์ธํ„ฐํŽ˜์ด์Šค์ด๋ฉฐ ํ•˜์œ„ ์ธํ„ฐํŽ˜์ด์Šค์ธ List, Queue, Set ๋“ฑ์ด ์ด๋ฅผ ์ƒ์†๋ฐ›๊ณ  ์žˆ๊ณ , List ์ธํ„ฐํŽ˜์ด์Šค๋Š” ArrayList, Vector, LinkedList์˜ ๊ตฌํ˜„์ฒด๋“ค์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

 

์ €๋Š” List ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„์ฒด๋กœ ๋Œ€๋ถ€๋ถ„ ArrayList ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉ์„ ํ•˜๋Š”๋ฐ์š”, ๋งค์šฐ ์˜ค๋ž˜์ „์— ์ž‘์„ฑ๋œ ๋ ˆ๊ฑฐ์‹œ์˜ ์ฝ”๋“œ๋Š” ๊ฐ€๋” Vector ํด๋ž˜์Šค๋„ ๋ดค์—ˆ๋Š”๋ฐ, ํ˜„์žฌ๋Š” ๋Œ€๋ถ€๋ถ„ ์‚ฌ์šฉํ•˜์ง€๋Š” ์•Š๋Š” ๋“ฏํ•ฉ๋‹ˆ๋‹ค.

(์™œ Vector ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”์ง€ ๊ถ๊ธˆํ•˜์‹œ๋‹ค๋ฉด ํ•ด๋‹น ํฌ์ŠคํŒ…์„ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”. ๐Ÿ˜€)

 

๊ธฐ์กด array์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ๋™์  ๋ฐฐ์—ด์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ์ฒด ์ƒ์„ฑ ์‹œ size๋ฅผ ํ• ๋‹นํ•˜์ง€ ์•Š์•„๋„ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜๋Š” ๋“ฑ์˜ ์—ฐ์‚ฐ์„ ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์•„๋ž˜ ์‚ฌ์ง„์ฒ˜๋Ÿผ ArrayList ํด๋ž˜์Šค์—๋„ ๊ต‰์žฅํžˆ ๋งŽ์€ ๋ฉ”์„œ๋“œ๋“ค์ด ์กด์žฌํ•˜๋Š”๋ฐ์š”, ArrayList ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ณผ์ •๊ณผ ์–ด๋– ํ•œ ์›๋ฆฌ๋ฅผ ํ†ตํ•ด ๋™์  ๋ฐฐ์—ด์ด ๊ฐ€๋Šฅํ•œ์ง€, ์ผ๋ถ€ ๋ฉ”์„œ๋“œ๋“ค์˜ ๋‚ด๋ถ€ ๋กœ์ง ๋“ฑ์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

 

ArrayList๋ž€?

Java 11 ๊ธฐ์ค€ ArrayList ํด๋ž˜์Šค์˜ ์ฃผ์„์—๋Š” ์œ„์™€ ๊ฐ™์ด ์ž‘์„ฑ์ด ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ฃผ์„์ด ๊ฝค๋‚˜ ๊ธธ๊ธฐ์— ์ค‘์š”ํ•œ ๋‚ด์šฉ๋งŒ ์š”์•ฝํ•ด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์‚ฌ์ด์ฆˆ ์กฐ์ ˆ์ด ๊ฐ€๋Šฅํ•œ List ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„์ฒด ๋ฐฐ์—ด
  • null์„ ํฌํ•จํ•œ ๋ชจ๋“  ์š”์†Œ๋“ค(elements)์„ ํ—ˆ์šฉ
  • ๋‚ด๋ถ€์ ์œผ๋กœ list ์ €์žฅ ์‹œ ์‚ฌ์šฉ๋˜๋Š” ๋ฐฐ์—ด์˜ ์‚ฌ์ด์ฆˆ๋ฅผ ์กฐ์ ˆํ•˜๋Š” ๋ฉ”์„œ๋“œ ์ œ๊ณต
  • n๊ฐœ์˜ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด O(n)์˜ ์‹œ๊ฐ„์ด ํ•„์š”
  • ๋งŽ์€ ์ˆ˜์˜ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์ „ ArrayList์˜ size๋ฅผ ๋Š˜๋ ค ์žฌํ• ๋‹น์— ํ•„์š”ํ•œ ๋น„์šฉ ๊ฐ์†Œ
  • ๋™๊ธฐํ™”๊ฐ€ ๋˜์ง€ ์•Š์Œ
  • ๋™๊ธฐํ™”๋˜์ง€ ์•Š์€ ์ ‘๊ทผ์„ ์˜ˆ๋ฐฉํ•˜๋ ค๋ฉด Collections.synchronizedList() ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ

 

์ถ”๊ฐ€์ ์œผ๋กœ, SynchronizedList ํด๋ž˜์Šค์˜ ๊ฒฝ์šฐ Collections ํด๋ž˜์Šค ๋‚ด๋ถ€์— static์œผ๋กœ ์„ ์–ธ์ด ๋˜์–ด ์žˆ์œผ๋ฉฐ, ๋‚ด๋ถ€ ๋กœ์ง์€ ๋Œ€๋ถ€๋ถ„ synchronized ๋ธ”๋Ÿญ์œผ๋กœ ๊ตฌํ˜„์ด ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

ArrayList Constructor

ArrayList ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๋Š” ์œ„ ์‚ฌ์ง„์ฒ˜๋Ÿผ ์ด 3๊ฐœ๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

    /**
     * Default initial capacity.
     */
    private static final int DEFAULT_CAPACITY = 10;

    /**
     * Shared empty array instance used for empty instances.
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};

    /**
     * Shared empty array instance used for default sized empty instances. We
     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
     * first element is added.
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    /**
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer. Any
     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
     * will be expanded to DEFAULT_CAPACITY when the first element is added.
     */
    transient Object[] elementData; // non-private to simplify nested class access

    /**
     * The size of the ArrayList (the number of elements it contains).
     *
     * @serial
     */
    private int size;

    /**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param  initialCapacity  the initial capacity of the list
     * @throws IllegalArgumentException if the specified initial capacity
     *         is negative
     */
    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    /**
     * Constructs a list containing the elements of the specified
     * collection, in the order they are returned by the collection's
     * iterator.
     *
     * @param c the collection whose elements are to be placed into this list
     * @throws NullPointerException if the specified collection is null
     */
    public ArrayList(Collection<? extends E> c) {
        Object[] a = c.toArray();
        if ((size = a.length) != 0) {
            if (c.getClass() == ArrayList.class) {
                elementData = a;
            } else {
                elementData = Arrays.copyOf(a, size, Object[].class);
            }
        } else {
            // replace with empty array.
            elementData = EMPTY_ELEMENTDATA;
        }
    }

 

Collection์„ ์ƒ์†๋ฐ›๋Š” List<T>๋Š” ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ํƒ€์ž…์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก Object ํƒ€์ž…์˜ ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

์œ„ ์ƒ์„ฑ์ž์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ArrayList ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๋งค๊ฐœ๋ณ€์ˆ˜์— int ๊ฐ’์„ ์„ค์ •ํ•˜๋ฉด ํ•ด๋‹น ๊ฐ’์˜ ์œ ํšจ์„ฑ ๊ฒ€์ฆ์„ ํ†ตํ•ด Object ๋ฐฐ์—ด ์ƒ์„ฑ ์‹œ length๋ฅผ ์„ค์ •ํ•˜๊ณ , ๋งค๊ฐœ๋ณ€์ˆ˜์— ์•„๋ฌด๋Ÿฐ ๊ฐ’ ์—†์ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ฉด Object ๋ฐฐ์—ด์ด ์ดˆ๊ธฐํ™”๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

(์‹ค์ œ ์œ„ ์ฝ”๋“œ์—์„œ elementData ๋ณ€์ˆ˜์˜ ์ฃผ์„์„ ํ™•์ธํ•ด๋ณด๋ฉด, ์ฒซ element๊ฐ€ added ๋  ๋•Œ size๊ฐ€ DEFAULT_CAPACITY(10) ๊ฐ’์œผ๋กœ ํ™•์žฅ๋œ๋‹ค๊ณ  ๋‚˜์™€์žˆ์Šต๋‹ˆ๋‹ค.)

List<Integer> list1 = new ArrayList<>(5); // list size = 5
List<Integer> list2 = new ArrayList<>(); // list size = 0 (์ดˆ๊ธฐํ™” ์‹œ size = 10)

 

๋”ฐ๋ผ์„œ   List<Integer> list = new ArrayList<>();  ์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค๋ฉด ์ตœ์ดˆ list์˜ size๋Š” 0์ด๋ฉฐ, ์ดํ›„ add์™€ ๊ฐ™์€ ์ž‘์—…์„ ํ•  ๋•Œ list์˜ size๊ฐ€ ํ• ๋‹น์ด ๋ฉ๋‹ˆ๋‹ค. size๊ฐ€ ์žฌํ• ๋‹น๋˜๋Š” ๊ณผ์ •์€ ์•„๋ž˜์—์„œ ์ถ”๊ฐ€์ ์œผ๋กœ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋˜ํ•œ size ๋ณ€์ˆ˜๋Š” ๋ฆฌ์ŠคํŠธ์˜ ์ „์ฒด ์‚ฌ์ด์ฆˆ๊ฐ€ ์•„๋‹Œ, ๋ฆฌ์ŠคํŠธ๊ฐ€ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” ์›์†Œ์˜ ๊ฐฏ์ˆ˜์ž…๋‹ˆ๋‹ค.

 

 

 

ArrayList.add()

ArrayList์— ์›์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋กœ ์—ฌ๋Ÿฌ ๋ฉ”์„œ๋“œ๊ฐ€ ์˜ค๋ฒ„๋กœ๋”ฉ ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.

์œ„ ์‚ฌ์ง„์—์„œ ๊ฐ€์žฅ ์œ„์— ์กด์žฌํ•˜๋Š” ๋ฉ”์„œ๋“œ์ธ add(E, Object[], int)๋Š” private ๋ฉ”์„œ๋“œ๋กœ ๋‚ด๋ถ€์—์„œ๋งŒ ํ˜ธ์ถœ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. 

๋”ฐ๋ผ์„œ ์‹ค์ œ๋กœ๋Š” ์›์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” add(E) ๋ฉ”์„œ๋“œ์™€ ํŠน์ • index์— ์›์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” add(int, E) ๋‘ ๋ฉ”์„œ๋“œ๋งŒ ๊ณต๊ฐœ API์ž…๋‹ˆ๋‹ค.

 

add() ๋ฉ”์„œ๋“œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฆฌ์ŠคํŠธ์˜ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰ ์œ„์น˜์— ์›์†Œ๋ฅผ ์‚ฝ์ž…ํ•˜๊ณ , 486๋ผ์ธ์—์„œ grow() ๋ฉ”์„œ๋“œ๊ฐ€ list์˜ size๋ฅผ ์žฌํ• ๋‹นํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.

 

 

์•„๋ž˜์™€ ๊ฐ™์€ ์ž‘์—…์„ ํ•  ๊ฒฝ์šฐ, resize๊ฐ€ ์–ด๋– ํ•œ ์‹์œผ๋กœ ์ง„ํ–‰๋˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>(10); // list์˜ ์ตœ์ดˆ size = 10

        // list์˜ size๊ฐ€ 10์ด๋ฏ€๋กœ resize ์—†์ด ์ „๋ถ€ add
        for (int i = 0; i < 8; i++) {
            list.add(i);
        }

        // i = 2์ผ ๋•Œ(size = 10) list resize
        for (int i = 0; i < 5; i++) {
            list.add(i);
        }
    }

newCapacity() ๋ฉ”์„œ๋“œ๊ฐ€ list์˜ newCapacity๋ฅผ ์„ค์ •ํ•˜๋Š”๋ฐ์š”, ๊ธฐ์กด ๋ฆฌ์ŠคํŠธ ์‚ฌ์ด์ฆˆ์˜ 50%(1.5๋ฐฐ) ๋งŒํผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

  • oldCapacity + (oldCapacity >> 1)

 

๋”ฐ๋ผ์„œ ์œ„์—์„œ ๊ธฐ์กด list์˜ ์‚ฌ์ด์ฆˆ๋Š” 10์ด๋ฏ€๋กœ, 1.5๋ฐฐ์ธ 15๋กœ ์‚ฌ์ด์ฆˆ๋ฅผ ์ฆ๊ฐ€์‹œํ‚ต๋‹ˆ๋‹ค.

์‚ฌ์ด์ฆˆ ์žฌํ• ๋‹น(10 -> 15)

์œ„ newCapacity() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ƒˆ๋กœ์šด size๋ฅผ ํ• ๋‹นํ•œ ํ›„์—๋Š” Arrays.copyOf() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ์กด Object ๋ฐฐ์—ด์ธ elementData ๋ณ€์ˆ˜๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ ์‚ฌ์ด์ฆˆ๋ฅผ ์ฆ๊ฐ€์‹œํ‚ต๋‹ˆ๋‹ค.

 

โ€ป ์ €๋Š” ํ‰์†Œ์— ํ•ญ์ƒ size ์„ค์ • ์—†์ด ArrayList๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์‚ฌ์šฉ์„ ํ–ˆ์—ˆ๋Š”๋ฐ์š”, Arrays.copyOf() ๋ฉ”์„œ๋“œ์˜ ๊ฒฝ์šฐ ๊ฒฐ๊ตญ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•˜๋Š” ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์ ์œผ๋กœ ๋น„ํšจ์œจ์ ์ผ ๋“ฏํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์–ด๋Š ์ •๋„ ์‚ฌ์ด์ฆˆ๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ์ตœ์ดˆ ๊ฐ์ฒด ์ƒ์„ฑ ์‹œ ์‚ฌ์ด์ฆˆ๋ฅผ ํ• ๋‹นํ•˜๊ณ , ์žฌํ• ๋‹นํ•˜๋Š” ์ž‘์—…์„ ์ค„์ผ ์ˆ˜ ์žˆ๋„๋ก ์Šต๊ด€์„ ๋“ค์ด๋Š”๊ฒŒ ์„ฑ๋Šฅ์—๋Š” ๋ฏธ๋น„ํ• ์ง€๋ผ๋„ ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๐Ÿ˜ƒ

 

 

 

ArrayList.set()

set() ๋ฉ”์„œ๋“œ์˜ ๊ฒฝ์šฐ index์— ์œ„์น˜ํ•œ ๊ฐ’์„ ์ƒˆ๋กœ์šด ์›์†Œ๋กœ ๋ณ€๊ฒฝํ•˜๊ณ  ๊ธฐ์กด ๊ฐ’์„ ๋ฆฌํ„ดํ•˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.

checkIndex๋Š” list์˜ ํฌ๊ธฐ๊ฐ€ ์•„๋‹Œ, ํ˜„์žฌ list์— ์กด์žฌํ•˜๋Š” ์›์†Œ์˜ ์‚ฌ์ด์ฆˆ(size)๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์œ ํšจ์„ฑ ๊ฒ€์ฆ์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

 

๋”ฐ๋ผ์„œ ์•„๋ž˜์ฒ˜๋Ÿผ ์›์†Œ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š” index์— set() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด IndexOutOfBoundException ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>(10);

        list.add(10);
        list.add(15);

        System.out.println(list.set(5, 35));
    }

 

 

 

ArrayList.remove(int index)

remove(int index) ๋ฉ”์„œ๋“œ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜์˜ index์— ์กด์žฌํ•˜๋Š” ์›์†Œ๋ฅผ ์‚ญ์ œํ•˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.

 

์œ„ ์‚ฌ์ง„์—์„œ 537๋ผ์ธ์˜ Object[] es ๋ณ€์ˆ˜ ๋ณต์‚ฌ๋Š” ์–•์€ ๋ณต์‚ฌ๋ฅผ ์ง„ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— es ๋ณ€์ˆ˜์— ์กด์žฌํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์ˆ˜์ •๋˜๋ฉด ์›๋ณธ ๋ฐฐ์—ด์ธ elementData์˜ ๋ฐ์ดํ„ฐ๋„ ํ•จ๊ป˜ ์ˆ˜์ •๋ฉ๋‹ˆ๋‹ค.

(Java์˜ ๊นŠ์€ ๋ณต์‚ฌ์™€ ์–•์€ ๋ณต์‚ฌ์— ๋Œ€ํ•œ ๋‚ด์šฉ ์ฐธ์กฐ)

 

 

์‹ค์ œ ์‚ญ์ œ๊ฐ€ ์ง„ํ–‰๋˜๋Š” ๋ฉ”์„œ๋“œ๋Š” fastRemove() ๋ฉ”์„œ๋“œ์ธ๋ฐ์š”, ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

    private void fastRemove(Object[] es, int i) {
        modCount++;
        final int newSize; // ์‚ญ์ œ ํ›„ ํ• ๋‹น๋  ๋ฆฌ์ŠคํŠธ์˜ size
        if ((newSize = size - 1) > i) // ์‚ญ์ œํ•  index๋ณด๋‹ค ํฐ ๋ฐ์ดํ„ฐ๋“ค์ด ์กด์žฌํ•  ๊ฒฝ์šฐ
            System.arraycopy(es, i + 1, es, i, newSize - i); // ์‚ญ์ œํ•  ๋ฐ์ดํ„ฐ์˜ ์šฐ์ธก ๋ฐ์ดํ„ฐ๋ฅผ ์ขŒ์ธก์œผ๋กœ 1์”ฉ ์ด๋™
        es[size = newSize] = null; // ๊ธฐ์กด์— ์กด์žฌํ•˜๋˜ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰ ์›์†Œ ์ œ๊ฑฐ
    }
    
    /* 
    	src - the source array
        srcPos - starting position in the source array
        dest - the destination array
        destPost - starting position in the destination data
        length - the number of array elements to be copied
    */
    @HotSpotIntrinsicCandidate
    public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

fastRemove() ๋ฉ”์„œ๋“œ๋Š” ๊ธฐ์กด elementData ๋ณ€์ˆ˜๋ฅผ ๋ณต์‚ฌํ•œ Object[] es ๋ณ€์ˆ˜๋กœ ์ž‘์—…์„ ํ•˜๋Š”๋ฐ์š”, ์‚ญ์ œํ•  ์›์†Œ ์ดํ›„์˜ index๋ฅผ ์ขŒ์ธก์œผ๋กœ 1์”ฉ ์ด๋™ํ•œ ํ›„ ๋งˆ์ง€๋ง‰ ์›์†Œ๋Š” ์‚ญ์ œ(null ์ฒ˜๋ฆฌ)ํ•ฉ๋‹ˆ๋‹ค.

 

์œ„ ๋กœ์ง์€ ์ฝ”๋“œ๋งŒ ๋ดค์„ ๋•Œ ์ •ํ™•ํžˆ ํŒŒ์•…์ด ๋˜์ง€ ์•Š์•„ ์‹ค์ œ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>(10);

        list.add(10);
        list.add(15);
        list.add(20);
        list.add(25);
        list.add(30);

        list.remove(1);
    }

5๊ฐœ์˜ ์›์†Œ๋ฅผ ์‚ฝ์ž… ํ›„ ์ฒซ ๋ฒˆ์งธ ์ธ๋ฑ์Šค(๊ฐ’์€ 15)๋ฅผ ์‚ญ์ œํ•˜๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

 

์œ„ ์ฝ”๋“œ์˜ System.arrayCopy() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฐ’์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • srcPos = 2 (๋ณต์‚ฌํ•  array์˜ ์‹œ์ž‘ index)
  • destPos = 1 (๋ชฉ์ ์ง€ ๋ฐ์ดํ„ฐ์˜ ์‹œ์ž‘ index)
  • length = 3 (๋ณต์‚ฌํ•  ์›์†Œ์˜ ์ˆ˜)

๋”ฐ๋ผ์„œ, ๋‘ ๋ฒˆ์งธ ์ธ๋ฑ์Šค๋ถ€ํ„ฐ ์ด 3๊ฐœ๋งŒํผ ๋ณต์‚ฌ๋ฅผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— 20, 25, 30์˜ ์›์†Œ๋ฅผ ์ขŒ์ธก์œผ๋กœ 1์”ฉ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

์œ„ ์‚ฌ์ง„์—์„œ ์ขŒ์ธก์ด ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ์ด๊ณ , ์šฐ์ธก์€ System.arrayCopy() ๋ฉ”์„œ๋“œ๊ฐ€ ์ง„ํ–‰๋œ ํ›„ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ๋‚œ ํ›„ es[size = newsize] = null; ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ๋งˆ์ง€๋ง‰ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ฑฐํ•˜๋ฉด ์œ„์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค.

 

 

 

ArrayList.remove(Object o)

remove() ๋ฉ”์„œ๋“œ๋Š” ์›์†Œ๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์•„ ํ•ด๋‹น ์›์†Œ๋ฅผ ์‚ญ์ œํ•˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.

์ฃผ์„์„ ์‚ดํŽด๋ณด๋ฉด ๋ฆฌ์ŠคํŠธ์— ์›์†Œ๊ฐ€ ์กด์žฌํ•˜๋ฉด ์ตœ์ดˆ ๋ฐœ๊ฒฌ๋˜๋Š” ๊ฐ’์„ ์‚ญ์ œํ•˜๊ฑฐ๋‚˜, ์กด์žฌํ•˜์ง€ ์•Š๋‹ค๋ฉด ์•„๋ฌด๋Ÿฐ ๋ณ€๊ฒฝ๋„ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์‚ญ์ œ๊ฐ€ ๋˜๋ฉด true๋ฅผ, ์•„๋ฌด๋Ÿฐ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚˜์ง€ ์•Š์œผ๋ฉด false๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

 

์‚ญ์ œํ•˜๋Š” ๋กœ์ง์€ list๋ฅผ ์ˆœํšŒํ•˜๋ฉด์„œ ์‚ญ์ œํ•˜๊ณ ์ž ํ•˜๋Š” ์›์†Œ๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ํƒ์ƒ‰ํ•œ ํ›„ ์กด์žฌํ•˜๋ฉด ์œ„์—์„œ ์‚ดํŽด๋ดค๋˜ remove(int index) ๋ฉ”์„œ๋“œ์™€ ๋™์ผํ•˜๊ฒŒ fastRemove() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ํ›„ true๋ฅผ, ์›์†Œ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด false๋ฅผ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค.

 

โ€ป ์ฃผ์˜ํ•  ์ ์€ List ํƒ€์ž…์ด Integer์ผ ๊ฒฝ์šฐ, index๋ฅผ ์˜๋ฏธํ•˜๋Š” remove(int index) ๋ฉ”์„œ๋“œ์™€ ์ค‘๋ณต๋˜๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜์ฒ˜๋Ÿผ Object ํƒ€์ž…์œผ๋กœ ํ˜•๋ณ€ํ™˜์„ ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>(10);

        list.add(10);
        list.add(15);
        list.add(20);
        list.add(25);
        list.add(30);

        System.out.println(list.remove((Object) 15)); // true
        System.out.println(list.remove((Object) 15)); // false
        System.out.println(list.remove((Object) 22)); // false
    }

 

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€