STUDY/Java

[Java] 컬렉션 (Collection)

ofijwe 2024. 10. 30. 17:14
반응형

📒 List 계열

1️⃣ 자료구조

  • 데이터 값의 모임, 또 데이터 간의 관계, 그리고 데이터에 적용할 수 있는 함수나 명령을 의미

2️⃣ 배열

  • 가장 기본적인 자료 구조
  • homeogeneous collection : 동일한 데이터 타입만 관리 가능
  • Polymorphism
    • Object를 이용하면 모든 객체 참조 가능 → Collection Framework
    • 담을 땐 편리, 빼낼 땐 Object로만
    • 런타임에 실제 객체의 타입 확인 후 사용해야 하는 번거로움
  • Generic을 이용한 타입 한정
    • 컴파일 타임에 저장하려는 타입 제한 → 형변환의 번거로움 제거

3️⃣ Collection Framework

  • java.util 패키지
    • 다수의 데이터를 쉽게 처리하는 방법 제공 → DB처럼 CRUD 기능 중요
  • Collection framework 핵심 interface
    • List : 입력 순서가 있는 데이터 집합
    • Set : 입력 순서를 유지하지 않는 데이터의 집합
    • Map : key와 value의 쌍으로 데이터를 관리하는 집합
  • Collection interface (CRUD)

4️⃣ Collection Framework - List

  • 특징
    • 입력 순서가 있는 데이터의 집합
    • 입력 순서가 있으므로 데이터의 중복 허락
  • 배열과 ArrayList
    • 장점
      • 가장 기본적인 형태의 자료 구조로 간단하며 사용이 쉬움
      • 접근 속도가 빠름
    • 단점
      • 크기를 변경할 수 X, 추가 데이터를 위해 새로운 배열을 만들고 복사해야 함
      • 비 순차적 데이터의 추가, 삭제에 많은 시간이 걸림
  • LinkedList
    • 각 요소를 Node로 정의하고 Node는 다음 요소의 참조 값과 데이터로 구성됨
    • 각 요소가 다음 요소의 링크 정보를 가지며 연속적으로 구성될 필요 X
  • 결론
    • 특정 클래스가 좋고 나쁨이 나닌 용도에 적합하게 사용해야 함
    • 소량의 데이터를 가지고 사용할 경우 큰 차이 X
    • 정적인 데이터 활용, 단순한 데이터 조회 → ArrayList
    • 동적인 데이터 추가, 삭제가 많은 작업 → LinkedList
  • 자료 삭제 시 주의사항
    • index를 이용한 for문
      • 요소가 삭제되면 size가 줄어들기 때문에 index 차감 필요
      • 거꾸로 접근하면 자연스럽게 해결
    • forEach 문장은 Collection 크기가 불변해야함.

📒 Set 계열

1️⃣ Set interface

  • 입력 순서 관리 X, 주머니에 데이터를 넣는 형태
  • 데이터를 구별할 순서 X, 중복 허용 X

📒 Map 계열

1️⃣ Map interface

  • Key와 Value를 하나의 Entry로 묶어서 데이터 관리
    • Key : Object 형태로 데이터 중복을 허락 X
    • Value : Object 형태로 데이터 중복 허락 O

📒 정렬

1️⃣ 정렬

  • 요소를 특정 기준에 대한 내림차순 또는 오름차순으로 배치하는 것
  • 크기를 비교할 수 있는 요소를 가지는 Colection들만 정렬 가능
    • List 계열
    • Set에서는 SortedSet의 자식 객체
    • Map에서는 SortedMap의 자식 객체(key 기준)
  • Collections의 sort()를 이용한 정렬
    • sort(List<T> list)

2️⃣ Comparator의 활용

  • 객체가 Comparable을 구현하고 있지 않거나 사용자 정의 알고리즘으로 정렬하려는 경우
  • sort(List<T> list, Comparator<? Super T> c)
  • public interface Comparator<T> { int compare(T o1, T o2); } public class StringLengthComparator implements Comparator<String> { @Override public int compare(String o1, String o2) { int len1 = o1.length(); int len2 = o2.length(); return Integer.compare(len1, len2); } } public void StringLengthSort() { Collections.sort(names, new StringLengthComparator()); System.out.println(names); }
  • 1회성 객체 사용 시 anonymous inner class 사용
    • 클래스 정의, 객체 생성 한 번에 처리
    • Collections.sort(names, new StringLengthComparator()); Collections.sort(names, new Comparator<String>() { @Override public int compare(String o1, String o2) { return Integer.compare(o1.length(), o2.length()); } });
    • 람다 표현식 이용
    • Collections.sort(names, (o1, o2) -> { return Integer.compare(o1.length(), o2.length()); });

📒 Lambda 표현식

1️⃣ Lambda 식

  • 함수적 프로그래밍의 형태로 재사용 가능한 코드 블록
  • 기존의 anonymous inner class를 이용한 처리 방식을 간결하게 처리

2️⃣ Lambda 표현식

  • 타겟 타입 또는 함수형 인터페이스
    • Lambda 식이 할당되는 인터페이스를 Lambda 식의 타겟 타입이라 함.
    • 타겟 타입은 abstract 메서드가 반드시 하나만 존재해야 함(default, static 등 무관)
  • @FunctionalInterface
    • 컴파일러가 하나의 abstract method만 있음을 체크
    • 그렇지 않을 경우 오류 발생 → 안정적인 programming을 위한 option
  • abstract method가 2개 이상 존재하는 경우는 여전히 익명의 inner class 사용
  • 기본 Lambda 식 : @FunctionalInterface에 대한 구현체 작성법
    • (type variable_name[,…]) → {실행문;};

3️⃣ Lambda 실행 블록에서의 변수 참조

  • Lambda 식 내부에서의 this는 외부 클래스의 instacne
    • 외부 클래스의 member 변수 : 접근제한자의 제약 없이 사용 가능
    • 외부 메서드의 local 변수 : final 키워드가 추가된 것으로 동작 → read only

4️⃣ 함수형 프로그래밍

  • java.util.function package
    • 일반적으로 객체지향의 java 프로그래밍은 메서드의 구조와 이름이 중요
    • 일반적인 함수형 프로그래밍 언어에서 함수의 타입은 구조적이며 이름이 불필요

5️⃣ 표준 API

  • 기본 제공 API 종류
    • 자주 사용되는 함수적 표준 interface를 java.util.function package에 정의
    • 주로 메서드 또는 생성자의 parameter로 Lambda식을 제공하기 위함
  • Consumer 계열
    • parameter는 있으며 return이 없는 형태
    • parameter 타입에 따라 다양한 consumer 존재
  • Supplier 계열
    • parameter는 없으며 return이 있는 형태
    • retrun 타입에 따라 다양한 supplier 존재
  • Function 계열
    • parameter와 return 값이 있는 형태
    • parameter와 return type에 따라 다양한 인터페이스 존재
    • 주로 파라미터를 이용해 연산을 수행한 후 원하는 타입으로 반환하는 역할
  • Operator 계열
    • function 계열과 유사: parameter와 return 값을 가짐
  • Predicate 계열
    • parameter를 받고 boolean 타입을 리턴

6️⃣ 메서드 참조와 생성자 참조

  • 람다 실행문 내부에서 다른 함수 하나만을 실행하는 겨우 :: 연산자를 이용해 기존 메서드 참조
    • <소유자>::<파라미터를 사용하는 소유자의 메서드>
  • 파라미터의 인스턴스 메서드 참조
    • 객체의 클래스 :: 인스턴스 메서드
    • 첫 번재 파라미터는 메서드의 소유자
    • 나머지 파라미터는 메서드의 파라미터 순서대로 전달
  • 정적 메서드 참조
    • 클래스::정적 메서드
    • 모든 파라미터가 메서드의 파라미터로 순서대로 전달됨
  • 특정 객체의 instance의 메서드 참조
    • 객체 :: 인스턴스 메서드 형태
    • 객체의 메서드가 호출되며 파라미터는 메서드에 그대로 전달됨
  • 생성자 참조
    • 클래스명 :: new의 형식으로 생성자 참조
    • 파라미터의 개수, 타입에 의해 호출되는 생성자 결정

📒 Stream API

1️⃣ Stream

  • JDK 8에 추가된 java.util.stream package
  • 배열 및 Collection의 요소를 하나씩 참조해서 처리하는 목적
    • 람다와 내부 반복자를 이용해 컬렉션을 다루는 코드 간결화
  • Stream API 역할 및 특징
    • 컬렉션, 배열 등 데이터 소스에 대한 공통된 접근 방식 제공
    • 손쉬운 병렬 처리

2️⃣ Stream 자료 처리

  • 맵/리듀스 모델 지원
    • 맵: 데이터를 작은 단위로 나누어 처리
    • 리듀스: 결과를 모아서 최종 결과를 생성
    • 중간 처리들과 최종 처리를 조합해 사용
      • 중간 처리: 매핑, 필터링, 정렬 등 가공 처리
      • 최종 처리: 반복, 카운팅, 평균, 총합 등 집계 처리
    • 각각의 중간 처리는 새로운 스트림을 리턴하여 builder 패턴 적용
      • 기존 스트림의 내용을 수정하지 않음
    • 최종 처리는 최종적으로 원하는 값을 반환 → 한번 최종 처리 끝난 스트림 재사용 X
  • Stream의 종류와 획득
    • java.util.stream package에 정의
    • 종류
      • Stream - 객체 요소에 대한 처리
      • IntStream, LongStream, DoubleStream - 각각 int, long, double 데이터 처리
    • 획득
      • Collection, 배열, File, Random 및 Stream 클래스의 static method로 생성

3️⃣ 중간 처리

  • 필터링
  • 자르기
  • 정렬
  • 매핑(변환) - 스트림의 요소를 다른 요소로 대체하는 작업
  • 조회(주석)

4️⃣ 최종 처리

  • 반복 - forEach()
  • 매칭
  • 통계 - count(), sum() …
  • 집계(aggregate)
  • 사용자 정의 집계 처리 - reduce()
  • 조사 - findFirst(), findAny()
  • 결과 모으기 - collect()
  • 결과 모으기 - 분할(partioningBy())과 그룹핑(groupingBy())
반응형