Programming/Java

[Java] 자바 LinkedList 사용 방법

psychoria 2020. 11. 28. 13:00
반응형

LinkedList는 ArrayList와 함께 List를 구체화한 클래스입니다.

ArrayList에 대한 내용은 아래의 링크에서 확인 가능합니다.

2020/11/11 - [Programming/Java] - [Java] 자바 ArrayList 사용 방법

 

[Java] 자바 ArrayList 사용 방법

ArrayList는 자바에서 기본적으로 많이 사용되는 클래스입니다. ArrayList는 자바의 List 인터페이스를 상속받은 여러 클래스 중 하나입니다. 일반 배열과 동일하게 연속된 메모리 공간을 사용하며 인

psychoria.tistory.com

ArrayList는 배열을 사용해서 List를 구현한 클래스입니다.

ArrayList와 다르게 LinkedList는 각각의 노드를 연결하는 방식을 사용합니다.

아래와 같이 LinkedList를 표현할 수 있습니다.

LinkedList

ArrayList는 한 덩어리의 큰 배열을 사용하는 방식입니다.

LinkedList는 양방향 연결 리스트(Doubly Linked List)로 구현되어 있습니다.

각각의 데이터가 노드(Node)로 구성되어 연결이 되는 구조입니다.

각각의 노드는 데이터와 함께 next(다음 노드)와 prev(이전 노드) 값을 내부적으로 가지고 있습니다.

일반적으로 LinkedList의 장점은 데이터를 추가하거나 삭제하는 것이 원활하다는 점입니다.

어느 위치에서든 추가나 삭제를 할 경우 변경되는 노드만 다시 연결해주면 됩니다.

그래서 주로 ArrayList는 검색이 많은 경우에 사용하고 LinkedList는 잦은 삽입/삭제 시 사용합니다.

자바의 LinkedList를 활용하는 방법을 알아보겠습니다.

 

1. LinkedList 생성

LinkedList의 생성은 ArrayList와 크게 다르지 않습니다.

먼저 아래 구문을 추가해서 LinkedList를 사용할 수 있게 해 줍니다.

import java.util.LinkedList;

자바의 LinkedList는 아래 명령어 중 하나를 선택해서 생성 가능합니다.

LinkedList<Integer> integers1 = new LinkedList<Integer>(); // 타입 지정
LinkedList<Integer> integers2 = new LinkedList<>(); // 타입 생략 가능
LinkedList<Integer> integers3 = new LinkedList<>(integers1); // 다른 Collection값으로 초기화
LinkedList<Integer> integers4 = new LinkedList<>(Arrays.asList(1, 2, 3, 4, 5)); // Arrays.asList()

일반적으로 new LinkedList<>()와 같이 타입을 생략한 형태로 초기화를 진행합니다.

Set이나 다른 ArrayList 등을 전달해서 해당 값으로 초기화하는 것도 가능합니다.

Arrays.asList로 한 번에 여러 개의 값을 입력하면서 초기화시키는 방법도 존재합니다.

ArrayList와 다른 점은 가용량이 의미가 없기 때문에 가용량을 받는 생성자가 존재하지 않는다는 점입니다.

 

2. LinkedList 엘레멘트 추가/변경

ArrayList와 동일하게 List를 구현했기 때문에 add() 메소드로 엘레멘트를 추가할 수 있습니다.

set() 메소드로 기존에 추가된 값을 변경하는 것 역시 가능합니다.

import java.util.LinkedList;

public class LinkedListTest {
    public static void main(String[] args) {
        LinkedList<String> colors = new LinkedList<>();
        // add() method
        colors.add("Black");
        colors.add("White");
        colors.add(0, "Green");
        colors.add("Red");

        // set() method
        colors.set(0, "Blue");

        System.out.println(colors);
    }
}

add()에 인덱스를 지정하지 않으면 가장 끝에 값이 추가됩니다.

LinkedList는 값을 찾아갈 때 처음부터 순차적으로 찾아갑니다.

그래서 값 추가 시 순차적으로 탐색할 것 같지만 그렇게 동작하지는 않습니다.

내부적으로 last라는 변수가 마지막 노드를 가리키고 있어서 이 변수에 바로 연결합니다.

그렇기 때문에 끝 부분에 추가할 때는 순차적인 탐색 없이 바로  마지막에 연결이 가능합니다.

결과

Black과 White는 순차적으로 추가되고 Green이 가장 앞에 추가되면 Black, White가 한 칸씩 밀립니다.

끝 부분에 다시 Red가 추가되고 가장 앞의 값이 Green에서 Blue로 변경되며 위와 같이 결과가 출력됩니다.

 

3. LinkedList 엘레멘트 삭제

remove() 메소드로 값을 삭제할 수 있습니다.

import java.util.Arrays;
import java.util.LinkedList;

public class LinkedListTest {
    public static void main(String[] args) {
        LinkedList<String> colors = new LinkedList<>(Arrays.asList("Black", "White", "Green", "Red"));
        String removedColor = colors.remove(0);
        System.out.println("Removed color is " + removedColor);

        colors.remove("White");
        System.out.println(colors);

        colors.clear();
        System.out.println(colors);
    }
}

remove()는 인덱스를 입력하거나 값을 직접 입력해서 호출 가능합니다.

인덱스로 삭제하는 경우 값을 리턴 받을 수 있는데 삭제와 동시에 추가 작업이 필요한 경우 활용 가능합니다.

값을 전체 삭제하고 싶은 경우 clear()를 호출하면 됩니다.

 

4. LinkedList 전체 값 확인

LinkedList 전체 값을 확인하는 방법은 ArrayList와 동일합니다.

import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;

public class LinkedListTest {
    public static void main(String[] args) {
        LinkedList<String> colors = new LinkedList<>(Arrays.asList("Black", "White", "Green", "Red"));
        // for-each loop
        for (String color : colors) {
            System.out.print(color + "  ");
        }
        System.out.println();

        // for loop
        for (int i = 0; i < colors.size(); ++i) {
            System.out.print(colors.get(i) + "  ");
        }
        System.out.println();

        // using iterator
        Iterator<String> iterator = colors.iterator();
        while (iterator.hasNext()) {
            System.out.print(iterator.next() + "  ");
        }
        System.out.println();

        // using listIterator
        ListIterator<String> listIterator = colors.listIterator(colors.size());
        while (listIterator.hasPrevious()) {
            System.out.print(listIterator.previous() + "  ");
        }
        System.out.println();
    }
}

기본적인 for-each나 while 등의 반복문을 통해 순차적으로 접근이 가능합니다.

혹은 iterator를 사용할 수도 있고 listIterator를 통해 역순으로 값을 탐색할 수 있습니다.

결과

LinkedList를 ArrayList로 변경해보면 ArrayList와 동일하게 동작하는 것을 확인할 수 있습니다.

 

5. 값 존재 유무 확인

값이 존재하는지 알고 싶은 경우 contains()를 호출하면 됩니다.

indexOf()를 사용하면 값이 존재하는지 여부와 존재 시 위치를 알 수 있습니다.

import java.util.Arrays;
import java.util.LinkedList;

public class LinkedListTest {
    public static void main(String[] args) {
        LinkedList<String> colors = new LinkedList<>(Arrays.asList("Black", "White", "Green", "Red"));
        boolean contains = colors.contains("Black");
        System.out.println(contains);

        int index = colors.indexOf("Blue");
        System.out.println(index);

        index = colors.indexOf("Red");
        System.out.println(index);
    }
}

contains()는 boolean 타입을 리턴하기 때문에 존재할 때 true를 리턴합니다.

indexOf()는 존재할 때는 0부터 시작하는 인덱스를 리턴하며 존재하지 않는 경우 -1을 리턴합니다.

LinkedList는 ArrayList와 같이 List의 구현체이기 때문에 거의 동일하게 동작합니다.

그래서 ArrayList를 LinkedList로 바꾸거나 그 반대로 변환해도 대부분은 문제없이 동작합니다.

반응형