본 게시글은 대학 전공수업을 들으며 노션에 정리한 내용을 블로그로 옮긴 것으로, 노션 웹을 통해 최적화된 형태로 읽으시길 권장드립니다.(➡️ 노션 링크)
11강 - 컬렉션 : JCF, Iterator, 자료구조, HashSet, ArrayList, LinkedList, HashMap
컬렉션
여러 원소를 하나의 그룹으로 묶어 관리하기 위한 자료구조
JCF는 이러한 데이터 목록을 관리하기 위한 인터페이스와 클래스의 모음
JCF(Java Collections Framework)
컬렉션을 표현/활용하기 위한 통합된 프레임워크
- 클래스와 인터페이스의 집합.
- 저장/검색/수정하는 도구 제공
컬렉션을 일관된 방법으로 다룰 수 있음
- 표준화/일관성있는 인터페이스 : 어떻게 표현되는지와 상관x
- 클래스: 인터페이스를 구현한 클래스를 제공
JCF의 인터페이스
Set : 순서x / 중복x
List : 순서O / 중복O
Queue: List와 유사, 삽입/삭제가 FIFO방식.
Map : <Key,Value>의 형태로, Key는 유일해야함.
객체 선언
- java.util패키지에 포함되며, 제네릭 타입.
- 변수 선언은 해당 인터페이스 유형으로, 인터페이스는 인터페이스를 구현하는 클래스(다루는 자료의 유형을 지정)를 사용한다.
코드
Set<Integer> set = new HashSet<>();
List<Integer> list = new ArrayList<>();
List<Integer> list = new LinkedList<>();
Queue<Integer> queue = new LinkedList<>();
Map<String, Integer> map = new HashMap<>();
Collection 인터페이스
- Set, List, Queue에서 공통으로 지원해야하는 기능을 정의
원소의 삽입과 삭제 메소드
원소 탐색 메소드
기타 메소드
Iteratable : 향상된for문 / foreach문 사용가능.
Iterator : 순차적으로 컬렉션을 다룰 수 있다.
HashSet
Set : 순서없고, 중복 허용 x.
HashSet : Null허용
예시코드
import java.util.HashSet; import java.util.Set; public class HashSetClass { public static void main(String args[]) { Set<String> set = new HashSet<String>(); set.add("one"); set.add("two"); set.add("three"); set.add("four"); System.out.println(set.add(new String("one"))); //false System.out.println(set.size()); //4 System.out.println(set.contains("four")); //true System.out.println(set.contains("one")); //true System.out.println(set.contains(new String("one"))); //true set.remove("four"); set.remove(new String("one")); System.out.println(set.size()); //2 set.clear(); System.out.println(set.size()); //0 } }
ArrayList
List
ArrayList
List : 순서O / 중복O
ArrayList : 크기조절 가능한 배열로 구현→ 더 큰 배열로 확장. 가장 일반적인 배열의 형태!
- 입력된 순서대로 관리됨!
ArrayList 메소드
- 예시 코드```java
package lecture11;
import java.util.ArrayList;
import java.util.List;
public class ArrayListClass {
public static void main(String args[]) {
List<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
list.add(1, "one"); //인덱스1에 "one" 추가
list.add("five");
System.out.println(list.size()); //5
System.out.println(list.indexOf("one")); //0
System.out.println(list.get(2)); //two
System.out.println(list.lastIndexOf("one")); //1(뒤에서부터)
System.out.println(list.set(3, "four")); //three //3번을 four로 변경후 기존 원소 리턴
System.out.println(list.remove(4)); //4번 삭제 후 기존 원소 리턴
System.out.println(list.remove("one")); //true 삭제 성공
}
}
```
```java
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ArrayListEx2 {
public static void main(String args[]) {
List<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
list.add("five");
// for 구문을 이용한 자료 탐색
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 향상된 for 구문을 이용한 자료 탐색
for (String s : list) {
System.out.println(s);
}
// Iterator 인터페이스를 이용한 자료 탐색
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
//출력결과는 모두 one~five
```
```java
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class ArrayListEx3 {
public static void main(String args[]) {
List<String> list = new ArrayList<String>();
list.add("one");
list.add("three");
list.add("two");
list.add(1, "one");
//함수형인터페이스 Consumer를 이용한 자료 출력 예!
Consumer<String> con1 = new Consumer<>() {
public void accept(String t) {
System.out.println(t);
}
};
//람다식
list.forEach(con1);
Consumer<String> con2 = t -> System.out.println(t);
list.forEach(con2);
list.forEach(t -> System.out.println(t));
}
}
//출력
one
one
three
two
```
Iterator 클래스
컬렉션에 저장된 원소를 차례대로 다룰 수 있음
컬렉션에서 Iterator 객체를 리턴하는 iterator() 사용 가능.
코드
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class IteratorClass { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("one"); list.add("two"); Iterator<String> it = list.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } } //출력결과 one two
LinkedList
ArrayList와 대체될 정도로 비슷하나, 각 요소들이 이전/다음 노드를 참조하는 ‘노드’라는 단위로 저장됨. (
이중 연결 리스트
)스택 자료구조에서 필요한 메소드도 제공함.
Queue 인터페이스도 구현함.
- boolean offer(E), boolean add(E)
- 뒤에 원소를 추가함.
- E poll(), E(remove)
- 앞의 원소를 삭제하고 리턴
- E peek(), E element()
- 앞의 원소를 읽음
- offer(E), poll, peek( 앞 3개)true/false 또는 null을 리턴하지만
add, remove, element (뒤 3개)는 실패시 예외를 발생시킴!
- boolean offer(E), boolean add(E)
예시 코드
import java.util.LinkedList; public class LinkedListClass { public static void main(String args[]) { LinkedList<String> queue = new LinkedList<String>(); queue.offer("one"); queue.offer("two"); queue.offer("three"); String s = queue.poll(); //s = "one"; while (s != null) { System.out.println(s); s = queue.poll(); //"two" -> "three" -> null(종료) } } } //출력결과 one two three
ArrayList와 LinkedList의 사용 차이
- Arraylist : 읽기와 접근이 빈번하고, 데이터의 크기가 비교적 고정되어 있으며, 삽입과 삭제가 드물게 발생하는 경우.
- LinkedLIst : 삽입과 삭제가 빈번하게 발생하고, 중간 요소의 추가와 삭제가 자주 일어나는 경우.
Map<K,V> 인터페이스
Map : <Key,Value>의 형태의 원소로 구성되는 컬렉션을 다루기 위한 인터페이스
JCF에서 Iterator, Collection과 독립적
key는 중복x, 하나의 key에 하나의 Value가 대응
순서는 중요하지 않음.
주요메서드
HashMap 클래스
HashMap
- 해싱을 이용해 Map 인터페이스를 구현한 클래스.
- 탐색 방법이 ArrayList, LinkedList와 다름
- scores = HashMap<이름, 성적> 객체
코드
import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; //단순하지만 성적관리 시스템 public class HashMapEx { public static void main(String[] args) { // Map 인터페이스 타입의 변수 선언 Map<String, Integer> lectures; // 학생 이름을 키로, <과목,점수>를 저장한 맵을 값으로 저장할 HashMap 초기화 Map<String, Map> scores = new HashMap<>(); // 학생 이름들을 저장할 ArrayList 초기화 List<String> names = new ArrayList<String>(); names.add("김철수"); names.add("이영희"); // 학생 이름을 순회할 Iterator 초기화 Iterator<String> it = names.iterator(); while (it.hasNext()) { String name = it.next(); // 다음 학생 이름 가져오기 if (name.equals("김철수")) { // 김철수의 과목 점수를 저장할 HashMap 초기화 lectures = new HashMap<String, Integer>(); lectures.put("국어", 100); // 국어 점수 추가 lectures.put("영어", 95); // 영어 점수 추가 lectures.put("수학", 80); // 수학 점수 추가 scores.put(name, lectures); // 김철수의 점수를 scores 맵에 저장 } else { // 이영희의 과목 점수를 저장할 HashMap 초기화 lectures = new HashMap<String, Integer>(); lectures.put("국어", 90); lectures.put("영어", 95); lectures.put("수학", 95); scores.put(name, lectures); // 이영희의 점수를 scores 맵에 저장 } } // 다시 학생 이름을 순회할 Iterator 초기화 Iterator<String> it2 = names.iterator(); while (it2.hasNext()) { String name = it2.next(); // 다음 학생 이름 가져오기 System.out.println(name); // 학생 이름 출력 System.out.print("국어 : "); // 국어 점수를 scores 맵에서 가져와 출력 System.out.println(scores.get(name).get("국어")); System.out.print("영어 : "); // 영어 점수를 scores 맵에서 가져와 출력 System.out.println(scores.get(name).get("영어")); System.out.print("수학 : "); // 수학 점수를 scores 맵에서 가져와 출력 System.out.println(scores.get(name).get("수학")); System.out.println(); // 빈 줄 출력 } } } //출력 결과 /* 김철수 국어 : 100 영어 : 95 수학 : 80 이영희 국어 : 90 영어 : 95 수학 : 95 */
그런데, 자꾸 보이는
Hash란 무엇인가?
- ‘해싱(Hashing) 기법을 사용하여 데이터를 저장하고 검색하는 방법’
- 해싱기법은 뭔데?
- 키(key)를 입력받아 해시 함수(hash function)를 통해 고정된 크기의 해시 코드(hash code)로 변환해 이를 기반으로 데이터를 저장/검색하는 방식.
- 해시 함수란?
- 입력받은 데이터를 해시값으로 출력시키는 알고리즘.
- 해시 코드란? :
- 해시 함수에 의해 생성된 고정된 크기의 정수 값, 데이터가 저장될 위치(버킷)를 결정함.
- 버킷이란? : 주소를 갖는 파일의 한 구역
- 해시 함수에 의해 생성된 고정된 크기의 정수 값, 데이터가 저장될 위치(버킷)를 결정함.
즉, 위 내용을 정리하자면, 해쉬란 ‘해싱기법을 활용하는 것’이다. 해싱이란 유일한 ‘Key’를 입력받으면, 해쉬함수를 통해 해시코드로 저장되고, 이 해시코드를 통해 이 자료가 ‘어디에’ 저장될지가 결정된다.
이렇게 말해도 어려운데, 도서관의 책과 책의 주소인 청구기호로 이해를 하면 될 것 같다.
비유를 하자면 key는 ‘책이름’이다. 편의상 ‘해리포터 1 KOR’이라고 하자. 해시함수는 사서들만 아는 알고리즘을 통해 ‘823.914 R884h한 1’이라는 이해할 수 없는 고정된 값(해시코드)로 저장한다. 이 위치에 따라 책은 일정한 장소(버킷)에 배치된다.
'Back-End > Java' 카테고리의 다른 글
(전공 정리) 13강 - 멀티 스레드 프로그래밍 : 프로세스, 스레드, 스레드 제어 (0) | 2024.06.22 |
---|---|
(전공 정리) 12강 - 스트림 : 중간연산(필터링,매핑,정렬,루핑), 종료연산(집계, 매칭) (0) | 2024.06.22 |
(전공 정리) 9강 - Java.io : 입출력스트림, 파일 입출력 (0) | 2024.06.22 |
(전공 정리) 8강 - java.lang 패키지: Object, String, StringBuffer (0) | 2024.06.22 |
(전공 정리) 7강 - 패키지와 예외처리 (0) | 2024.06.22 |
(전공 정리) 6강 - 제네릭, 람다식 (0) | 2024.06.22 |