티스토리 뷰

1. List 개요

1-1. List 인터페이스란?

💡 순서가 있는 데이터의 집합으로 같은 데이터의 중복 저장을 허용.
ArrayList, LinkedList, Vector, Stack이 있다.

1-2. List 특징

  • List 인터페이스를 구현한 모든 클래스는 저장 순서가 유지된다.
  • List 계열의 클래스는 중복 저장을 허용한다.

2. ArrayList 개요

2-1. ArrayList 란?

💡 자바에서 제공하는 기본 배열보다 느릴 수 있지만 동적 배열이 구현되어 있다.

ArrayList 클래스는 가장 많이 사용되는 컬렉션 클래스

2-2. ArrayList 특징

  • ArrayList는 인스턴스를 생성하게 되면 내부적으로 10칸짜리 배열을 생성해서 관리한다.
  • 배열의 단점을 보완하기 위해 만들어졌기 때문에 크기 변경, 요소 추가/삭제/정렬 기능들을 메소드로 제공하고 있다.
  • 자동적으로 수행되는 것이지 속도가 빨라지는 것은 아니다.
  • ArrayList는 스레드간 동기화가 지원되지 않는다. 따라서 다수의 스레드가 동시에 접근하여 데이터를 조작하게 될 경우 데이터 훼손이 일어날 수 있다.
  • ArrayList는 인덱스로 데이터에 접근할 수 있기 때문에 조회 기능적으로 뛰어나다.
section01.list.run.Application1
package com.ohgiraffers.section01.list.run;     // list -> 배열의 업그레이드 (1. 1개의 타입만 X / 2. 크기 정하지 않아도 된다.)

import java.util.*;

public class Application1 {
    public static void main(String[] args) {

        /* 수업목표. 컬렉션 프레임워크에 대해 이해할 수 있다.(list부터) */
//        ArrayList list = new ArrayList();               // 제네릭 안쓰면 ArrayList<Object>와 같다.
        List list = new ArrayList();                    // List 계열의 다른 인스턴스로 바껴도 나머지 코드에 영향을 주지
                                                        // 않기 위해서 다형성을 적용한 형태로 많이 쓴다.

        /* 설명. 자료형에 구애받지 않고 데이터를 추가할 수 있다. */
        list.add("apple");
        list.add(123);
        list.add(45.67);
        list.add(new java.util.Date());

        /* 컬렉션들은 toString() 오버라이딩이 잘 되어 있어 출력해 보기 편함 */
        System.out.println("list 한번에 출력: " + list);

        System.out.println("list.get(0): " + list.get(0));  // 처음 add한 값
        System.out.println("list.get(2): " + list.get(2));  // 세 번째 add한 값
        System.out.println("list에 담긴 데이터의 크기: " + list.size()); // length 아니다!!!

        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        /* 설명.
        *   배열보다 ArrayList 가 나은 점
        *    1. 처음부터 크기 할당 불필요
        *    2. 중간에 값 추가 및 삭제가 용이
        *  */

        /* 설명. 배열과 ArrayList 를 활용해 각각 원하는 인덱스에 값 추가해보기 */
        int[] intArr = new int[5];
        int num = 0;
        for (int i = 0; i < intArr.length; i++) {
            intArr[i] = ++ num;
        }

        System.out.println(Arrays.toString(intArr));

        int[] newArr = new int[intArr.length + 1];
        System.arraycopy(intArr, 0, newArr, 0, intArr.length);
        System.out.println(Arrays.toString(newArr));

        /* 설명. 2번 인덱스 위치에 7을 끼워넣기 */
        for (int i = newArr.length - 2; i > 1; i--) {
            newArr[i+1] = newArr[i];
        }

        System.out.println(Arrays.toString(newArr));
        newArr[2] = 7;
        System.out.println(Arrays.toString(newArr));

        /* 설명. ArrayList 에서 제공하는 add() 메소드로 쉽게 해 보자. */
        ArrayList<Integer> intArrList = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            intArrList.add(i + 1);
        }
        System.out.println(intArrList);
        intArrList.add(2, 7);       // 매개변수 2개짜리 add 메소드를 활용
        System.out.println(intArrList);

        /* 설명. ArrayList에는 중복(동등(e, h)) 값이 허용된다. */
        System.out.println(list);
        list.add("apple");
        list.add(123);
        System.out.println(list);

        /* 설명. ArrayList가 관리하는 값을 수정하려면 set() 메소드 활용한다. */
        list.set(0, 777);
        System.out.println(list);

        /* 설명. ArrayList가 관리하는 것을 삭제하려면 remove() 메소드 활용한다. */
        list.remove(0);
        System.out.println(list);

        list.add(null);
        System.out.println(list);

        /* 설명. ArrayList를 활용한 정렬 */
        /* 설명. 1. 문자열 데이터 정렬 */
        List<String> stringList = new ArrayList<>();
        stringList.add("apple");
        stringList.add("orange");
        stringList.add("banana");
        stringList.add("mango");
        stringList.add("grape");

        System.out.println("stringList = " + stringList);

        /* 설명. ArrayList 안에 들어있는 데이터 타입(String)에 정의된 정렬 기준대로 정렬 */
        Collections.sort(stringList);       // String에는 문자열 오름차순(Ascending)에 대한 정의가 되어 있음
        System.out.println("stringList = " + stringList);

        List<Integer> integerList = new ArrayList<>();
        integerList.add(4);
        integerList.add(20);
        integerList.add(5);
        integerList.add(8);
        integerList.add(14);

        System.out.println("integerList = " + integerList);

        Collections.sort(integerList);
        System.out.println("integerList = " + integerList);

        /* 설명. 내림차순으로 바꾸기 위해 ArrayList 에서 LinkedList로 교체 */
        stringList = new LinkedList<>(stringList);

        /* 설명. Iterator(반복자)는 hasNext()와 next()를 활용해 들어있는 data를 반복시킬 수 있는 타입이다. */
        /* 설명. 다루는 Iterator와 관련된 컬렉션의 제네릭 타입과 일치하는 제네릭을 꼭 써주자!(다운캐스팅 고민 없도록) */
        Iterator<String> iter = ((LinkedList<String>)stringList).descendingIterator();      // 이해 안댐?
        // descendingIterator는 linkedList의 고유 메소드여서 다운캐스팅하고, 반환형이 Iterator여서 Iterator 변수로 받는다.
        while (iter.hasNext()) {
            System.out.print(iter.next() + " ");
        }
    }
}

// 실행 결과
list 한번에 출력: [apple, 123, 45.67, Tue Jul 23 20:10:36 KST 2024]
list.get(0): apple
list.get(2): 45.67
list에 담긴 데이터의 크기: 4

apple
123
45.67
Tue Jul 23 20:10:36 KST 2024

[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 0]
[1, 2, 3, 3, 4, 5]
[1, 2, 7, 3, 4, 5]

[1, 2, 3, 4, 5]
[1, 2, 7, 3, 4, 5]

[apple, 123, 45.67, Tue Jul 23 20:10:36 KST 2024]
[apple, 123, 45.67, Tue Jul 23 20:10:36 KST 2024, apple, 123]

[777, 123, 45.67, Tue Jul 23 20:10:36 KST 2024, apple, 123]

[123, 45.67, Tue Jul 23 20:10:36 KST 2024, apple, 123]

[123, 45.67, Tue Jul 23 20:10:36 KST 2024, apple, 123, null]

stringList = [apple, orange, banana, mango, grape]

stringList = [apple, banana, grape, mango, orange]

integerList = [4, 20, 5, 8, 14]

integerList = [4, 5, 8, 14, 20]

orange mango grape banana apple
section01.list.run.Application2
package com.ohgiraffers.section01.list.run;

import com.ohgiraffers.section01.list.comparator.AscendingPrice;
import com.ohgiraffers.section01.list.dto.BookDTO;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Application2 {
    public static void main(String[] args) {

        /* 수업목표. ArrayList에서 관리되는 자료형의 정렬 기준을 이용할 수 있다. */
        /* 목차. 1. Comparable 인터페이스 구현 방법 활용 */
        List<BookDTO> bookList = new ArrayList<>();
        bookList.add(new BookDTO(1, "홍길동전", "허균", 50000));
        bookList.add(new BookDTO(2, "목민심서", "정약용", 30000));
        bookList.add(new BookDTO(3, "동의보감", "허준", 40000));
        bookList.add(new BookDTO(4, "삼국사기", "김부식", 46000));
        bookList.add(new BookDTO(5, "삼국유사", "일연", 58000));

        /* 설명. Collectionas.sort를 활용한 정렬(Comparable 방식 또는 Comparator 방식) */
//        Collections.sort(bookList);                       // Comparable 방식
        Collections.sort(bookList, new AscendingPrice());   // Comparator 방식 (Comparable 보다 강하다)

        /* 설명. ArrayList가 제공하는 sort를 사용할 수도 있다.(다만 Comparator 기준만 가능) */
        bookList.sort(new AscendingPrice());        // ArrayList 일때만 사용 가능, Comparator 방식과 같다.

        System.out.println(bookList);

        for (int i = 0; i < bookList.size(); i++) {
            System.out.println(bookList.get(i));
        }
    }
}

// 실행 결과
[BookDTO{number=2, title='목민심서', author='정약용', price=30000}, BookDTO{number=3, title='동의보감', author='허준', price=40000}, BookDTO{number=4, title='삼국사기', author='김부식', price=46000}, BookDTO{number=1, title='홍길동전', author='허균', price=50000}, BookDTO{number=5, title='삼국유사', author='일연', price=58000}]

BookDTO{number=2, title='목민심서', author='정약용', price=30000}
BookDTO{number=3, title='동의보감', author='허준', price=40000}
BookDTO{number=4, title='삼국사기', author='김부식', price=46000}
BookDTO{number=1, title='홍길동전', author='허균', price=50000}
BookDTO{number=5, title='삼국유사', author='일연', price=58000}
section01.list.dto.BookDTO
package com.ohgiraffers.section01.list.dto;

public class BookDTO implements Comparable<BookDTO>{
    private int number;
    private String title;
    private String author;
    private int price;

    public BookDTO() {
    }

    public BookDTO(int number, String title, String author, int price) {
        this.number = number;
        this.title = title;
        this.author = author;
        this.price = price;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "BookDTO{" +
                "number=" + number +
                ", title='" + title + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                '}';
    }

    /* 필기.
    *   우리가 원하는 필드의 오름차순 또는 내림차순을 할 수 있다.
    *   필드가 n개면 총 (n * 2)가지의 정렬 기준을 가질 수 있다.(각각 ASC 또는 DESC)
    *   정렬은 CompareTo()메소드가 반환하는 int형의 부호에 따라 정해지게 되므로 오름차순과 내림차순은
    *   부호만 달리 되도록 하면 된다.
    *   (해당 필드가 String형일 경우는 String의 compareTo() 메소드를 활용하자)
    *   */

    @Override                           // 정렬을 하나밖에 하지 못한다.
    public int compareTo(BookDTO o) {   // 메소드를 호출하는 것이 두번째, 매개변수로 들어오는 것이 첫번째 -> 내부적으로...

        /* 설명. 가격에 대한 오름차순 */
//        return this.price - o.getPrice();     // 어떤 필드를 이용할지가 중요.

        /* 설명. 가격에 대한 내림차순 */
//        return o.getPrice() - this.price;
//        return -(this.price - o.getPrice());

        /* 설명. 책 제목에 대한 오름차순 */
//        return this.title.compareTo(o.getTitle());

        /* 설명. 책 제목에 대한 내림차순 */
//        return -this.title.compareTo(o.getTitle());
        return o.getTitle().compareTo(this.title);
    }
}
section01.list.comparator.AscendingPrice
package com.ohgiraffers.section01.list.comparator;

import com.ohgiraffers.section01.list.dto.BookDTO;

import java.util.Comparator;

public class AscendingPrice implements Comparator<BookDTO> {

    /* 설명. 가격 오름차순이 가능하도록 compare() 메소드 오버라이딩 */
    @Override
    public int compare(BookDTO o1, BookDTO o2) {
        return o1.getPrice() - o2.getPrice();
    }
}

3. LinkedList 개요

3-1. LinkedList란?

💡 ArrayList 클래스가 배열과 유사하게 데이터를 저장함으로써 발생하는 단점을 보완하기 위해 고안.
내부적으로 연결 리스트(Linked List)를 이용해 데이터를 저장.

인덱스 같은 위치는 신경 쓰지 않는다.

3-2. LinkedList 특징

  • LinkedList는 저장되는 데이터들이 연속된 공간에 저장되는 것이 아니다. 따라서 각 데이터를 링크(Link)를 연결하여 구성한다.
  • 데이터의 삽입, 삭제가 빈번할 경우 연결되는 링크 정보만 수정하면 되기 때문에 ArrayList보다 더 적합하다.
  • 스택, 큐, 양방향 큐 등을 구성하기 용이하다.
  • LinkedList 에는 단일 연결 리스트와 이중 연결 리스트가 있다.
    • 단일 연결 리스트
      • 저장한 요소가 순서를 유지하지 않고 저장되지만 이러한 요소들 사이를 링크로 연결하여 구성하며 마치 연결된 리스트 형태인 것 처럼 만든 자료구조이다.
      • 요소의 저장과 삭제 시 다음 요소를 가리키는 참조 링크만 변경하면 되기 때문에 요소의 저장과 삭제가 빈번히 일어나는 경우 ArrayList보다 성능 면에서 우수하다.
    • 이중 연결 리스트
      • 단일 연결 리스트는 다음 요소만 링크하는 반면 이중 연결 리스트는 이전 요소도 링크하여 이전 요소로 접근하기 쉽게 고안된 자료구조 이다.
section01.list.run.Application3
package com.ohgiraffers.section01.list.run;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class Application3 {
    public static void main(String[] args) {

        /* 수업목표. List 계열을 출력하는 4가지 방법 */
        /* 수업목표. LinkedList에 대해 이해할 수 있다. */
//        List<String> arrList = new ArrayList<>();
        List<String> arrList = new LinkedList<>();
        arrList.add("apple");
        arrList.add("banana");
        arrList.add("orange");
        arrList.add("mango");
        arrList.add("grape");

        /* 설명. 1. toString() 활용하기 */
        System.out.println("arrList = " + arrList);

        /* 설명. 2. for문 활용하기 */
        for (int i = 0; i < arrList.size(); i++) {
            System.out.println(arrList.get(i));
        }

        /* 설명. 3. for-each문 활용하기 */
        for(String str: arrList) {
            System.out.println(str);
        }

        /* 설명. 4. iterator 활용하기 */
        Iterator<String> iter = arrList.iterator();
        while(iter.hasNext()) {
            System.out.println(iter.next());
        }

        /* 설명. 1번 인덱스(2번째)의 과일 수정 */
        arrList.set(1, "pineapple");
        System.out.println("arrList = " + arrList);

        /* 설명. list가 관리하는 요소들 제거 */
        arrList.remove(2);      // LinkedList는 ArrayList와 달리 부분적인 요소 제거에서 성능이 우수하다.
        System.out.println("arrList = " + arrList);
        arrList.clear();              // 전체 요소들 제거 / 리스트 객체는 그대로 있다. 보관한 값만 제거
        System.out.println("arrList = " + arrList);

        /* 설명. 요소가 없는 list 계열인지 확인 */
        System.out.println("isEmpty = " + arrList.isEmpty());

    }
}

// 실행 결과
arrList = [apple, banana, orange, mango, grape]

apple
banana
orange
mango
grape

apple
banana
orange
mango
grape

apple
banana
orange
mango
grape

arrList = [apple, pineapple, orange, mango, grape]
arrList = [apple, pineapple, mango, grape]
arrList = []
isEmpty = true

 

4. Stack 개요

4-1. Stack 이란?

💡 '쌓다', '더미' 라는 뜻을 가진 자료 구조로 리스트 계열 클래스인 Vector 클래스를 상속받아 구현된 자료구조

LIFO(Last In First Out)

4-2. Stack 특징

  • 제일 나중에 들어간 데이터가 가장 먼저 나오는 LIFO(Last In First Out) 구조로 되어 있다.
  • 메소드가 호출될 때 해당 구조로 메모리에 올라가게 된다.
section01.list.run.Application4
package com.ohgiraffers.section01.list.run;

import java.util.Stack;

public class Application4 {
    public static void main(String[] args) {

        /* 수업목표. Stack에 대해 이해하고 사용할 수 있다. */
        /* 필기.
        *   Stack이란?
        *    후입선출(LIFO) 또는 선입후출(FiLO)의 자료 구조로 push(), pop(), peek() 등의 메소드를
        *    활용하여 자료를 처리할 수 있다.
        *  */

        Stack<Integer> integerStack = new Stack<>();

        /* 설명. Stack 인스턴스 생성 후 데이터 추가 */
        integerStack.push(1);
        integerStack.push(2);
        integerStack.push(3);
        integerStack.push(4);
        integerStack.push(5);

        System.out.println(integerStack);

        System.out.println("peak(): " + integerStack.peek());
        System.out.println(integerStack);

        System.out.println("search(): " + integerStack.search(2));

        System.out.println("pop(): " + integerStack.pop());
        System.out.println("pop(): " + integerStack.pop());
        System.out.println("pop(): " + integerStack.pop());
        System.out.println("pop(): " + integerStack.pop());
        System.out.println("pop(): " + integerStack.pop());
        System.out.println(integerStack);
    }
}

// 실행 결과
[1, 2, 3, 4, 5]

peak(): 5
[1, 2, 3, 4, 5]

search(): 4

pop(): 5
pop(): 4
pop(): 3
pop(): 2
pop(): 1
[]

 

5. Queue 개요

5-1. Queue 란?

💡 사전적 의미로 '줄'을 의미. 스택과는 다르게 FIFO(선입선출)로 구현되어 있다.

시간보다 순서의 정확성을 더 중요하게 생각할 때 큐 사용!

5-2. Queue 특징

  • 먼저 들어간 데이터가 먼저 나오는 FIFO(First In First Out) 구조.
  • 큐는 Front와 Rear를 정하고 한 곳에는 삭제만, 다른 한 곳에서는 삽입 연산만 처리한다.
  • Queue 인터페이스를 상속받는 하위 인터페이스 들은 Deque, BlockingQueue, BlockingDeque, TreansferQueue 등 다양하지만 대부분의 큐는 LinkedList를 이용한다.
package com.ohgiraffers.section01.list.run;

import java.util.Collections;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;

public class Application5 {
    public static void main(String[] args) {

        /* 수업목표. Queue에 대해 이해하고 활용할 수 있다. */
        /* 필기.
        *   Queue란?
        *    선형 메모리 공간에 데이터를 저장하여 순서를 유지하기 위한 선입선출(FIFO) 방식의 자료구조이다.
        *    대부분 LinkedList를 많이 사용한다.
        *  */
//        Queue que = new Queue();
//        Queue<String> que = new LinkedList<>();         // Queue 타입은 단방향만 가능...
//        LinkedList<String> que = new LinkedList<>();    // LinkedList는 queue 중에서도 deque에 해당되어
//                                                        // offerFirst()나 offerLast() 같은 메소드도 제공된다.

        /* 설명. PriorityQueue를 활용하면 선입선출 + 정렬의 개념을 가져갈 수 있다. */
//        PriorityQueue<String> que = new PriorityQueue<>();             // String의 기준대로 문자열 오름차순 / 결과 이상하던데?????????기준이 뭐지???????????????
        PriorityQueue<String> que = new PriorityQueue<>(Collections.reverseOrder());    // 반대인 내림차순

        que.offer("first");
        que.offer("second");
        que.offer("third");
        que.offer("fourth");
        que.offer("fifth");

        System.out.println("que = " + que);

        System.out.println("peek(): " + que.peek());

        System.out.println("poll(): " + que.poll());
        System.out.println("que = " + que);
        System.out.println("poll(): " + que.poll());
        System.out.println("que = " + que);
        System.out.println("poll(): " + que.poll());
        System.out.println("que = " + que);
        System.out.println("poll(): " + que.poll());
        System.out.println("que = " + que);
        System.out.println("poll(): " + que.poll());
        System.out.println("que = " + que);

    }
}

// 실행 결과
que = [third, fourth, second, first, fifth]

peek(): third

poll(): third
que = [second, fourth, fifth, first]
poll(): second
que = [fourth, first, fifth]
poll(): fourth
que = [first, fifth]
poll(): first
que = [fifth]
poll(): fifth
que = []
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함