본문 바로가기
JAVA

컬렉션 프레임워크

by 융디's 2024. 4. 27.
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);

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 리턴
  • 배열 복사(깊은복사)
    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 인터페이스를 구현하지 않은 클래스의 객체를 사용할 때 활용한다.


@기본 형태

// T : 비교할 객체 타입

int compare(T obj1, T obj2)

  • 이 인터페이스는 compare()을 오버라이드 하여 두 객체를 비교하는 방식 제공
    • compare() 메서드의 반환값
      • obj1 > obj2 : 양수 반환
      • obj1 < obj2 : 음수 반환
      • obj1 = obj2 : 0 반환
  • 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