7일차
컬렉션은 배열보다 다수의 참조형 데이터를 더 쉽고 효과적으로 처리할 수 있는 기능을 많이 가지고 있습니다.
컬렉션기능 : 크기 자동 조정/ 추가/ 수정/ 삭제/ 반복/ 순회/ 필터/ 포함 확인 등..
컬렉션의 종류
Collection에는 List, Set , Queue , Map 이 있습니다.
List : 순서가 있는 데이터의 집합 (데이터 중복 허용) - 배열과 비슷
Queue : 빨대🥤처럼 한쪽에서 데이터를 넣고 반대쪽에서 데이터를 뺄 수 있는 집합
Set : 순서가 없는 데이터의 집합 (데이터 중복 허용 안 함) - 순서 없고 중복 없는 배열
Map : 순서가 없는 (Key, Value) 쌍으로 이루어진 데이터의 집합 (Key값 중복 허용 안 함)
| List | Queue | Stack | Set | Map | |
|---|---|---|---|---|---|
| 추가 | .add() | .add() | .push() | .add() | .put() |
| 읽기/꺼내기 | .get() | .poll() | .pop() | - | - |
| 삭제 | .remove() | - | - | .remove(삭제할 값) | .remove(삭제할 key값) |
| 맨처음 조회 | - | .peek() | .peek() | - | - |
| 값 수정 | .set() | - | - | - | - |
| 값 전체삭제 | .clear() | - | - | - | - |
순서가 있는 데이터의 집합 (데이터 중복 허용) - 배열과 비슷
ArrayList는 배열(Array)처럼 일렬로 데이터를 저장하고 조회하여 순번 값(인덱스)로 값을 하나씩 조회할 수 있습니다.
특징
- 배열(Array)처럼 크기가 정해져 있지 않고 필요할 때마다 크기가 점점 더 늘어납니다.
❓
Array와 어떤 점이 다르길래ArrayList는 크기를 지정하지 않아도 되는 건가요?
먼저,Array처럼 크기를 고정하여 생성하는 것을 정적 배열 이라면
ArrayList처럼 크기가 가변적으로 늘어나는 것을 동적 배열 이라고 합니다.
Array은 메모리에 연속된 공간을 요청한 사이즈만큼 받아서 실제 값을 저장하는 기본형 변수로 저장하기 때문에 정적 배열 입니다.ArrayList는 생성시점에 작은 연속된 공간을 요청해서 참조형 변수들을 담아놓고, 값이 추가될 때 더 큰 공간이 필요하면 더 큰 공간을 받아서 저장하기 때문에 동적 배열 입니다.
따라서, 기본형 변수로 저장하는 Array는 정적 배열이고, 참조형 변수로 저장하는 ArrayList는 동적 배열이라고 기억하시면 됩니다!
기능
선언 : ArrayList<Integer> intList 형태로 선언합니다.
생성 : new ArrayList<Integer>(); 형태로 생성합니다.
초기화 : 사이즈를 지정하는 것이 없기 때문에 초기화가 필요 없습니다.
값 추가 : intList.add({추가할 값}) 형태로 값을 추가합니다.
값 수정 : intList.set({수정할 순번}, {수정할 값}) 형태로 값을 수정합니다.
값 삭제 : intList.remove({삭제할 순번}) 형태로 값을 삭제합니다.
전체 출력 : intList.toString() 형태로 전체 값을 대괄호[]로 묶어서 출력합니다.
전체 제거 : intList.clear() 형태로 전체 값을 삭제합니다.
📌
LinkedList는 메모리에 남는 공간을 요청해서 여기저기 나누어서 실제 값을 담아 놓고, 실제 값이 있는 주소값으로 목록을 구성하고 저장합니다.
특징
기본적인 기능은 ArrayList 와 동일하지만 LinkedList는 값을 나누어 담기 때문에 모든 값을 조회하는 속도가 느립니다. 대신에, 값을 중간에 추가하거나 삭제할 때는 속도가 빠릅니다.
기능
선언 : LinkedList<Integer> linkedList 형태로 선언합니다.
생성 : new LinkedList<Integer>(); 형태로 생성합니다.
초기화 : 사이즈를 지정하는 것이 없기 때문에 초기화가 필요 없습니다.
값 추가 : linkedList.add({추가할 값}) 형태로 값을 추가합니다.
값 중간에 추가 : linkedList.add({추가할 순번}, {추가할 값}) 형태로 값을 중간에 추가합니다.
값 수정 : linkedList.set({수정할 순번}, {수정할 값}) 형태로 값을 수정합니다.
값 삭제 : linkedList.remove({삭제할 순번}) 형태로 값을 삭제합니다.
전체 출력 : linkedList.toString() 형태로 전체 값을 대괄호[]로 묶어서 출력합니다.
전체 제거 : linkedList.clear() 형태로 전체 값을 삭제합니다.
Queue은 빨대🥤처럼 한쪽에서 데이터를 넣고 반대쪽에서 데이터를 뺄 수 있는 집합입니다.
선입선출(First-In-First-Out)
특징
First In First Out : 먼저 들어간 순서대로 값을 조회할 수 있다.
그렇기 때문에 넣는 기능(add()), 조회(peek()), 꺼내는(poll()) 기능만 존재합니다.
Queue는 생성자가 없는 껍데기라서 바로 생성할 수는 없습니다. (껍데기 = 인터페이스)
생성자가 존재하는 클래스인 LinkedList를 사용하여 Queue를 생성해서 받을 수 있습니다.
// LinkedList 를 생성하면 Queue 기능을 할 수 있습니다.
// (Queue 가 부모/ LinkedList 가 자식이기 떄문)
Queue<Integer> intQueue = new LinkedList<Integer>();
기능
선언 : Queue<Integer> intQueue 형태로 선언합니다.
생성 : new LinkedList<Integer>(); 형태로 생성합니다.
추가 : intQueue.add({추가할 값}) 형태로 값을 맨 위에 추가합니다.
조회 : intQueue.peek() 형태로 맨 아래 값을 조회합니다.
꺼내기 : intQueue.poll() 형태로 맨 아래 값을 꺼냅니다. (꺼내고 나면 삭제됨)
📌
Stack은 값을 수직으로 쌓아놓고 넣었다가 빼서 조회하는 형식으로 데이터를 관리합니다.
“후입선출(Last-In-First-out)” 성질을 가졌다고 표현하며, 주로 상자와 비유해서 설명합니다.
특징
상자에 물건을 넣고 빼는 것처럼 밑에서 위로 쌓고, 꺼낼 때는 위에서부터 꺼내는 형식입니다.
그렇기 때문에 넣는 기능(push()) 과 조회(peek()), 꺼내는(pop()) 기능만 존재합니다.
이렇게 불편하게 쓰는 이유는 최근 저장된 데이터를 나열하고 싶거나 데이터의 중복 처리를 막고 싶을 때 사용합니다.
기능
선언 : Stack<Integer> intStack 형태로 선언합니다.
생성 : new Stack<Integer>(); 형태로 생성합니다.
추가 : intStack.push({추가할 값}) 형태로 값을 추가합니다.
조회 : intStack.peek() 형태로 맨 위값을 조회합니다.
꺼내기 : intStack.pop() 형태로 맨 위값을 꺼냅니다. (꺼내고 나면 삭제됨)
Set은 순서가 없는 데이터의 집합 (데이터 중복 허용 안 함) - 순서 없고 중복 없는 배열
특징
Set은 그냥 Set으로 쓸 수도 있지만 HashSet, TreeSet 등으로 응용하여 사용할 수 있습니다.Set는 생성자가 없는 껍데기라서 바로 생성할 수는 없습니다. (껍데기 = 인터페이스)HashSet를 사용하여 Set를 생성해서 받을 수 있습니다.기능
선언 : Set<Integer> intSet 형태로 선언합니다.
생성 : new HashSet<Integer>(); 형태로 생성합니다.
추가 : intSet.add({추가할 값}) 형태로 값을 맨 위에 추가합니다.
삭제 : intSet.remove({삭제할 값}) 형태로 삭제할 값을 직접 지정합니다.
포함 확인 : intSet.contains({포함 확인 할 값}) 형태로 해당 값이 포함되어있는지 boolean 값으로 응답받습니다.
HashSet외에도TreeSet,LinkedHashSet이 있습니다.
HashSet: 가장 빠르며 순서를 전혀 예측할 수 없음TreeSet: 정렬된 순서대로 보관하며 정렬 방법을 지정할 수 있음LinkedHashSet: 추가된 순서, 또는 가장 최근에 접근한 순서대로 접근 가능
즉, 보통HashSet을 쓰는데 순서 보장이 필요하면LinkedHashSet을 주로 사용합니다.
여태까지 value 값들만 넣어서 관리하는 분류통(자료구조)를 배웠다면
Map은key-value구조로 구성된 데이터를 저장할 수 있습니다.
특징
key-value 형태로 데이터를 저장하기 때문에 기존에 순번으로만 조회하던 방식에서, key 값을 기준으로 value를 조회할 수 있습니다.
key 값 단위로 중복을 허용하지 않는 기능을 가지고 있습니다.
Map 은 그냥 Map으로 쓸 수도 있지만 HashMap, TreeMap등으로 응용하여 사용할 수 있습니다.
Map으로 쓸 수도 있지만 HashSet, TreeSet 등으로 응용하여 사용할 수 있습니다.
기능
선언 : Map<String, Integer> intMap 형태로 Key타입과 Value타입을 지정해서 선언합니다.
생성 : new HashMap<>(); 형태로 생성합니다.
추가 : intMap.put({추가할 Key값},{추가할 Value값}) 형태로 Key에 Value값을 추가합니다.
조회 : intMap.get({조회할 Key값}) 형태로 Key에 있는 Value값을 조회합니다.
전체 key 조회 : intMap.keySet() 형태로 전체 key 값들을 조회합니다.
전체 value 조회 : intMap.values() 형태로 전체 value 값들을 조회합니다.
삭제 : intMap.remove({삭제할 Key값}) 형태로 Key에 있는 Value값을 삭제합니다.
HashMap외에도TreeMap이 있습니다.
HashMap: 중복을 허용하지 않고 순서를 보장하지 않음, 키와 값으로 null이 허용TreeMap: key 값을 기준으로 정렬을 할 수 있습니다. 다만, 저장 시 정렬(오름차순)을 하기 때문에 저장시간이 다소 오래 걸림
자료구조 요리 레시피 메모장 만들기
- 입력값
- 저장할 자료구조명을 입력합니다. (List / Set / Map)
- 내가 좋아하는 요리 제목을 먼저 입력합니다.
- 이어서 내가 좋아하는 요리 레시피를 한 문장씩 입력합니다.
- 입력을 마쳤으면 마지막에 “끝” 문자를 입력합니다.
- 출력값
- 입력이 종료되면 저장한 자료구조 이름과 요리 제목을 괄호로 감싸서 먼저 출력해 줍니다.
- 이어서, 입력한 모든 문장 앞에 번호를 붙여서 입력 순서에 맞게 모두 출력해 줍니다.
입력의 두번째 값만 출력됨
import java.util.ArrayList;
import java.util.Scanner;
public class W02 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<String> strList = new ArrayList<String>();
int count = 1;
String str = "";
while (!sc.nextLine().equals("끝")) {
str = sc.nextLine();
strList.add(str);
}
System.out.println("[" + strList.get(0) + " 으로 저장된 " + strList.get(1) + "]");
for (int i = 2; !strList.get(i).equals("끝"); i++) {
System.out.println(count++ + ". " + strList.get(i));
}
}
}
- 입력
1
2
3
4
5
6
7
8
9
끝
끝
- 출력
[2 으로 저장된 4]
- 6
- 8
import java.util.ArrayList;
import java.util.Scanner;
public class W02 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<String> strList = new ArrayList<String>();
int count = 1;
String str = "";
while (!str.equals("끝")) {
str = sc.nextLine();
strList.add(str);
}
System.out.println("[" + strList.get(0) + " 으로 저장된 " + strList.get(1) + "]");
for (int i = 2; !strList.get(i).equals("끝"); i++) {
System.out.println(count++ + ". " + strList.get(i));
}
}
}