[JAVA8 병렬프로그래밍] 분할반복 Spliterator

반응형
728x90
반응형

분할 반복 Spliterator

자바 8에서 Split과 Iterator의 합성어로 Spliterator 인터페이스를 제공한다. 

 

 

Iterator 예제

HelloPerson.java
package org.example.Spliterator;

import java.util.ArrayList;
import java.util.List;

public class HelloPerson {
    private String firstName;
    private String lastName;
    private String country;

    public HelloPerson(String firstName, String lastName, String country) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.country = country;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    @Override
    public String toString() {
        return this.getFirstName() + " " + this.getLastName() + " from " + this.getCountry();
    }

    public static List<HelloPerson> getSampleDate() {
        // List 객체를 생성한다.
        List<HelloPerson> person = new ArrayList<HelloPerson>();

        // 테스트 데이터를 추가한다.
        person.add(new HelloPerson("윤기", "장", "대한민국"));
        person.add(new HelloPerson("해라", "장", "미국"));
        person.add(new HelloPerson("해윤", "장", "중국"));
        person.add(new HelloPerson("애리", "노", "일본"));
        person.add(new HelloPerson("크롱", "장", "남극"));

        return person;
    }
}

 

IteratorExample.java
package org.example.Spliterator;

import java.util.Iterator;
import java.util.List;

public class IteratorExample {
    public static void main(String[] args) {
        // List 객체를 생성한다.
        List<HelloPerson> personList = HelloPerson.getSampleDate();

        // Iterator로 데이터를 처리한다.
        Iterator<HelloPerson> peopleIterator = personList.iterator();

        while (peopleIterator.hasNext()) {
            HelloPerson person = peopleIterator.next();
            System.out.printf("안녕~~ %s\n", person);
        }
    }
}

 

SpliteratorExample.java
package org.example.Spliterator;

import java.util.List;
import java.util.Spliterator;

public class SpliteratorExample {

    public static void main(String[] args) {
        // List 객체를 생성한다.
        List<HelloPerson> personList = HelloPerson.getSampleDate();

        // Spliterator 객체를 생성한다.
        Spliterator<HelloPerson> spliterator = personList.spliterator();

        // 순차 처리 한다.
        spliterator.forEachRemaining((person) -> System.out.printf("안녕~~ %s\n", person));
    }
}

 

1) 기본은 순차 처리로 수행된다.

 

Iterator을 Spliterator로 변경하면 hasNext나 next 메서드 호출, while 또는 for 없어도 동일한 효과를 얻게된다. 

 

 

 

병렬 처리로 변경

SpliteratorExample2.java
package org.example.Spliterator;

import java.util.List;
import java.util.Spliterator;

public class SpliteratorExample2 {
    public static void printSize(String name, Spliterator<HelloPerson> spliterator) {
        System.out.printf("Estimated size (%s) : %s\n", name, spliterator.estimateSize());
    }

    public static void printSpliterator(Spliterator<HelloPerson> spliterator) {
        spliterator.forEachRemaining((person) -> System.out.printf("안녕~~ %s\n", person));
    }

    public static void main(String[] args) {
        // List 객체를 생성한다.
        List<HelloPerson> personList = HelloPerson.getSampleDate();

        // Spliterator 객체를 생성한다.
        Spliterator<HelloPerson> spliterator1 = personList.spliterator();

        printSize("spliterator1", spliterator1);
        Spliterator<HelloPerson> spliterator2 = spliterator1.trySplit();

        System.out.println("첫번째 split 후");
        printSize("spliterator1", spliterator1);
        printSize("spliterator2", spliterator2);

        Spliterator<HelloPerson> spliterator3 = spliterator1.trySplit();

        System.out.println("두번째 split 후");
        printSize("spliterator1", spliterator1);
        printSize("spliterator2", spliterator2);
        printSize("spliterator3", spliterator3);

        System.out.println(" ");
        System.out.println("spliterator1 출력 ~~~");
        printSpliterator(spliterator1);
        System.out.println("spliterator2 출력 ~~~");
        printSpliterator(spliterator2);
        System.out.println("spliterator3 출력 ~~~");
        printSpliterator(spliterator3);
    }
}

1) Spliterator가 참조하고 있는 데이터의 크기를 구한다.

System.out.printf("Estimated size (%s) : %s\n", name, spliterator.estimateSize());

 

2) trySplit() 메서드 사용

데이터를 반으로 분리한다.

Spliterator<HelloPerson> spliterator2 = spliterator1.trySplit();

...

Spliterator<HelloPerson> spliterator3 = spliterator1.trySplit();
전개 내용
첫번째 Spliterator spliterator1 : 5개
두번째 Spliterator  spliterator1.trySplie()을 시도하여 반으로 분리한다. 

- spliterator1 : 데이터 3개
- spliterator2: 데이터 2개
세번째 Spliterator spliterator1.trySplie()을 시도하여 반으로 분리한다. 

- spliterator1 : 데이터 2개
- spliterator2: 데이터 2개
- spliterator3: 데이터 1개 

 

 

trySplit()

trySplit은 데이터를 정확히 반으로 나누려고 하며 데이터 개수가 홀수인 경우는 원천 Spliterator가 하나가 더 많게 분리된다. 

순서상으로는 앞에 있는 데이터들이 분리되는 쪽으로 이동된다. 

원천 데이터의 순서가 보장될 경우에만 위 규칙으로 예상할 수 있고, 그렇지 않을 경우는 다양한 경우의 수가 발생할 수 있다.

 

 

반응형

Designed by JB FACTORY