반응형
일급 컬렉션이란
Collection을 Wrapping 하면서, 그 외 다른 멤버 변수가 없는 상태를 의미합니다.
일급 콜렉션 적용
- 다른 멤버 변수가 없어야 한다.
- 각 컬렉션은 그 자체로 포장되어 있으므로, 컬렉션과 관련된 동작은 해당 클래스에서만 이루어진다.
기존 코드
Map<String, String> map = new HashMap<>();
map.put("1", "A");
map.put("2", "B");
map.put("3", "C");
일급 컬렉션 코드
public class GameRanking {
private Map<String, String> ranks;
public GameRanking(Map<String, String> ranks) {
this.ranks = ranks;
}
}
- 비즈니스에 종속적인 자료구조이다.
- 클래스명을 통해 Game Ranking에 관한 자료구조임을 파악할 수 있음
- Collection의 불변성을 보장합니다.
- 상태와 행위를 한 곳에서 관리합니다.
- 이름이 있는 컬렉션을 사용해 어떤 용도로 사용되는지 명확히 합니다.
불변성
일급 컬렉션은 컬렉션의 불변을 보장합니다.
final과 setter 미설정을 통해 불변성을 보장합니다.
만약, final만 사용하는 경우 100% 불변을 지켜주지 않고, 재할당만 방지해 줍니다.
테스트 코드 1
@Test
public void testFinal() {
//given
final Map<String, Boolean> collection = new HashMap<>();
//when
collection.put("1", true);
collection.put("2", true);
collection.put("3", true);
collection.put("4", true);
//then
assertThat(collection.size()).isEqualTo(4);
}
위 코드를 테스트 코드로 실행해 보면 정상적으로 동작함을 알 수 있습니다.
재할당은 되지 않고, 생성된 collection에 값을 추가하는 것은 방지하지 않아 setter가 존재한다면 불변적이라고 할 수 없습니다.
테스트 코드 2
@Test
public void testFinal2() {
//given
final Map<String, Boolean> collection = new HashMap<>();
//when
collection = new HashMap<>();
//then
assertThat(collection.size()).isEqualTo(4);
}
final로 선언된 collection을 재할당하려고 하면 컴파일 에러가 발생하는 것을 확인할 수 있습니다.
결론 :
Java에서 final은 재할당만 방지되고 기존의 컬렉션 객체에 값이 추가될 수 있다.
일급 컬렉션 - 불변성 적용
public class Orders {
private final List<Order> orders;
public Orders(List<Order> orders) {
this.orders = orders;
}
public Orders getOrders() {
return orders;
}
}
위와 같이 컬렉션의 값을 변경할 수 있는 메서드를 구현하지 않고 private으로 선언함으로써 불변 컬렉션을 생성합니다.
컬렉션에 접근할 수 있는 방법이 없기 때문에 값을 변경 / 추가할 수 없습니다.
상태와 행위를 한 곳에서 관리
일급 컬렉션은 상태와 행위가 한 곳에 존재합니다.
public class PayGroups {
private List<Pay> pays;
public PayGroups(List<Pay> pays) {
this.pays = pays;
}
public Long getNaverPaySum() {
return getFilteredPays(pay -> PayType.isNaverPay(pay.getPayType()));
}
public Long getKakaoPaySum() {
return getFilteredPays(pay -> PayType.isKakaoPay(pay.getPayType()));
}
private Long getFilteredPays(Predicate<Pay> predicate) {
return pays.stream()
.filter(predicate)
.mapToLong(Pay::getAmount)
.sum();
}
}
List<Pay>를 처리하는 로직을 한 클래스에서 관리하여 유지보수와 확장성을 높일 수 있습니다.
일급 컬렉션을 사용하지 않는 경우
- 똑같은 기능을 수행하는 메소드가 중복 생성될 수 있습니다.
반응형
'JAVA' 카테고리의 다른 글
[Java] 자바 인코딩, 디코딩, base64 인코딩, 디코딩 처리하기 (1) | 2024.09.14 |
---|---|
[JAVA] static, final, staic final 개념 이해하기 - 전역 변수, 상수 (0) | 2024.09.14 |
[JAVA] Java Stream groupingBy 통해 그룹핑하기 (0) | 2024.08.17 |
[JAVA] JDK, JRE, JVM 차이 및 개념 이해하기 (0) | 2024.08.10 |
[JAVA] Java Optional.ofNullable() : Null 안전성과 간결한 코드 작성 방법 (0) | 2024.01.24 |