728x90
컬렉션 프레임워크
@2024.04.15
컬렉션 프레임워크는 프로그래밍 언어에서 데이터 집합을 효율적으로 처리할 수 있는 라이브러리
핵심은 데이터를 저장, 검색 ,조작 통신할 때 일관된 접근 방식을 제공한다는 것

Collection Interface
💡
자바 컬렉션 프레임 워크의 근간을 이루며, List/Set/Queue와 같은 여러 하위 인터페이스를 포함한다.
- 주요 기능
- 저장과 접근 : 다수의 객체를 저장하고 저장된 객체들에 접근하는 기능 제공
- 크기 조회 : 컬렉션에 저장된 객체의 수를 확인하는 메서드 제공
- 데이터 수정 : 객체의 추가, 삭제와 같은 수정 기능 제공
- 데이터 검색 : 특정 객체가 존재하는지 확인하는 기능 제공
- Collection을 상속받는 주요 인터페이스 : List 인터페이스, Set 인터페이스, Queue 인터페이스
List Interface
💡
순서가 있는 데이터의 컬렉션으로 동일한 요소의 중복을 허용한다.
- 순서가 중요하거나 동일한 요소의 반복 처리가 필요한 경우 사용
- ArrayList 구현 클래스
- 배열을 사용하여 인덱스를 통한 빠른 접근 가능
- 요소 추가 및 삭제 시 다른 요소들의 이동이 필요
// ArrayList 생성 List<String> fruits = new ArrayList<>(); // 요소 추가 fruits.add("바나나"); fruits.add("포도"); //인덱스로 요소에 접근 fruits.get(1) // 포도 //인덱스로 요소 수정 fruits.set(1,"사과") // 바나나를 사과로 //인덱스로 특정 요소 삭제 fruits.remove(1) // 사과 포도 //요소의 개수(크기) 출력 fruits.size(); // 1 //리스트가 비어있는지 확인하여 true,flase 반환 fruits.isEmpty(); // flase // 해당 요소가 있는지 확인후 true/false반환 fruits.contains("사과"); // true //리스트 내용 출력 System.out.println(fruits) //[사과] // 해당 요소가 처음 등장하는 인덱스 반환 fruits.indexOf("사과") // 0 // 리스트 모든 요소 삭제 fruits.clear();
- LinkedList 구현 클래스
- 이중 연결 리스트를 사용하여 요소를 관리
- 데이터 삽입 및 삭제가 빠르나, 임의 접근에는 상대적으로 시간이 더 걸린다
// LinkedList 생성 List<String> fruits = new LinkedList<>(); // 요소 추가 fruits.add("바나나"); fruits.add("포도"); // 인덱스로 요소에 접근 System.out.println(fruits.get(1)); //포도 // 인덱스로 요소 수정 fruits.set(1, "사과"); // 바나나를 사과로 // 인덱스로 특정 요소 삭제 fruits.remove(1); // 사과 삭제 // 요소의 개수(크기) 출력 System.out.println(fruits.size()); // 1 // 리스트가 비어있는지 확인하여 true/false 반환 System.out.println(fruits.isEmpty()); // false // 해당 요소가 있는지 확인 후 true/false 반환 System.out.println(fruits.contains("사과")); // true // 리스트 내용 출력 System.out.println(fruits); // [바나나] // 해당 요소가 처음 등장하는 인덱스 반환 System.out.println(fruits.indexOf("바나나")); // 0 // 리스트 모든 요소 삭제 fruits.clear();
- Vector 구현 클래스
- ArrayList와 유사하나, 동기화를 지원하여 스레드에 안전한 방식으로 구현
- 멀티 스레드 환경에서 사용하기 적합하지만, 성능이 다소 느리다.
- Stack 구현 클래스
- Vector를 상속받은 클래스로, LIFO(후입선출) 방식의 데이터 처리에 사용
Set Interface
💡
순서에 관계없이 요소를 관리하는 데이터 컬렉션으로 중복을 허용하지 않는다.
- HashSet 구현 클래스
- 가장 자주 사용되는 Set 구현체로, 내부적으로 HashMap를 사용하여 요소를 저장
- 해시 테이블을 사용하여 빠른 접근 속도 제공
// HashSet 생성 Set<String> fruits = new HashSet<>(); // 요소 추가 fruits.add("바나나"); fruits.add("포도"); 1 // 중복 요소를 추가하려고하나, 추가가 안된다. -> object.equals로 중복 요소 체크 fruits.add("포도"); //해당 요소가 있는지 확인후 true/false반환 fruits.contains("포도") // true //요소 제거 fruits.remove("포도") //리스트가 비어있는지 확인하여 true,flase 반환 fruits.isEmpty(); // flase // 요소의 개수(크기) 출력 fruits.size(); // 1 // 리스트 모든 요소 삭제 fruits.clear(); // 배열로 반환 Object[] array = fruits.toArray();
- LinkedHashSet 구현 클래스
- HashSet과 유사하지만, 요스를 삽입 순서대로 유지한다.
- LinkedList의 형태로 데이터를 저장하여 순서를 보존
- TreeSet 구현 클래스
- 레드-블랙 트리 구조를 사용하여 정렬된 상태 유지
- 요소들을 정렬된 순서대로 저장하고, 검색, 삭제, 삽입 작업을 효율적으로 수행
Queue Interface
💡
FIFO(First In First Out)로 요소를 처리할 때 사용한다.
- LinkedList 구현 클래스
- PriorityQueue 구현 클래스
Map Interface
💡
키와 값을 한 쌍으로 저장하는 순서가 없는 데이터 구조이며, 각 키는 고유값을 가지므로 해당 키에 매핑된 값을 검색할 수 있다.
- HashMap 구현 클래스
- 가장 자주 사용되는 map 구현체로 해시 테이블을 사용해 키-값 쌍을 관리
- 순서를 보장하지 않으며, null 키와 값이 허용
import java.util.HashMap; import java.util.Map; public class HashMapExample { public static void main(String[] args) { // HashMap 객체 생성 Map<String, Integer> hashMap = new HashMap<>(); // put 메서드를 사용하여 요소 추가 hashMap.put("apple", 10); hashMap.put("banana", 20); hashMap.put("orange", 15); // get 메서드를 사용하여 값 가져오기 System.out.println("apple의 값: " + hashMap.get("apple")); // containsKey 메서드를 사용하여 키 확인 System.out.println("grape이 맵에 포함되어 있는가? " + hashMap.containsKey("grape")); // size 메서드를 사용하여 맵의 크기 확인 System.out.println("맵의 크기: " + hashMap.size()); // remove 메서드를 사용하여 요소 제거 hashMap.remove("banana"); // keySet 메서드를 사용하여 모든 키 가져오기 System.out.println("모든 키: " + hashMap.keySet()); // values 메서드를 사용하여 모든 값 가져오기 System.out.println("모든 값: " + hashMap.values()); // entrySet 메서드를 사용하여 모든 키-값 쌍 가져오기 System.out.println("모든 키-값 쌍: " + hashMap.entrySet()); // clear 메서드를 사용하여 맵 비우기 hashMap.clear(); // isEmpty 메서드를 사용하여 맵이 비어 있는지 확인 System.out.println("맵이 비어 있는가? " + hashMap.isEmpty()); } }
- LinkedHashMap 구현 클래스
- 요소들이 추가된 순서 또는 접근 순서를 유지
- TreeMap 구현 클래스
- 레드-블랙 트리 기반의 Map 구현체
- 키에 따라 정렬된 순서로 키-값 쌍을 저장
- 키의 순서에 따라 정렬되거나, 제공된 Comparator에 의해 정렬
- HashTable 구현 클래스
- HashMap과 유사하나, 동기화를 지원
- 멀티 스레드 환경에서 안전하게 사용 가능
- 일반적으로 ConcurrentHashMap을 사용하는 것이 더 바람직
Iterator Interface
💡
컬렉션의 구조와 관계없이 동일한 방식으로 저장된 요소를 읽거나 제거하는 방법을 제공하는 인터페이스
- 인터페이스 = 표준 같은 느낌, Iterater → 읽고 제거하는 방법이 표준
- 컬렉션 내의 요소를 순차적으로 접근할 수 있으며, 컬렉션의 구조와 상관없이 동일한 방법으로 데이터를 처리할 수 있다.
- 주요 기능
- 순차적 접근
- 컬렉션 내의 요소를 순서대로 접근
⇒ 컬렉션의 내부 구조를 몰라도 각 요소에 접근 가능
- 컬렉션 내의 요소를 순서대로 접근
- 안전한 요소 제거
- Iterator의 remove()을 통해 요소를 제거 가능
- 컬렉션을 직접 조작하여 발생할 수 있는 동시성 문제를 방지
- 단방향 이동
- 컬렉션의 요소를 앞에서 뒤로만 이동하며 접근한다.
- 순차적 접근
- List 계열 클래스, Set 계열 클래스, Map 계열 클래스는 모두 Iterator를 지원
ArrayList<String> fruits = new ArrayList<>(); fruits.add("사과"); fruits.add("바나나"); fruits.add("포도"); //fruits 컬렉션에 대한 Iteratort 인스턴스 iteratort 생성 Iterator<String> iterator = fruits.iterator(); //iterator가 가리키는 ArrayList 컬렉션 순회 => foreach과 동작 방식이 비슷 while(iterator.hasNext()){ // 다름 요소를 가지고 있는지 확인하고 있으면 true 반환 String fruit = iterator.next(); // 컬렉션의 요소 반환 후 iterator의 위치를 다음 요소로 이동 System.out.println(fruit); }
Utility Interface
💡
컬렉션과 배열을 조작하는 다양한 유틸리티 메서드 제공
Collections 클래스
💡
자바 표준 컬렉션 프레임워크에 포함된 클래스로, 다양한 컬렉션 관련 알고리즘과 정적 메서드를 제공
- 인스턴스화 할 수 없으며, 주로 컬렉션을 조작하거나 변환하는 데 사용되는 정적 메서드로 구성
- 주요 메소드
- Collections.sort(list)
- 주어진 리스트를 오름차순으로 정렬
// Comparator를 사용한 정렬 Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); // 이름을 기준으로 오름차순 정렬 } });
- Collections.synchronizedList(new ArrayList<>())
- 스레드 안전을 위해 동기화된 리스트 생성
- Collections.unmodifiableList(list)
- 읽기 전용 리스트를 생성하여 내용 변경을 방지
- Collections.shuffle(list)
- 주어진 리스트의 요소들을 무작위로 섞는 기능 제공
List<Integer> numbers = new ArrayList<>(); for (int i = 1; i <= 10; i++) { numbers.add(i); // 1부터 10까지 숫자를 리스트에 추가 } System.out.println("원래 순서: " + numbers); Collections.shuffle(numbers); // 리스트 섞기 System.out.println("섞은 후: " + numbers);
- Collections.sort(list)
Arrays 클래스
💡
배열과 관련된 다양한 작업을 수행하기 위한 유틸리티 메서드를 제공하는 유틸리티 클래스
- 유틸리티 : 프로그램이나 시스템에서 특정 작업을 수행하는 데 도움이 되는 도구나 기능
- 배열정렬
Arrays.sort(); // 예시 int[] array = {3, 1, 5, 2, 4}; Arrays.sort(array); //배열을 오름차순으로 정렬하며 반환값은 없고, 이미 정렬되어있음 {1,2,3,4,5}
- 배열 검색
Arrays.binarySearch() // 예시 int[] array = {3, 1, 5, 2, 4}; int index = Arrays.binarySearch(array, 3); //배열에서 3을 검색해서 인덱스 반환
- 배열 비교
Arrays.equals() // 예시 int[] array1 = {1, 2, 3}; int[] array2 = {1, 2, 3}; boolean isEqual = Arrays.equals(array1, array2); // 두 배열이 같은지 비교
- 같은 인덱스에 같은 값이 들어가있는지 비교
- int[] array1 = {1, 2, 3};
int[] array2 = {3, 2, 1}; 일때는 false 리턴
- int[] array1 = {1, 2, 3};
- 같은 인덱스에 같은 값이 들어가있는지 비교
- 배열 복사(깊은복사)
Arrays.copyOf() Arrays.copyOfRange() // 예시1 int[] array = {1, 2, 3, 4, 5}; int[] newArray1 = Arrays.copyOf(array, array.length); // 배열을 복사하여 새로운 배열 생성 // 예시2 int[] newArray2 = Arrays.copyOfRange(array, 1, 4); // 배열의 인덱스 1~4까지 요소를 복사하여 // 새로운 배열 생성
- 배열 출력
Arrays.toString() // 예시 int[] array = {1, 2, 3, 4, 5}; String arrayString = Arrays.toString(array); // 배열을 문자열로 변환하여 반환 // [1, 2, 3, 4, 5] 출력
- 배열 비교
Arrays.compare() // 예시 int[] array1 = {1, 2, 3}; int[] array2 = {1, 2, 4}; int result = Arrays.compare(array1, array2) // 배열비교
- 같은 인덱스별로 비교하며 같으면 0, 앞 배열이 더크면 1, 작으면 -1 반환
- 해당 예시는 0, 0, -1을 출력해서 result 값은 -1이 된다.
Comparable Interface
💡
객체를 비교할 때 사용되는 인터페이스로, 구현시 compareTo()를 오버라이드 하여 객체 간의 정렬 순서를 정의할 수 있다.
@기본 형태
@기본 형태
// T : 비교할 객체 타입
public int compareTo(T obj)
- compareTo()는 비교 대상 객체 obj와 호출한 객체를 비교
- 호출한 객체 > obj : 양수 반환
- 호출한 객체 < obj : 음수 반환
- 호출한 객체 = obj : 0 반환
- 예시 1
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Person implements Comparable<Person> { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } //예제 1 : int age값을 기준으로 정렬 @Override public int compareTo(Person other) { // 비교 대상 객체와 비교되는 객체의 값을 비교 // 이 예제에서는 정수 값을 기준으로 비교 return this.age - other.age; // 나이를 기준으로 오름차순 정렬 } //예제 2 : String name값을 기준으로 정렬 @Override public int compareTo(MyClass other) { // String의 compareTo 메서드를 사용하여 name을 기준으로 정렬합니다. return this.name.compareTo(other.name); }
- 예시 2
String str1 = "apple"; String str2 = "banana"; int result = str1.compareTo(str2); if (result < 0) { System.out.println("str1 is less than str2"); } else if (result > 0) { System.out.println("str1 is greater than str2"); } else { System.out.println("str1 is equal to str2"); }
Comparator Interface
💡
객체를 비교할 때 사용되는 인터페이스 중 하나며, 주로 정렬된 컬렉션을 사용할 때나,
Comparable 인터페이스를 구현하지 않은 클래스의 객체를 사용할 때 활용한다.
@기본 형태
Comparable 인터페이스를 구현하지 않은 클래스의 객체를 사용할 때 활용한다.
@기본 형태
// T : 비교할 객체 타입
int compare(T obj1, T obj2)
- 이 인터페이스는 compare()을 오버라이드 하여 두 객체를 비교하는 방식 제공
- compare() 메서드의 반환값
- obj1 > obj2 : 양수 반환
- obj1 < obj2 : 음수 반환
- obj1 = obj2 : 0 반환
- compare() 메서드의 반환값
- Comparable과 달리 객체 외부에서 정렬 기준을 정의하므로, 여러 다른 기준으로 객체를 정렬할 수 있다.
class Movie{ private String title; private int release; private double grade; public String getTitle(){ return title; } public double getGrade() { return grade; } public int getRelease() { return release; } } //Movie class에 실수형 점수를 기준으로 정렬 class RatingComparator implements Comparator<Movie> { @Override public int compare(Movie o1, Movie o2) { return Double.compare(o1.getGrade(),o2.getGrade()); } }
728x90
'JAVA' 카테고리의 다른 글
java.io 패키지 (0) | 2024.04.27 |
---|---|
데코레이터 패턴 (1) | 2024.04.27 |
제네릭 (1) | 2024.04.26 |
java.lang과 java.util 패키지 (0) | 2024.04.26 |
내부 클래스 (0) | 2024.04.25 |