-
[Java Study] - LinkedList , Queue in Collection frameworkJava 2021. 9. 26. 16:23
LinkedList는 java Collection framework에서 List 인터페이스를 구현한 클래스로 List 인터페이스로 사용 가능한 컬렉션입니다.
LinkedList에는 Node로 불리는 요소가 있는데요
요소는 데이터와 다음 Node의 주소값 2가지로 나눌 수 있습니다.
- Head 는 오직 리스트의 첫번째 요소 주소값 만 가지고 있습니다.
- 리스트의 마지막 요소는 노드의 주소 값 부분이 null 입니다.
이렇게 이전요소와 다음요소가 직접적으로 연결된 데이터 구조를 linear data strucure(선형 자료구조) 라고 합니다.
LinkedList 는 대표적인 선형 자료구조 중 하나입니다.
위의 예시는 타입을 Integer 으로 지정 했을 때이다.
데이터 값은 모두 Integer
메서드
LinkedList 에서 메서드 중 일부를 살펴보면
- boolean add(Object o ) : 리스트의 마지막 부터 해당 요소를 추가한다.
- void add(int index , Object element) : 지정한 index 위치에 요소를 추가한다.
- void addFirst(Objct o) : 리스트의 첫번째에 해당 요소를 추가한다.
- void addLast(Object o) : 리스트의 제일 마지막에 요소를 추가한다.
- int size() : 리스트에 들어 있는 요소 개수를 반환 한다.
- boolean contains(Object o) : 리스트에 해당 요소가 있으면 true , 그렇지 않으면 false 를 반환한다.
- boolean remove(Object o) : 리스트에 해당 요소를 삭제한다.
- int indexOf(Object o) : 해당 요소가 리스트의 몇 번째 인덱스에 있는지 반환한다. 만약 없으면 -1을 반환한다.
※ add(Object o) , addLast(Object o) 메서드의 차이점은 무엇일 까?
두 메서드는 동일한 기능을 수행하는데 ,
차이점은 add(Object o) 는 수행이 잘 되었는지 boolean 값을 반환하고,
addLast(Object o)는 아무 값도 반환하지 않는다.
또 하나는,
add(Object o) 는 Collection 인터페이스 안에 선언되어 있기 때문에 ,
List 인터페이스를 구현한 클래스 와 Queue 인터페이스를 구현한 클래스에서 전부 사용 할 수 지만
addLast(Object o) 는 Deque interface 안에 선언되어 있기 때문에
Deque interface를 구현한 클래스만 사용할 수 있다.
즉 사용 범위가 다른 것이다.
reference
https://www.codekru.com/java/linked-list-addfirst-and-addlast-methods
구현 해보기
#1
#2
public class ListNode<E> { private int size; private Node head; class Node { E data; Node next; public Node(E data) { this.data = data; this.next = null; } public Node(E data, Node next) { this.data = data; this.next = next; } } public ListNode() { head = null; size = 0; } boolean add(E data) { // list가 비어 있으면 head node 에 첫 번째 node 값을 할당한다. if (head == null) { head = new Node(data); } else { // list에 값이 있다면 Node node = head; // 리스트 연결을 위한 임시 노드 while (node.next != null) { // 리스트의 마지막 까지 반복 node = node.next; } node.next = new Node(data); } size++; return true; } void add(int index, E data) { if (index == 0) { head = new Node(data, head); } else { Node node = getNode(index-1); node.next = new Node(data , node.next); } size++; } Node getNode(int index) { if (index < 0 || index >= size) { throw new IndexOutOfBoundsException(); } Node node = head; for (int i = 0; i < index; i++) { node = node.next; } return node; } }
public static void main(String[] args) { ListNode listNode = new ListNode(); listNode.add(11); listNode.add(22); listNode.add(33); }
Queue
Queue 인터페이스는 FIFO(First-In First-Out) 자료구조에서 사용되는 메서드를 정의하고 있다.
위에서 살펴본 LinkedList가 Queue 인터페이스를 구현한 대표적인 클래스다.
메서드 설명 boolean add(E e) queue 에 해당 원소를 넣는다. 성공하면 true를 리턴하고 실패 하면 예외가 발생한다. boolean offer(E e) queue 에 해당 원소를 넣는다. 성공하면 true를 리턴하고 실패 하면 false 를 리턴한다. E element() queue 의 head를 리턴한다. 만약 queue가 비어 있다면 예외가 발생한다. E peek() queue 의 head를 리턴한다. 만약 queue가 비어 있다면 null 을 리턴한다. E remove() queue 의 head를 리턴하고 , queue에서 제거한다. 만약 queue가 비어 있다면 예외가 발생한다. E poll() queue 의 head를 리턴하고, queue에서 제거한다. 만약 queue가 비어 있다면 null을 리턴한다. boolean isEmpty() queue 가 비어있는지 확인 한다. 비어있으면 true , 데이터가 있으면 false 를 리턴 한다. public class Example { public static void main(String[] args) { // 정수 값 담는 queue 생성 Queue<Integer> queue = new LinkedList<>(); queue.add(10); // 정수 10을 queue 에 넣는다. queue.add(20); // 정수 20을 queue 에 넣는다 queue.add(30); // 정수 30을 queue 에 넣는다. queue.add(40); queue.add(50); queue.add(60); queue.add(70); System.out.println(queue.element()); // 10 을 반환 System.out.println(queue.peek()); // 10을 반환 System.out.println(queue.remove()); // 10울 반환하고 10을 queue 에서 제거한다. System.out.println(queue.peek()); //위에서 10을 제거 했기 때문에 20을 반환 System.out.println(queue.poll()); // 20을 반환하고 20을 queue 에서 제거한다. System.out.println(queue.isEmpty()); // queue에 data 가 있으므로 false; } }
예외가 발생하는 경우 - element() , remove()
public class Example { public static void main(String[] args) { // 정수 값 담는 queue 생성 Queue<Integer> queue = new LinkedList<>(); System.out.println(queue.element()); // java.util.NoSuchElementException 발생 } }
NoSuchElementException 발생 (Runtime Exception)
public class NoSuchElementException extends RuntimeException { private static final long serialVersionUID = 6769829250639411880L; /** * Constructs a {@code NoSuchElementException} with {@code null} * as its error message string. */ public NoSuchElementException() { super(); } /** * Constructs a {@code NoSuchElementException}, saving a reference * to the error message string {@code s} for later retrieval by the * {@code getMessage} method. * * @param s the detail message. */ public NoSuchElementException(String s) { super(s); } }
public class Example { public static void main(String[] args) { // 정수 값 담는 queue 생성 Queue<Integer> queue = new LinkedList<>(); System.out.println(queue.remove()); //java.util.NoSuchElementException 발생 } }
null 을 반환하는 경우 - peek() , poll()
public class Example { public static void main(String[] args) { // 정수 값 담는 queue 생성 Queue<Integer> queue = new LinkedList<>(); System.out.println(queue.peek()); // null 반환 } }
public class Example { public static void main(String[] args) { // 정수 값 담는 queue 생성 Queue<Integer> queue = new LinkedList<>(); System.out.println(queue.poll()); // null 반환 } }
양방향 queue 에 해당하는 LinkedList
위에서 살펴본 queue 는 FIFO 자료구조로 데이터를 넣고 제거하는 것이 한쪽으로만 가능했다. (단 방향)
이에 비해 LinkedList 는 양방향으로 데이터를 넣고 제거하는 것이 가능하다.
그림으로 살펴보면
위에서 살펴본 queue 메서드를 포함하여 LinkedList 클래스에 추가 된 것이
메서드 설명 addFirst() queue 의 시작 지점에 해당 요소를 넣는다. addLast() queue 의 끝 지점에 해당 요소를 넣는다. peekFirst() queue 의 시작 지점에 있는 해당 요소를 리턴한다. peekLast() queue 의 끝 지점에 해당 요소를 리턴한다. pollFirst() queue 의 시작 지점에 있는 해당 요소를 리턴하고 , 요소를 삭제한다. pollLast() queue 의 끝 지점에 있는 해당 요소를 리턴하고 , 요소를 삭제한다. 이다.
public class Example { public static void main(String[] args) { LinkedList<Integer> queue = new LinkedList<>(); queue.add(10); queue.add(20); queue.add(30); queue.addFirst(40); // LinkedList 시작점에 원소를 추가 queue.add(50); System.out.println(queue); // [40 , 10 , 20 ,30 ,50] System.out.println(queue.peekLast()); // 50 System.out.println(queue.peekFirst()); // 40 } }
public class Example { public static void main(String[] args) { LinkedList<Integer> queue = new LinkedList<>(); queue.add(10); queue.add(20); queue.add(30); queue.addFirst(40); // LinkedList 시작점에 원소를 추가 queue.add(50); System.out.println(queue); // [40 , 10 , 20 ,30 ,50] System.out.println(queue.pollFirst()); // 40을 리턴하고 queue 에서 40을 제거 System.out.println(queue); // [10, 20, 30, 50] System.out.println(queue.pollLast()); // 50을 리턴하고 queue 에서 50을 제거 System.out.println(queue); // [10, 20, 30] } }
REFERENCE
https://www.geeksforgeeks.org/linked-list-set-1-introduction/
https://beginnersbook.com/2013/12/linkedlist-in-java-with-example/
https://www.upgrad.com/blog/what-is-linear-data-structure/
https://www.programiz.com/java-programming/queue
이것이 자바다'Java' 카테고리의 다른 글
[JavaStudy] - Class Loader(클래스 로더) in JVM (0) 2021.09.29 [Java Study] - Garbage Collection(GC) in JVM (0) 2021.09.26 [Java Study] - 연산자 , 연산자의 종류 (0) 2021.09.23 [Java Study] - 자바 데이터 타입, 변수 ,배열 (0) 2021.09.22 [Java Study] - JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가. (2) 2021.09.16