티스토리 뷰

Backend/Java8

#9 Predicate

RadderNepa 2022. 9. 21. 00:03

● 도입

- Predicate는 input을 받아서 true / false를 return 하는 interface이다.

@FunctionalInterface
public interface Predicate<T> {
	boolean test(T t);
}

 

 

● 실습

package com.fastcampus.functionalprogramming.chapter4;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class Chapter4Section4 {
	public static void main(String[] args) {
		// 양수 / 음수를 알려주는 기능
		Predicate<Integer> isPositive = x -> x > 0;
		List<Integer> integerInputs = Arrays.asList(10, -18, 20, -30, 29);
		System.out.println(filter(integerInputs, isPositive));
	}
	
	// true 인 것만 뽑아 새로운 List를 만들어 return 하자
	public static <T> List<T> filter(List<T> inputs, Predicate<T> condition) {
		List<T> output = new ArrayList<T>();
		for (T input : inputs) {
			if(condition.test(input)) {
				output.add(input);
			}
		}
		return output;
	}
}

 

 

● 구조

- Predicate interface의 구조는 아래와 같다.

package java.util.function;

import java.util.Objects;

@FunctionalInterface
public interface Predicate<T> {
    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);
    }

    @SuppressWarnings("unchecked")
    static <T> Predicate<T> not(Predicate<? super T> target) {
        Objects.requireNonNull(target);
        return (Predicate<T>)target.negate();
    }
}

- 이 중에서 and, negate, or method에 대해 자세히 알아보자

 

1. negate

default Predicate<T> negate() {
	return (t) -> !test(t);
}

cf) negate 뜻
1. 무효화하다, 효력이 없게 만들다 (=nullify)
2. (존재 등을) 부인하다

- 위의 실습 챕터에서 아래와 같은 Predicate를 만들었다.

Predicate<Integer> isPositive = x -> x > 0; // 0 보다 큰 것만 골라내는 Predicate

- 그렇다면 isPositive Predicate의 반대 행동을 하는 Predicate는 무엇일까?

- 0과 같거나 0 보다 작은 수만 골라내는 것이다. 바로 이 Predicate를 negate를 이용해 만들어 볼 것이다.

package com.fastcampus.functionalprogramming.chapter4;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class Chapter4Section4 {
	public static void main(String[] args) {
		Predicate<Integer> isPositive = x -> x > 0; // 양수 / 음수를 알려주는 기능
		List<Integer> integerInputs = Arrays.asList(10, -5, 4, -2, 0);
        
		System.out.println("Positive : " + filter(integerInputs, isPositive));
        
		// negate()를 붙여줬기에 isPositive와 정반대의 행동을 한다.
		System.out.println("Non-Positive : " + filter(integerInputs, isPositive.negate()));
	}
	
	// true 인 것만 뽑아 새로운 List를 만들어 return 하자
	public static <T> List<T> filter(List<T> inputs, Predicate<T> condition) {
		List<T> output = new ArrayList<T>();
		for (T input : inputs) {
			if(condition.test(input)) {
				output.add(input);
			}
		}
		return output;
	}
}

 

2. or

default Predicate<T> or(Predicate<? super T> other) {
	Objects.requireNonNull(other);
	return (t) -> test(t) || other.test(t);
}
Predicate<Integer> isPositive = x -> x > 0; // 0 보다 큰 것만 골라내는 Predicate

- 이번에는 or를 이용해 0 보다 '크거나' 0과 같은 숫자만 골라내는 Predicate를 만들어보자

package com.fastcampus.functionalprogramming.chapter4;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class Chapter4Section4 {
	public static void main(String[] args) {
		Predicate<Integer> isPositive = x -> x > 0; // 양수 / 음수를 알려주는 기능
		List<Integer> integerInputs = Arrays.asList(10, -5, 4, -2, 0);
		
		// (x -> x == 0)라는 Predicate를 새로 만들어서 or method에 넘겨주는 것이다.
		// 아래의 filter method에는 isPositive와 or(x -> x == 0)가 합쳐진 새로운 Predicate가 argument로 전달되는 것이다.
		System.out.println("Non-negative : " + filter(integerInputs, isPositive.or(x -> x == 0)));			
	}
	
	// true 인 것만 뽑아 새로운 List를 만들어 return 하자
	public static <T> List<T> filter(List<T> inputs, Predicate<T> condition) {
		List<T> output = new ArrayList<T>();
		for (T input : inputs) {
			if(condition.test(input)) {
				output.add(input);
			}
		}
		return output;
	}
}

 

3. and

default Predicate<T> and(Predicate<? super T> other) {
	Objects.requireNonNull(other);
	return (t) -> test(t) && other.test(t);
}
Predicate<Integer> isPositive = x -> x > 0; // 0 보다 큰 것만 골라내는 Predicate

- 이번에는 and를 이용해 양수'이면서' 짝수만 골라내는 Predicate를 만들어보자

package com.fastcampus.functionalprogramming.chapter4;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class Chapter4Section4 {
	public static void main(String[] args) {
		Predicate<Integer> isPositive = x -> x > 0; // 양수 / 음수를 알려주는 기능
		List<Integer> integerInputs = Arrays.asList(10, -5, 4, -2, 0, 3);
		// 아래의 filter method에는 isPositive와 and(x -> x % 2 == 0)가 합쳐진 새로운 Predicate가 argument로 전달되는 것이다.
		System.out.println("Even-Positive : " + filter(integerInputs, isPositive.and(x -> x % 2 == 0)));
	}
	
	// true 인 것만 뽑아 새로운 List를 만들어 return 하자
	public static <T> List<T> filter(List<T> inputs, Predicate<T> condition) {
		List<T> output = new ArrayList<T>();
		for (T input : inputs) {
			if(condition.test(input)) {
				output.add(input);
			}
		}
		return output;
	}
}

 

- 이렇듯 단 1개의 filter method만 만들었는데도 다양한 조건의 결과값을 얻을 수 있게 됐다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
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
글 보관함