Stream을 이용한 반복 작업

7714 단어
먼저 가장 전형적인 귀속 응용 장면을 보자.
public class Test4 {
    public static Long f(int n){
        if(n==1||n==2){
            return 1L;
        }else{
            return f(n-1)+f(n-2);
        }
    }

    public static void main(String[] args) {
        long now = System.currentTimeMillis();
        System.out.println(f(40));
        System.out.println(" :"+((System.currentTimeMillis()-now)/1000.0)+" ");
    }
}

프로그램 실행 결과: 102334155 소모 시간: 4.672초 계산된 개수를 50으로 높이면 프로그램 실행 결과: 12586269025 소모 시간: 536.292초
다음은 Stream을 사용하여 피보나치 수열의 계산 작업을 완성합니다.반복 컴퓨팅을 보다 포괄적으로 적용하기 위해 인터페이스부터
public interface Recursion {

    Recursion compute();

    default boolean isFinish(){return false;}

    default T result(){throw new UnsupportedOperationException(" ");}

    default T invoke(){

        return Stream.iterate(this,Recursion::compute)// ,
                 // Recursion filter 
                // Lambda “ ” ,iterate filter 
                // filter 
                .filter(Recursion::isFinish)
                .findFirst()
                .get()// Recursion 
                .result();// result 

    }

그리고 도구류 Recursions를 써서 호출이 발생할 때 Recursion 대상의 생성을 잠시 후에 되돌려줍니다
public class Recursions {

    public static Recursion call(Recursion recursion){
        return recursion;
    }

    public static  Recursion done(T result){

        return new Recursion(){

            @Override
            public Recursion compute() {
                throw new UnsupportedOperationException(" ");
            }

            @Override
            public boolean isFinish() {
                return true;
            }

            @Override
            public T result() {
                return result;
            }
        };
    }

}

그런 다음 테스트 방법 및 테스트 클래스를 작성할 수 있습니다.
public class Test5 {

    public static Recursion f(long l1,long l2,int count){
        if(count==1){
            return Recursions.done(l1);
        }else{
            return Recursions.call(f(l2,l1+l2,count-1));
        }
    }

    public static void main(String[] args) {
        long now = System.currentTimeMillis();
        Long s = f(1, 1, 50).invoke();
        System.out.println(s);
        System.out.println(" :"+((System.currentTimeMillis()-now)/1000.0)+" ");
    }

}

코드 실행 후: 계산 결과: 12586269025 소모 시간: 0.128초 Test5에서Test4에서 사용한 귀속 알고리즘과 같지 않습니다.Test5의 f 방법은 매번'귀속'할 때마다 이 순간의 연산 결과를 생성하고 이 결과를 이용하여 다음 연산에 다시 참여한다.main 방법 중 f(1,1,50).invoke(); invoke 방법이 호출되기 전에 f 방법은 50번 실행되었고, 최종적으로 Recursion 대상을 되돌려줍니다.이 Recursion 대상은 Recursions 도구 클래스의done 방법으로 만들어졌으며, 이 컴퓨터 방법은 호출되면 이상이 발생할 수 있는 구체적인 구현을 제공하지 않았습니다.그러나 이 Recursion 대상에서 invoke 방법을 호출할 때strema 서열iterate에서 발생하는 무한 서열의 첫 번째 요소(즉 Recursion 대상 자체)는 Filter의 조건에 부합되기 때문에(이 Recursion 대상의 isComplete 방법은true로 되돌아간다) 이 Recursion 대상의 컴퓨터 방법을 호출하여 두 번째 서열의 내용을 계산하지 않기 때문에iterate 방법은 이미 끝났다.그 다음에 get 방법을 이용하여 이 Recursion 대상을Stream 시퀀스에서 꺼낸 후,result 방법을 호출하여 계산 결과를 가져옵니다.이 예에서 Recursion 인터페이스와 Recursions 도구 클래스는 귀속 작업을 할 때 어느 정도 통용성을 가진다. 응용 장면에서 적당한 테스트 방법을 쓰면 된다. 예를 들어 누적된 귀속 작업을 하면 된다.
public class Test6 {

    public static Recursion f(long l , int count){
        if(count==1){
            return Recursions.done(l);
        }else{
            return Recursions.call(f(l*count,count-1));
        }
    }

    public static void main(String[] args) {
        System.out.println(f(1,5).invoke());
    }

}

프로그램 실행 결과: 120

좋은 웹페이지 즐겨찾기