[공부 내용 정리]
컬렉션(Collection) : 요소를 수집해서 저장하는 것
ex) 다수개의 객체를 저장해 두고 필요할 때 마다 꺼내서 사용하는 경우
배열의 문제점을 해결하기 위해 java.util 패키지에 컬렉션과 관련된 인터페이스와 클래스들이 존재함. 이들을 총칭해서 컬렉션이라고 함. ex) List, Set, Map
List, Set 은 객체를 추가, 삭제하는 방법에 공통점이 있고 Collection 인터페이스로 정의해 두고 있음.(배열이나 트리 형태. 하나의 값만 저장함)
Map은 키(Key)와 값(Value)을 하나의 쌍으로 묶어서 관리하는 구조로 되어있음.
List Collection
List : 자료형의 개수가 계속 변하는 상황에서 유리한 자료구조 형태
List 컬렉션은 객체 자체를 저장하는게 아니라 객체의 번지를 참조함.
package chapter11.list;
import java.util.ArrayList;
import java.util.List;
public class ArrayListExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
// 요소 추가
list.add("안");
list.add("녕");
list.add("하");
list.add("세");
list.add("요");
// 요소 검색
String element1 = list.get(0);
boolean element2 = list.contains("안"); // boolean 리턴. 포함되어있으면 true, 아니면 false.
String element3 = list.get(1);
System.out.println(element1);
System.out.println(element2);
System.out.println(element3);
// 객체 삭제
System.out.println(list);
list.remove(4);
list.remove(3);
list.remove(2);
System.out.println(list);
// null
list.clear(); // 리스트 안에 있는 모든 요소들 삭제
if (list.isEmpty() && list != null) { // NullPointException 피하기
System.out.println("list가 비어있습니다.");
}
}
}
List 컬렉션에서 공통적으로 사용 가능한 List 인터페이스 메소드
ArrayList
List 인터페이스의 구현 클래스, ArrayList에 객체를 추가하게 되면 객체가 인덱스로 관리됨. 일반 배열과 ArrayList는 인덱스로 객체를 관리한다는 점에서 동일.
List<E> list = new ArrayList<E>();
- ArrayList에 객체를 추가하면 인덱스 0부터 차례대로 저장됨. 만약 ArrayList에서 특정 인덱스의 객체를 제거하면 모두 앞으로 1씩 당겨짐.
- 따라서 빈번한 객체 삭제와 삽입이 일어나는 곳에서는 ArrayList 사용이 바람직하지 않음.→ 이땐 LinkedList가 더 나음.
- 인덱스 검색, 맨 마지막 객체 추가시엔 좋은 성능을 발휘함.
LinkedList
List 구현 클래스. LinkedList는 인접 참조를 링크해서 체인처럼 관리함.
List<E> list = new LinkedList<E>();
- LinkedList에서 특정 인덱스의 객체를 제거하면 앞뒤 링크만 변경되고 나머지 링크는 변경되지 않음. 삽입시도 마찬가지
중간에 요소 추가 또는 삭제시엔 앞 뒤 링크만 변경하면 되는 LinkedList가 더 빠름. ArrayList는 뒤쪽 인덱스들을 모두 1씩 증가 또는 감소 시키는 시간이 필요하므로 처리 속도가 더 느림.
Set Collection
set 컬렉션은 저장 순서가 유지되지 않음. 또한 객체를 중복해서 저장할 수 없음.
HashSet
Set<E> set = new HashSet<E>();
- HashSet은 객체들을 순서 없이 저장하고 동일한 객체는 중복 저장하지 않음.
- HashSet은 객체를 저장하기 전에 먼저 객체의 hashCode() 메소드를 호출해서 해시코드를 얻어냄. 그리고 이미 저장되어있던 객체들의 해시코드와 비교함. 만약 동일한 해시코드가 있다면 equals() 메소드로 두 객체 비교 후 true가 나오면 동일한 객체로 판단하고 중복 저장하지 않음.
package chapter11.list;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class HashSetExample {
public static void main(String[] args) {
// 객체 생성
Set<String> stringSet = new HashSet<>();
stringSet.add("요소1");
stringSet.add("요소2");
stringSet.add("요소3");
stringSet.add("요소1");
System.out.println(stringSet);
// 객체 검색 (iterator 사용)
Iterator<String> iterator = stringSet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
System.out.println(stringSet.size());
// 향상된 for문
for (String str : stringSet) {
System.out.println(str);
}
// 객체 삭제
boolean element1 = stringSet.remove("요소2"); // remove의 리턴값은 bool. 삭제가 됐으면 true.
System.out.println(element1);
stringSet.clear(); // 내용 전부 삭제
System.out.println(stringSet);
}
}
Map Collection
Map 컬렉션은 키(key)와 값(value)으로 구성된 객체를 저장하는 구조임. 키는 중복될 수 없지만 값은 중복 저장될 수 있음.
Map 컬렉션에서 공통적으로 사용 가능한 Map 인터페이스 메소드
HashMap
Map 인터페이스를 구현한 대표적인 Map 컬렉션
Map<K, V> map = new HashMap<K, V>(); // K: 키 타입 파라미터, V: 값 타입 파라미터
package chapter11;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapExample {
public static void main(String[] args) {
HashMap<String, Integer> hashmap = new HashMap<>();
// 객체 생성
hashmap.put("key1" , 1);
hashmap.put("key2" , 2);
hashmap.put("key3" , 3);
System.out.println("객체 생성 : "+hashmap);
// 객체 찾기
System.out.println("\\nget으로 값 뽑아내기 : "+hashmap.get("key1"));
// getOrDefault() 메소드 사용
System.out.println("getOrDefault() : "+hashmap.getOrDefault("key4", 4));
boolean isContains = hashmap.containsKey("X");
System.out.println("\\nisContains : " + isContains);
boolean containsValue = hashmap.containsValue(3);
System.out.println("containsValue : " + containsValue);
// 객체를 하나씩 처리
Set<String> keySet = hashmap.keySet();
System.out.println("\\nkeySet : "+keySet);
// 객체 삭제
System.out.println("\\nremove 전 : "+hashmap);
hashmap.remove("key2");
System.out.println("remove 후 : "+hashmap);
// Entry 사용 (key, value 쌍을 전체 순회할 수 있음. 따로 단독으로 뽑아낼 수 있음)
Set<Map.Entry<String, Integer>> entrySet = hashmap.entrySet();
for (Map.Entry<String, Integer> entry : entrySet) { // entry 에는 key, value 쌍 묶음이 들어있음
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println("\\nkey, value : "+key+", "+value);
System.out.println("key만 : "+key);
}
}
}
- get()과 getOrDefault()의 차이점 잘 알아두기
→ getOrDefault() : null 대신 기본 값을 반환하도록 함.
Hashtable
HashMap과 동일한 내부 구조를 가지고 있음.
하지만 Hashtable은 동기화된 (synchronized) 메소드로 구성되어있기 때문에 멀티 스레드가 동시에 이 메소드를 실행할 수 없고, 하나의 스레드가 실행을 완료해야 다른 스레드를 실행할 수 있음.
그래서 멀티 스레드 환경에서 안전하게 객체를 추가, 삭제할 수 있는 특징을 갖고있음. → thread safe 하다고 말함.
package chapter11;
import java.util.Hashtable;
import java.util.Map;
import java.util.Scanner;
public class HashTableExample {
public static void main(String[] args) {
Map<String, String> map = new Hashtable<>();
map.put("spring", "qwer");
map.put("sumer", "qwer1234");
map.put("fall", "qwer123");
map.put("winter", "qwe123");
Scanner scanner = new Scanner(System.in); // 키보드로 부터 입력된 내용을 받기 위해 생성
while (true) {
System.out.println("아이디와 비밀번호를 입력해주세요");
System.out.println("아이디: ");
String id = scanner.nextLine(); // 키보드로 입력한 아이디를 읽는다
System.out.println("비밀번호: ");
String password = scanner.nextLine();
System.out.println();
if (map.containsKey(id)) {
if (map.get(id).equals(password)) {
System.out.println("로그인이 되었습니다");
break;
} else {
System.out.println("비밀번호가 일치하지 않습니다!");
}
} else {
System.out.println("입력하신 아이디가 존재하지 않습니다!\\n");
}
if (map.containsKey(id)){
if (map.getOrDefault(id,"").equals(password)){
System.out.println("로그인이 되었습니다.");
break;
} else {
System.out.println("비밀번호가 일치하지 않습니다.");
}
} else {
System.out.println("아이디가 일치하지 않습니다.");
}
}
}
}
'Back-End > Java # 교육' 카테고리의 다른 글
[Java 교육] 람다식 마무리/스트림 (다시 복습 필수) (1) | 2024.02.19 |
---|---|
[Java 교육] LIFO,FIFO 컬렉션/람다식 (다시 복습 필수 - 람다식) (1) | 2024.02.16 |
[Java 교육] 제한된 타입/와일드카드 타입/제네릭 상속, 구현 (1) | 2024.02.14 |
[Java 교육] 자동 리소스 닫기/중간정리/제네릭 (1) | 2024.02.08 |
[Java 교육] 사용자 정의 예외/트랜잭션 (1) | 2024.02.07 |