Java Stream Interface의 filter에 대해서 자세히 알아보자
filter란 주어진 요소를 조건에 따라 필터링할 때 사용한다.
주어진 조건을 만족하는 연산을 통해 데이터를 필터링한 후 스트림에 포함한다.
Stream<T> filter(Predicate<? super T> predicate)
filter 메서드에서 Predicate는 조건을 나타내는 함수형 인터페이스인
java.util.function.Predicate의 인스턴스이다.
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
static <T> Predicate<T> not(Predicate<? super T> target) {
Objects.requireNonNull(target);
return (Predicate<T>)target.negate();
}
위 Predicate 인터페이스는 test, and, negate, or, isEqual, not을
사용해 사용자가 원하는 데이터를 필터링할 수 있도록 도와준다.
사용자가 List에 저장된 숫자 중 홀수 또는 짝수의 숫자만 얻으려 하는 경우
위의 test(T t) 메서드를 사용해 true를 반환하는 요소를 스트림에 포함시킨다.
이런 방식은 반복문과 스트림 두 경우를 사용할 수 있으니 상황에 맞게 선택하면 되겠다.
public class SelfMakeFilter {
public static void main(String[] args) {
List<Integer> numberList = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
List<Integer> evenNumbers = new ArrayList<>();
List<Integer> oddNumbers = new ArrayList<>();
for (int number : numberList) {
if (number % 2 != 0) {
oddNumbers.add(number);
} else {
evenNumbers.add(number);
}
}
// 결과
System.out.println("짝수 : " + evenNumbers);
System.out.println("홀수: " + oddNumbers);
}
}
public class SelfMakeFilter {
public static void main(String[] args) {
// Integer 타입의 리스트 생성
SelfMakeArrayList<Integer> selfList = SelfMakeArrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 짝수
SelfMakeArrayList<Integer> evenNumbers = integerList.filter((Integer n) -> n % 2 == 0).toList();
// 홀수
SelfMakeArrayList<Integer> oddNumbers = integerList.filter((Integer n) -> n % 2 != 0).toList();
// 결과
System.out.println("짝수 : " + evenNumbers);
System.out.println("홀수: " + oddNumbers);
}
}
class SelfMakeArrayList<E> {
private final E[] t;
SelfMakeArrayList(E[] arrays) {
t = arrays;
}
// 배열을 리스트로 변환하는 메서드
public static <E> SelfMakeArrayList<E> asList(E... t) {
return new SelfMakeArrayList<>(t);
}
// 필터링 연산을 수행하는 메서드
public SelfMakeArrayList<E> filter(SelfMakePredicateNegate<? super E> predicateNegate) {
List<E> resultList = new ArrayList<>();
for (E item : t) {
if (predicateNegate.test(item)) {
resultList.add(item);
}
}
return new SelfMakeArrayList<>(resultList.toArray(Arrays.copyOf(t, 0)));
}
// 리스트로 변환하는 메서드
public List<E> toList() {
return Arrays.asList(t);
}
// 문자열로 변환하는 메서드
public String toString() {
return Arrays.toString(t);
}
}
interface SelfMakePredicateNegate<T> {
boolean test(T t);
default SelfMakePredicateNegate<T> negate() {
return (t) -> !test(t);
}
}