본문으로 바로가기

[Java] 자바 8 Stream API 필터링 (filter, distinct)

category Backend/Java 2022. 1. 1. 14:22

1. 필터링

  • 필터링은 중간 처리 기능으로 요소를 걸러내는 역할을 합니다.
  • 필터링 메소드인 distinct()filter() 메소드는 모든 스트림(Stream, IntStream, LongStream, DoubleStream)이 가지고 있는 공통 메소드 입니다.
  • distinct() : 중복 요소를 제거합니다.
  • filter() : 특정 조건을 지정하여 원하는 요소만 필터링(꺼내) 합니다.

필터링 메소드

2. distinct()

distinct()

Stream<T> distinct();
  • Stream의 경우 Object.equals(Object)가 true이면 동일한 객체로 판단하여 중복을 제거합니다.
  • IntStream, LongStream, DoubleStream은 동일 값(==) 일 경우 중복을 제거합니다.

 

int[]

int[] intArr = {1,1,1,2,2,3,3,4};

IntStream intStream = Arrays.stream(intArr).distinct();
intStream.forEach(System.out::println);

/*
[결과]
1
2
3
4
*/

 

List<String>

List<String> stringList = Arrays.asList(
        "A",
        "A",
        "A",
        "B",
        "B",
        "C"
);
stringList.stream()
        .distinct()
        .forEach(System.out::println);
/*
[결과]
A
B
C
*/

 

 

DTO(VO)

  • DTO(VO) 같은 경우에는 equals()를 오버 라이딩하여 중복을 체크할 조건을 구현해야 중복을 제거할 수 있습니다.
  • equals()를 재정의 할 경우에는 마찬가지로 hashCode() 또한 오버 라이딩해야 합니다.

[이름이 같은 경우 같은 객체]

static class People {

    private String name;
    private int age;

    People(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }

    // 이름이 같은 경우 중복 처리
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        People other = (People) obj;
        return Objects.equals(name, other.name);
    }
}
List<People> peopleList = Arrays.asList(
        new People("A", 1),
        new People("A", 1),
        new People("B", 1),
        new People("B", 2),
        new People("B", 2),
        new People("C", 1),
        new People("C", 2),
        new People("C", 3)
);

peopleList.stream()
        .distinct()
        .forEach(p -> {
            System.out.println(p.getName() + ":" + p.getAge());
        });
/*
[결과]
A:1
B:1
C:1
*/

 

[나이가 같은 경우 같은 객체]

  • 실행 코드는 위의 예시와 동일합니다.
@Override
public int hashCode() {
    return age;
}

// 나이가 같은 경우 중복 처리
@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    People other = (People) obj;
    return age == other.getAge();
}

/*
[결과]
A:1
B:2
C:3
*/

3. filter()

filter()

Stream<T> filter(Predicate<? super T> predicate);
  • 특정 조건을 지정하여 원하는 요소만 필터링(꺼내) 합니다.
  • Predicate<T> : T 타입을 받아서 boolean을 리턴하는 함수 인터페이스

 

double[]

double[] doubleArr = {1.0, 1.1, 1.2, 2.1, 2.2, 3.0, 3.5};

DoubleStream doubleStream = Arrays.stream(doubleArr).filter(d -> d > 2);
doubleStream.forEach(System.out::println);

/*
[결과]
2.1
2.2
3.0
3.5
*/

 

List

List<String> stringList = Arrays.asList(
        "Apple",
        "Bee",
        "An",
        "Can",
        "Ant",
        "Butter"
);
stringList.stream()
        .filter(s -> s.startsWith("A"))
        .forEach(System.out::println);
/*
[결과]
Apple
An
Ant
*/

 

DTO(VO)

List<People> peopleList = Arrays.asList(
        new People("A", 1),
        new People("A", 1),
        new People("B", 1),
        new People("B", 2),
        new People("B", 2),
        new People("C", 1),
        new People("C", 2),
        new People("C", 3)
);

peopleList.stream()
        .filter(p -> p.getAge() > 1)
        .forEach(p -> {
            System.out.println(p.getName() + ":" + p.getAge());
        });
/*
[결과]
B:2
B:2
C:2
C:3
*/