Java Predicate 살펴보기2 C# 개발자가

몬난아·2021년 8월 14일
0

Java Predicate 살펴보기2 이다

Predicate의 기본은 저번 게시글에서 작성했고 predicate 에서 default함수?로 구성되어 있는
"and, or, negate, isEqual, not" 5개 함수를 사용해보는 예제를 테스트 하는걸로 마무리.

먼저 어제 글쓸때까지는 발견을 못햇던 부분인데 predicate를 소스보기 해서 다시 자세히보았더니
not은 내부적으로 negate를 호출함으로 결과적으로 같은 함수임을 지금에서 확인하였습니다.

실질적으로 내부에서 negate()를 호출 하는 코드가 있는부분을 확인하실수 있습니다.

그럼으로 확인해야할 함수는 아래 4개로 정해졌습니다

and : 조건1 + 조건2
or : 조건1 OR 조건2
negate : !(조건) "사전적 의미로 부정하다 인것으로 확인
isEqual : 동등연산

먼저 상대적으로 확인이 쉬운 and or 에 대한 연산확인

public static void main(String[] args) {
        Predicate<Integer> pre1 = i -> (i%2) == 0;
        Predicate<Integer> pre2 = i -> i >= 5;
        Predicate<Integer> pre3 = i -> i == 7;

        System.out.println("---------- and or ------------");
        //(짝수 and 5크고) OR 7
        var allpredicate = pre1.and(pre2).or(pre3);
        System.out.println(allpredicate.test(3)); //false
        System.out.println(allpredicate.test(7)); //true
        System.out.println(allpredicate.test(8)); //true
        System.out.println(allpredicate.test(10)); //true

        System.out.println("---------- negate ------------");
        var not_allpredicate = allpredicate.negate();
        System.out.println(not_allpredicate.test(3)); //false
        System.out.println(not_allpredicate.test(7)); //true
        System.out.println(not_allpredicate.test(8)); //true
        System.out.println(not_allpredicate.test(10)); //true



        System.out.println("---------- isEqual ------------");
        List<Integer> list = Arrays.asList(1,2,3,4,5);

        var filterList = list.stream().filter(Predicate.isEqual(5)).map(Integer::new).collect(Collectors.toList());
        //var filterList = list.stream().filter(r -> r==5).map(Integer::new).collect(Collectors.toList());
        System.out.println(filterList.size());//1

    }

and or의 조건식
조건1 : 짝수
조건2 : 5보다크거나 같다.
조건3 : 7이면

negate의 조건식은 (and or) 조건식의 모두 반대값을 표현

isEqual의 표현식은 filter를 이용해서 같음을 표기 하였지만 Predicate로 꼭표현하기위해
lamda문법보다 다소 번거롭게 표현하였습니다.
아래 주석으로 표현한 r -> r == 5를 표현하기 위한 방법이였습니다 아마 Equal의 표현식을 사용못하는 정확한 이유는 알지 못하겠지만 Generic 객체의 Equal을 호출하여 ReferenceEqual을 피하기 위한 방법중 하나가 아니였을까.. 생각됩니다.

출력결과는 다음과 같습니다.

c#의 테스트 코드도 크게 다른부분은 없으며 다음과 같습니다.

namespace ConsoleApp1
{

    class Program
    {
        public delegate bool Test(int i);

        static void Main(string[] args)
        {
            Func<int, bool> func1 = i => (i%2) == 0;
            Func<int, bool> func2 = i => i >= 5;
            Func<int, bool> func3 = i => i == 7;

            var andFunc = func1 + func2;


            Console.WriteLine("------------ and or -------------");
            Console.WriteLine(andFunc(3) || func3(3));
            Console.WriteLine(andFunc(7) || func3(7));
            Console.WriteLine(andFunc(8) || func3(8));
            Console.WriteLine(andFunc(10) || func3(10));

            Console.WriteLine("------------ not -------------");
            Console.WriteLine(!(andFunc(3) || func3(3)));
            Console.WriteLine(!(andFunc(7) || func3(7)));
            Console.WriteLine(!(andFunc(8) || func3(8)));
            Console.WriteLine(!(andFunc(10) || func3(10)));


            List<int> list = new List<int>{1,2,3,4,5};
            list.Where(r => r == 5);
        }
    }
}

두코드의 가장 큰차이점은 C#의 delegate특징은 + - 식의 합연산과 빼기 연신이 가능다하다는점
이외에 and or는 코드가 아니라도 일반 if문에서 사용하는 &&,|| 연산도 가능하다는점
not연산은 역시 if에서 사용하는 부정연산으로 !간단하게 가능하다는점

코드가독성은 일반적인 if문에서 더 자주쓰이는 문법을 그대로 사용할수 있다는 점에서는 C#이 역시 다소 더 쉬운 문법인것으로 보이나 해당부분의 언어적인 설계의 특성도 한목한다고 볼수 있고 아직 자세한건 알지 못하나 java도 C#의 linq와 같은 and or not연산을 코드 연속성있게 하는 코드를위해 해당 인터페이스를 구성하지 않았나 생각됩니다.

Java Collection과 Stream에 대해서 이제 막 코드를 본지 2-3일되는 시점에서 논하고 평할수 없는 부분이며 delegate가 없다는 한계점을 interface로 극복한점이 상당히 인상적입니다.

여기까지가 Predicate학습 마무리 입니다.

profile
잘~ 사는게 목표인사람

0개의 댓글