강의를 들으며 내가 알고 있는 내용을 점검하고,
새로 배운 내용을 정리하며,
궁금한 내용을 알아가며 학습해나가는 것을 목표로 합니다.
Collection은 여러 데이터의 묶음을 추상화한 인터페이스입니다.
Collection 도입 이전에는 공통된 표준 인터페이스가 없어 프로그래머가 모든 종류의 컬렉션에서 작동할 수 있는 알고리즘을 짜는 일이 어려웠습니다.
그렇기 때문에 JDK 1.2 부터 Collection이 도입 된 후 다음과 같은 장점을 가지게 되었습니다.
(출처 : https://www.geeksforgeeks.org/collections-in-java-2/)
Collection을 Set, List, Queue 인터페이스가 구현 하고 있습니다.
그리고 각각의 클래스들이 이러한 상위 인터페이스를 상속받아 특정 자료구조를 구현합니다.
Map 인터페이스도 Collection 으로 보나 구조상의 차이로 인해 별도로 정의됩니다.
Iterator는 컬렉션에서 저장된 요소를 읽어오기 위한 방법을 표준화 하기 위한 인터페이스입니다.
Collection이 Iterable을 implements 하고 있기 때문에 컬렉션이 구현한 하위 클래스들도 Iterable의 iterator를 구현하여 사용할 수 있습니다.
기본적으로는 두 개의 메소드가 제공됩니다.
JDK 1.5 부터는 Enhance for문을 권장하고 있으며 같은 성능을 유지하면서도 코드의 명확성을 확보하고 버그를 예방해 줍니다.
하지만 여전히 요소의 선택적 제거나 대체 등을 수행하기 위해서는 iterator를 사용해야 합니다.
람다를 활용할 수 있는 기술 중 하나인 Stream은 데이터의 흐름입니다.
Java 8 이전에 배열 또는 컬렉션 인스턴스를 다루려면 for나 foreach를 통해 요소 하나씩을 꺼내서 다루었습니다. 이러한 방식은 로직이 복잡 해질수록 코딩이 어려워지는 단점이 있었습니다.
하지만 Stream을 사용하여 람다식을 통해 코드를 간결하게 표현하며 함수형으로 배열과 컬렉션을 처리할 수 있으며, 여러 고차함수를 사용하여 강력한 기능을 안정적으로 사용 가능합니다.
또 병렬처리가 간단하게 가능하여 더욱 빠르게 요소들을 처리 할 수 있습니다.
Stream은 크게
생성하기
Stream은 Stream 객체를 생성하여 사용할 수 있으며, 배열, 컬렉션, 수, 파일 등으로 스트림을 만들 수 있다. 단 재사용이 불가능해 연산이 끝나면 다시 생성해주어야 합니다.
가공하기
데이터를 가공하기 위한 중간 연산이며 연산 결과를 다시 Stream으로 다시 반환하기 때문에 계속 연산을 이어 나갈 수 있습니다. 이를 method chaining이라고 합니다.
결과 만들기
가공된 데이터로 원하는 결과를 얻기 위한 과정이며, Stream의 요소들을 소모하면서 진행하기 때문에 1번만 처리 가능합니다.
의 세 가지 단계로 나눌 수 있습니다.
자바에서는 거의 모든것이 레퍼런스 이기 때문에 결과 값이 언제나 null이 될 수 있습니다.
null로 인해 발생할 수 있는 에러인 NullPointerException을 피하고 확인하는 로직을 줄이기 위해 null 대신 초기값을 사용하는 것을 권장하기도 합니다. 또는 Empty 객체를 사용하여 빈 생성자를 만들어 이러한 과정에서의 에러를 체크하고 null 가드를 하기도 합니다.
하지만 자바 8 부터는 Optional을 사용해서 NullPointerException을 방지할 수 있습니다. Optional은 null이 올 수 있는 값을 한 번 더 감싸는 래퍼 클래스로서, null이 일어나지 않도록 방지 합니다.
//빈 객체 생성
Optional<String> opt = Optional.empty();
//문자열 값이 비어있는지 확인하고 비어 있으면 "null?"로 초기화
Optional<String> optional = Optional.ofNullable(getString());
String str = optional.orElse("null?");
또한 람다 계산식을 지원하며 스트림과 같이 생성 - 가공하기 - 결과 도출의 연산을 수행할 수 있습니다.