티스토리 뷰
개념
-
스트림은 고유 요소로 이루어진 스트림을 반환하는 중간 연산인
distinct
메서드를 지원한다.- 고유 여부는 객체의
equals
와hashCode
메서드를 통해 판단한다.
- 고유 여부는 객체의
예제
-
아래 예제에서 사용되는 내용들은 다양한 상황을 연출하기 위해서 임의로 만들어진 내용이므로 특정 속성에 대해서 왜 저 타입이 사용되었는지 의문을 가지지 말자!
-
예제 코드에서 사용되고 있는 스펙
- Java 15 preview (record라는 새로운 클래스 개념을 사용하기 위해서 해당 프리뷰 버전을 사용. 하위 버전의 경우는 일반 클래스를 생성한 후 getter를 만들고 사용하면 됨) - 참고
- JUnit 5
- Gradle 6.7
기본 데이터 생성
public record Song(int no, String title, String albumName, String artist) {
@Override
public boolean equals(Object song) {
return getClass() == song.getClass() && artist.equals(((Song) song).artist);
}
@Override
public int hashCode() {
return artist.hashCode();
}
}
private final DistinctUsage distinctUsage = new DistinctUsage();
private final List<Song> songs = List.of(
new Song(1, "Bohemian Rhapsody", "A Night at the Opera", "Queen"),
new Song(2, "2002", "Speak Your Mind", "Anne-Marie"),
new Song(3, "Blueming", "Love Poem", "IU"),
new Song(4, "Love Poem", "Love Poem", "IU"));
중복 숫자 제거
- 숫자가 담긴 리스트가 주어졌을 때 중복된 숫자를 제거하는 메서드를 만들어보자.
public List<Integer> getDistinctNumbers(List<Integer> lists) {
return lists.stream()
.distinct()
.collect(Collectors.toList());
}
- 테스트
@Test
@DisplayName("중복 숫자 제거")
void getDistinctNumbersTest() {
final var expect = List.of(1, 2, 8, 4);
final var result = distinctUsage.getDistinctNumbers(List.of(1, 2, 2, 8, 4, 1, 4));
assertIterableEquals(expect, result);
}
- 테스트가 가볍게 성공한다.
중복된 가수 이름 제거
- 이번에는 우리가 만든 커스텀 클래스(Song) 를 사용해서 리스트를 만들고 중복을 제거해보자.
public List<Song> getSongsWithDistinctArtist(List<Song> songs) {
return songs.stream()
.distinct()
.collect(Collectors.toList());
}
-
사실 위의 예제와 크게 다른 점은 없다.
-
distinct
메서드 자체가 파라미터를 가지고 있지 않기 때문에 오버로딩 정도의 예제다. -
여기서 주의할 점은 커스텀으로 만든 클래스의 경우 Number 타입이나 String 타입과 같은 Java의 기본 데이터 형태를 사용할 때와 다르게
equals
와hashCode
메서드를 오버라이딩해줘야 한다.- 그렇지 않을 경우
distinct
가 정상적으로 작동하지 않는다.
- 그렇지 않을 경우
-
여기서는 가수 이름 을 통해 중복을 제거하도록 테스트해보자.
@Test
@DisplayName("중복된 가수 이름 제거")
void getSongsWithDistinctAlbumNameTest() {
final var result = distinctUsage.getSongsWithDistinctArtist(songs);
result.forEach(System.out::println);
assertEquals(3, result.size());
assertEquals("Bohemian Rhapsody", result.get(0).title());
assertEquals("2002", result.get(1).title());
assertEquals("Blueming", result.get(2).title());
}
- 콘솔에 다음과 같은 실행 결과와 함께 테스트가 성공한다.
-
여기서 Song 클래스의
equals
와hashCode
메서드를 다음과 같이 오버라이딩했기 때문에 테스트가 정상적으로 성공했다.- 둘 중 하나라도 오버라이딩하지 않았다면
distinct
메서드가 정상적으로 작동하지 않아서 테스트가 실패한다.
- 둘 중 하나라도 오버라이딩하지 않았다면
이상 Stream API에서 사용하는 중간 연산 중 distinct
메서드의 간단한 사용법에 대해 살펴보았다.
'프로그래밍 > Java' 카테고리의 다른 글
[Stream API] 중간 연산 - map 메서드 (2) | 2021.01.04 |
---|---|
[Stream API] 중간 연산 - slicing 관련 메서드들 (0) | 2021.01.03 |
[Stream API] 중간 연산 - filter 메서드 (2) | 2020.12.30 |
Intellij IDEA에서 Gradle을 사용해 Java Preview 버전의 코드 테스트하기. (0) | 2020.10.28 |
[Java 14] Helpful NullPointerExceptions (0) | 2020.08.12 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- lambda
- 변경사항
- flatMapToDouble
- java
- mapToObj
- #예제 #example #가계부 #Account Book
- 충북 콕! 콕!
- 계획
- import문
- IntelliJ
- flatMapToLong
- java14
- 람다
- #React #ReactJS #리액트
- Java8
- Stream API
- 토이 프로젝트
- 회고
- modern java
- jdk14
- 익명 클래스
- flatMapToInt
- #배열 #array #map 함수
- 중간 연산
- 다짐
- 개발자
- 자바
- 목표
- 스트림
- flaMap
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
글 보관함