티스토리 뷰
1. List 개요
1-1. List 인터페이스란?
💡 순서가 있는 데이터의 집합으로 같은 데이터의 중복 저장을 허용.
ArrayList, LinkedList, Vector, Stack이 있다.
1-2. List 특징
- List 인터페이스를 구현한 모든 클래스는 저장 순서가 유지된다.
- List 계열의 클래스는 중복 저장을 허용한다.
2. ArrayList 개요
2-1. 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 클래스를 상속받아 구현된 자료구조
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 = []
'한화시스템 > 백엔드' 카테고리의 다른 글
[BE] JAVA_컬렉션(Collection)_Map (2) | 2024.07.24 |
---|---|
[BE] JAVA_컬렉션(Collection)_Set (1) | 2024.07.24 |
[BE] JAVA_컬렉션(Collection)_개요 (1) | 2024.07.23 |
[BE] JAVA_제네릭스(Generics) (0) | 2024.07.23 |
[BE] JAVA_입출력_파일 클래스(File Class) (5) | 2024.07.22 |