컬렉션 프레임워크 : 데이터를 효율적으로 저장하고 관리하기 위한 다양한 자료구조 클래스를 제공하는 라이브러리. 데이터의 추가, 삭제 검색, 정렬 등의 작업을 쉽게 처리 할 수 있음.
- ArrayList : 배열과 비슷하지만 크기가 동적으로 변함.
- 배열처럼 인덱스를 사용하여 요소에 접근할 수 있지만, 요소의 추가와 삭제가 더 유연.
- 요소가 추가되면 자동으로 크기가 조정되며, 중복된 값을 허용
- ArrayList의 주요 기능:
- add() : 요소 추가
- get() : 인덱스의 요소를 가져옴.
- size() : 리스트의 크기(개수)
- toString() : ArrayList의 모든요소를 문자열로 출력
- 형변환의 필요성: 기본적으로 Object 타입을 저장. 따라서 특정 타입의 요소를 가져올 때 다운캐스팅이 필요함.
System.out.println((String)data); // Object 타입을 String으로 형변환하여 출력
컬렉션 프레임워크의 장점: 동적 크기 증가, 성능 최적화, 데이터 추가/삭제의 유연성
[제네릭(Generic)]
->제네릭은 컬렉션 사용할 때 타입 안정성의 문제 발생을 해결하기 위한 기법, 타입 안정성을 높이고 형 변환을 줄여줌.
장점
- 타입의 안정성
- 코드 가독성
- 재사용성
제네릭과 컬렉션 프레임워크의 관계
제네릭은 컬렉션 프레임워크와 함께 사용되어, 컬렉션이 다루는 데이터의 타입을 명시적으로 지정할 수 있습니다. 제네릭을 사용하지 않으면, 모든 데이터가 Object로 처리되기 때문에, 데이터를 꺼낼 때마다 형변환이 필요합니다. 그러나 제네릭을 사용하면 컴파일 시점에 데이터 타입이 결정되므로 형변환이 필요 없고, 더 안전한 코드를 작성할 수 있습니다.
제네릭의 주요 특징
- 타입 파라미터: 제네릭 클래스나 메서드에서는 타입 파라미터를 사용합니다. 예를 들어, ArrayList<String>은 String 타입을 저장하는 ArrayList입니다. <T>, <E>, <K, V> 등과 같은 타입 파라미터를 사용할 수 있습니다.
- 컴파일 시 타입 검증: 제네릭을 사용하면 컴파일 시점에 타입을 체크하여 런타임 오류를 줄일 수 있습니다.
- 형변환 불필요: 제네릭을 사용하면 데이터를 꺼낼 때마다 형변환을 할 필요가 없어서 코드가 더 간결해집니다.
package com.util1;
import java.util.ArrayList;
public class ArrayListEx03 {
public static void main(String[] args) {
// 제네릭을 사용하지 않은 ArrayList (다양한 타입이 들어갈 수 있음)
ArrayList al = new ArrayList();
// 1. ArrayList에 다양한 타입의 데이터 추가
al.add("A"); // 문자열
al.add("B"); // 문자열
al.add(10); // 정수형 (int)
al.add(20); // 정수형 (int)
al.add('a'); // 문자형 (char)
al.add('b'); // 문자형 (char)
// 2. ArrayList의 요소 출력 (정상적으로 출력)
System.out.println(al); // 출력: [A, B, 10, 20, a, b]
// 3. ArrayList의 데이터 타입 불일치로 인한 문제 발생
// 이 코드는 컴파일 시에는 문제가 없지만, 실행 시 ClassCastException 오류 발생
for (int i = 0; i < al.size(); i++) {
// ArrayList에서 데이터를 가져올 때, Object로 반환되기 때문에
// 문자열로 형변환을 시도하지만, 정수나 문자형이 들어가 있으면 오류 발생
String data = (String) al.get(i); // 실행 중 ClassCastException 발생
System.out.println(data);
}
// 4. !!!!!!제네릭을 사용한 ArrayList!!!!
// 제네릭을 사용하여 String 타입으로만 데이터를 받도록 제한
ArrayList<String> al2 = new ArrayList<>();
// 5. ArrayList에 문자열만 추가
al2.add("aa");
al2.add("bb");
al2.add("cc");
// 6. 제네릭을 사용한 ArrayList에서 데이터를 가져올 때는 형변환이 필요 없음
// 타입 안정성이 보장되므로 String 타입으로 바로 가져올 수 있음
for (int i = 0; i < al2.size(); i++) {
String data = al2.get(i); // 형변환 필요 없음
System.out.println(data);
}
// 7. 향상된 for문을 사용하여 ArrayList의 요소 출력 (더 간결하게 표현 가능)
for (String data : al2) {
System.out.println(data); // 형변환 없이 바로 출력
}
}
}
[Set]
HashSet은 컬렉션 프레임워크에서 제공하는 Set 인터페이스를 구현한 클래스 중 하나로, 중복된 요소를 허용하지 않고 순서가 없는 데이터 집합을 관리
1. HashSet의 특징
- 중복을 허용하지 않음: 동일한 값이 두 번 이상 저장되지 않습니다. 즉, 중복 요소는 자동으로 제거됩니다.
- 순서가 없음: HashSet에 저장된 요소들은 저장된 순서대로 출력되지 않습니다. 순서가 중요한 경우에는 LinkedHashSet이나 TreeSet을 사용하는 것이 좋습니다.
- 빠른 접근 속도: 내부적으로 해시맵(HashMap)을 사용하기 때문에 검색, 삽입, 삭제 등의 연산이 빠르게 수행됩니다. (평균적으로 O(1) 성능)
- null 값 허용: 단, HashSet은 한 개의 null 값만을 저장할 수 있습니다.
HashSet에서 equals()와 hashCode()의 역할
HashSet이 객체를 저장할 때, 먼저 객체의 해시 코드를 계산해서 같은 해시 코드가 있는지 확인합니다. 만약 같은 해시 코드를 가진 객체가 이미 존재한다면, HashSet은 equals() 메서드를 사용하여 실제 내용이 동일한지 확인합니다. 내용이 동일하면 중복된 객체로 간주하고 저장하지 않습니다.
// HashSet 생성 (제네릭으로 String 타입만 허용)
HashSet<String> set = new HashSet<>();
// 요소 추가 (add 메서드 사용)
set.add("홍길동");
set.add("박문수");
set.add("임꺽정");
set.add("홍길동"); // 중복된 값은 무시됨
// HashSet 출력 (저장 순서는 보장되지 않음)
System.out.println(set); // 출력: [임꺽정, 박문수, 홍길동]
equals()와 hashCode()의 동작 원리
- 해시 코드를 비교: 새로운 객체가 HashSet에 추가될 때, 먼저 객체의 해시 코드를 확인합니다. 같은 해시 코드를 가진 객체가 이미 있다면, 중복될 가능성이 있다고 판단합니다.
- equals()로 비교: 같은 해시 코드를 가진 객체가 있다면, equals() 메서드를 통해 실제로 같은 객체인지를 확인합니다. equals() 결과가 true면 중복된 객체로 처리되어 저장되지 않습니다.
- 중복된 객체 거부: equals() 메서드에 의해 같은 객체로 판단된 경우, HashSet은 해당 객체를 저장하지 않습니다.
[Map]
Map 인터페이스와 HashMap 클래스
Map 인터페이스는 자바 컬렉션 프레임워크에서 키(key)와 값(value)의 쌍으로 데이터를 저장하는 자료구조를 정의하는 인터페이스입니다. HashMap은 Map 인터페이스를 구현한 대표적인 클래스 중 하나로, 데이터를 해시 테이블 방식으로 관리합니다.
HashMap의 특징:
- 순서가 없음: HashMap은 요소가 삽입된 순서를 보장하지 않습니다.
- 중복된 키는 허용되지 않음: 중복된 키를 허용하지 않으며, 같은 키로 다시 값을 삽입하면 기존 값이 덮어쓰기됩니다.
- 빠른 성능: HashMap은 O(1)의 시간 복잡도로 검색, 삽입, 삭제를 처리할 수 있습니다.
- null 허용: 키와 값에 null을 허용합니다. 단, 키는 한 번만 null 값을 가질 수 있고, 값에는 여러 번 사용할 수 있습니다.
HashMap의 주요 메서드
- put(K key, V value): 주어진 키와 값을 HashMap에 저장합니다. 만약 같은 키가 이미 존재하면, 새로운 값으로 덮어씁니다.
- get(Object key): 주어진 키에 해당하는 값을 반환합니다. 키가 존재하지 않으면 null을 반환합니다.
- remove(Object key): 주어진 키에 해당하는 값을 삭제합니다.
- containsKey(Object key): 주어진 키가 존재하는지 여부를 확인합니다. 존재하면 true, 없으면 false를 반환합니다.
- containsValue(Object value): 주어진 값이 존재하는지 여부를 확인합니다. 값이 존재하면 true, 없으면 false를 반환합니다.
- keySet(): HashMap에 존재하는 모든 키를 Set 형태로 반환합니다.
- values(): HashMap에 존재하는 모든 값을 Collection 형태로 반환합니다.
// 사용자 정의 클래스도 Map에 지정 가능
// 1. Student 객체 생성 (학번과 이름을 인자로 전달)
Student s1 = new Student("1001", "박");
Student s2 = new Student("1002", "홍");
Student s3 = new Student("1003", "임");
// 2. HashMap 생성 (키는 String 타입, 값은 Student 객체 타입)
HashMap<String, Student> map = new HashMap<>();
// 3. HashMap에 키-값 쌍으로 Student 객체 추가
map.put("a", s1); // "a" 키에 박 객체 추가
map.put("b", s2); // "b" 키에 홍 객체 추가
map.put("c", s3); // "c" 키에 임 객체 추가
// 4. HashMap 전체 출력 (키-값 쌍으로 출력)
// 출력 형식: {키1=값1, 키2=값2, ...}
System.out.println(map); // {a=박, b=홍, c=임}
// [실습] HashMap의 키셋과 값컬렉션을 추출하고 반복문으로 출력해보세요.
// HashMap의 모든 키를 가져오기 (keySet 메서드 사용)
Set<String> keys = map.keySet();
// 각 키를 출력
for (String key : keys) {
System.out.println(key); // "a", "b", "c" 출력
}
// HashMap에 저장된 모든 값을 가져오기 (values 메서드 사용)
Collection<Student> values = map.values();
// 각 값을 출력 (toString 메서드를 통해 Student 객체 출력)
for (Student value : values) {
System.out.println(value); // 박, 홍, 임 출력
[Properties]
Properties 클래스
Properties 클래스는 키와 값을 문자열(String) 형태로 저장하는 특수한 HashMap 클래스입니다. 자바에서 설정 파일(예: .properties 파일)을 읽고 쓰는 데 자주 사용되며, 시스템 설정이나 애플리케이션의 구성 정보를 관리할 때 유용합니다. 기본적으로 키-값 쌍으로 데이터를 저장하는데, 키와 값이 모두 문자열로 제한됩니다.
Properties 클래스는 자바의 Hashtable 클래스를 상속받았으며, 키와 값이 모두 문자열이어야 한다는 특징을 제외하고는 다른 맵 클래스와 유사한 동작을 합니다.
주요 특징:
- 문자열 기반: Properties는 키와 값이 모두 문자열로 저장됩니다.
- 파일 입출력 지원: .properties 파일 형태로 설정 정보를 읽고 쓰는 기능을 제공합니다.
- 시스템 설정 접근: 자바 시스템 설정이나 환경 변수 등의 정보를 쉽게 얻을 수 있습니다.
System.getProperties() (Java SE 17 & JDK 17)
[Stack 과 Queue]
| 동작원리 | 삽입 위치 | 삭제위치 | 주요메서드 | |
| Stack | LIFO | 맨 위 | 맨위 | push() pop() peek() |
| Queue | FIFO | 맨 뒤 | 맨 앞 | offer() poll() peek() |
Stack과 Queue의 사용 사례
- Stack 사용 사례:
- 함수 호출 스택
- 브라우저 뒤로가기
- Queue 사용 사례:
- 프린터 작업 대기열
- 프로세스 관리
- Stack
- push() : 스택의 맨 위에 요소를 추가
- add() : 리스트처럼 작동하여 요소를 맨끝에 추가
- get() : 특정 인덱스에 있는 요소 가져옴
- pop() : 스택 맨 위에 있는 요소를 제거하고 반환
// Stack 객체 생성 (String 타입)
Stack<String> stack = new Stack<>();
// 1. 요소 추가 (push 메서드 사용)
// 스택의 맨 위에 요소를 추가
stack.push("홍길동");
stack.push("박문수");
stack.push("임꺽정"); // (임꺽정으로 수정)
// 2. 스택의 현재 상태 출력
System.out.println(stack); // 출력: [홍길동, 박문수, 임꺽정]
// 3. add() 메서드로 요소 추가
// add() 메서드는 스택에서 제공되지만 일반 리스트의 추가처럼 사용됨
stack.add("이몽룡"); // 스택의 맨 마지막(리스트의 끝)에 추가
System.out.println(stack); // 출력: [홍길동, 박문수, 임꺽정, 이몽룡]
// 4. 특정 인덱스의 요소 가져오기 (get 메서드 사용)
// 스택의 3번째 인덱스(즉, 네 번째 요소)를 가져옴
String data = stack.get(3);
System.out.println(data); // 출력: 이몽룡
System.out.println(stack); // 출력: [홍길동, 박문수, 임꺽정, 이몽룡]
// 5. 스택에서 맨 위 요소 제거 (pop 메서드 사용)
// 스택의 맨 위 요소를 제거하고 반환
String popData = stack.pop();
System.out.println(popData); // 출력: 이몽룡
System.out.println(stack); // 출력: [홍길동, 박문수, 임꺽정]
- Queue
- offer() : 큐의 맨 뒤에 요소를 추가
- peek() : 큐의 맨 앞에 있는 요소를 제거하지 않고 가져옴
- poll() : 큐의 맨 앞에 있는 요소를 제거하고 반환
// Queue 객체 생성 (LinkedList 사용)
Queue<String> queue = new LinkedList<>();
// 1. 요소 추가 (offer 메서드 사용)
// 큐의 맨 뒤에 요소를 추가
queue.offer("홍길동");
queue.offer("박문수");
queue.offer("임꺽정");
// 2. 큐의 현재 상태 출력
System.out.println(queue); // 출력: [홍길동, 박문수, 임꺽정]
// 3. 특정 요소 추가 (offer 메서드 사용)
// 큐의 맨 뒤에 새로운 요소를 추가
queue.offer("이몽룡");
System.out.println(queue); // 출력: [홍길동, 박문수, 임꺽정, 이몽룡]
// 4. 큐의 맨 앞 요소 가져오기 (peek 메서드 사용)
// 큐의 맨 앞에 있는 요소를 제거하지 않고 가져옴
String data = queue.peek();
System.out.println(data); // 출력: 홍길동
System.out.println(queue); // 큐는 변하지 않음: [홍길동, 박문수, 임꺽정, 이몽룡]
// 5. 큐에서 맨 앞 요소 제거 (poll 메서드 사용)
// 큐의 맨 앞 요소를 제거하고 반환
String polledData = queue.poll();
System.out.println(polledData); // 출력: 홍길동
System.out.println(queue); // 출력: [박문수, 임꺽정, 이몽룡]'Backend > Java' 카테고리의 다른 글
| [Java] 중첩클래스 (0) | 2024.10.31 |
|---|---|
| [Java]Java IO(Exception/throw/File/스트림) (0) | 2024.10.24 |
| [java] System/Data/Calendar/Random/Array 클래스 (0) | 2024.10.22 |
| [java]java.lang 패키지 (0) | 2024.10.21 |
| [java]상속/은닉/다형성/추상클래스/interface (1) | 2024.10.18 |