programing

왜 Itable은 stream() 메서드와 parallel Stream() 메서드를 제공하지 않습니까?

newsource 2022. 8. 7. 16:57

Itable은 stream() 메서드와 parallel Stream() 메서드를 제공하지 않습니까?

?가요?Iterable는 「」를 .stream() ★★★★★★★★★★★★★★★★★」parallelStream()합니다.하다

public class Hand implements Iterable<Card> {
    private final List<Card> list = new ArrayList<>();
    private final int capacity;

    //...

    @Override
    public Iterator<Card> iterator() {
        return list.iterator();
    }
}

트레이딩 카드 게임을 하면서 카드를 손에 쥘 수 있는 핸드 구현입니다.

으로는 ★★★★★★★★★★★★★★★★★★★★★★★★.List<Card>는 최대 용량을 확보하고 기타 유용한 기능을 제공합니다..List<Card>.

했습니다.Iterable<Card>하고 는 확장 할 수 루루 、 For - loops ) 。Hand는 클래스도 합니다.get(int index)즉 「」, 「」를 참조해 .Iterable<Card>정당하다고 생각합니다.)

Iterable는 다음interface 다 、 음음(( ( adoc ) 。

public interface Iterable<T> {
    Iterator<T> iterator();

    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}

이제 다음을 사용하여 스트림을 얻을 수 있습니다.

Stream<Hand> stream = StreamSupport.stream(hand.spliterator(), false);

그럼 진짜 질문으로 넘어가죠.

  • ?는 왜?Iterable<T>되어 있지 .stream() ★★★★★★★★★★★★★★★★★」parallelStream()불가능하거나 원치 않는 건 아무것도 보이지 않아요?

제가 찾은 관련 질문은 다음과 같습니다.Stream이 필요한 이유<T > 구현 불가능 <T >
그건 이상하게도 어느 정도 다른 방법으로 할 수 있다는 것을 암시하는 것이다.

이는 누락이 아니었다. 2013년 6월에 EG 목록에 대한 자세한 논의가 있었다.

Expert Group의 최종적인 논의는 이 스레드에 뿌리를 두고 있습니다.

',stream()가 있는 것 Iterable 「 」라는 사실.Iterable이치노'CHANGE: 'CHANGE: 'CHANGE:

Stream<T> stream()

항상 네가 원하는 건 아니었어몇 가지 일은Iterable<Integer>스트림 메서드가 반환되는 것이 더 낫습니다.IntStream ★★★★★★★★★★★★★★★★★★.stream()이렇게 높은 계층에 있는 방법은 불가능하게 만들 수 있습니다. 그 정말 수 있게 요.Stream Iterable「」를spliterator()★★★★★★★★의 실장stream()Collection을 사용하다

default Stream<E> stream() {
    return StreamSupport.stream(spliterator(), false);
}

을 ""에서 얻을 수 .Iterable 라이선스:

Stream s = StreamSupport.stream(iter.spliterator(), false);

우리는 국, 리, 리를 더하는 것으로 을 내렸다.stream()로로 합니다.Iterable실수하는 거야

프로젝트 람다 메일링 리스트 중 몇 개를 조사했는데 흥미로운 논의를 몇 개 찾은 것 같아요.

나는 지금까지 만족할 만한 설명을 찾지 못했다.이 모든 것을 읽고 난 후 나는 그것이 단지 누락이라고 결론지었다.그러나 API 설계 과정에서 수년간 여러 번 논의된 것을 알 수 있습니다.

람다 립스 스펙 엑스퍼트

Lambda Libs Spec Experts 메일링 리스트에서 이에 대한 논의를 발견했습니다.

Itable/Iterator.stream()에서 Sam Pullara는 다음과 같이 말했습니다.

저는 Brian과 함께 제한/서브스트림 기능[1]을 구현하는 방법에 대해 알아보고 있었는데, 그는 Iterator로 전환하는 것이 올바른 방법이라고 제안했습니다.나는 그 해결책을 생각해 보았지만, 반복기를 가져와 스트림으로 만들 뚜렷한 방법을 찾지 못했다.이 안에 있는 것으로 판명되었습니다. 먼저 반복기를 스플리터로 변환한 다음 스플리터를 스트림으로 변환하기만 하면 됩니다.그래서 저는 이 두 가지를 Itable/Iterator 중 하나에 직접 매달아야 하는지 아니면 둘 다 매달아야 하는지에 대해 다시 생각하게 됩니다.

적어도 두 세계 사이를 깔끔하게 이동할 수 있도록 Iterator에 저장해 두는 것이 좋습니다.또, 다음의 조작을 실시할 필요는 없습니다.

Streams.stream(Spliterators.spliterator)알 수 없는 크기(반복기, 스플리테이터).주문 완료)

그러자 브라이언 괴츠는 이렇게 대답했다.

샘의 요점은 반복기를 주는 도서관 수업은 많이 있지만 반드시 자신의 분절기를 쓰도록 놔두지 않는다는 것이었다.그래서 할 수 있는 건 call stream(스플리터)밖에 없어요.알 수 없는 크기(반복기).Sam은 이를 위해 Iterator.stream()을 정의할 것을 제안하고 있습니다.

stream() 메서드와 spliterator() 메서드는 라이브러리 라이터/고급 사용자용으로 유지하고 싶습니다.

그리고 나중에

스플리테이터를 쓰는 것이 반복기보다 쉽기 때문에 반복기 대신 스플리테이터를 쓰는 것이 좋습니다(반복기는 90년대입니다).

하지만 넌 요점을 놓치고 있어.이미 당신에게 반복자를 건네주는 수많은 수업들이 있다.그리고 그들 중 다수는 분쇄기 준비가 되어 있지 않다.

Lambda 메일링 리스트의 이전 설명

이것은 당신이 찾고 있는 답이 아닐 수도 있지만, 프로젝트 람다 메일링 리스트에서 간단히 설명했습니다.아마도 이것은 그 주제에 대한 폭넓은 논의를 촉진하는 데 도움이 될 것이다.

Brian Goetz의 "Streams from Itatable"은 다음과 같이 말합니다.

뒤로 물러서는 중...

스트림을 만드는 방법은 여러 가지가 있습니다.요소를 설명하는 방법에 대한 정보가 많을수록 스트림 라이브러리에서 더 많은 기능과 성능을 얻을 수 있습니다.대부분의 정보에는 다음과 같은 정보가 포함되어 있습니다.

반복기

반복기 + 크기

스플리터

크기를 아는 스플리터

크기를 알고 모든 서브스플릿이 크기를 알고 있다는 것을 더 잘 아는 스플리터.

(Q(요소당 작업량)가 중요하지 않은 경우에는 멍청한 반복기에서라도 병렬화를 추출할 수 있다는 사실에 놀랄 수도 있습니다.)

Itable이 stream() 메서드를 사용하는 경우 크기 정보 없이 반복기를 스플리테이터로 랩합니다.하지만, 대부분의 가능한 것들은 크기 정보를 가지고 있습니다.그 말은 우리가 부족한 물줄기를 공급하고 있다는 거죠.별로 안 좋아요.

여기서 Stephen이 개략적으로 설명한 API 프랙티스의 단점 중 하나는 Collection이 아닌 Itable을 받아들이기 위해 "작은 파이프"를 통해 무언가를 강제하고, 따라서 유용할 경우 크기 정보를 폐기한다는 것입니다.각 데이터를 위한 작업만 수행한다면 문제 없습니다. 하지만 더 많은 작업을 수행할 경우 원하는 모든 정보를 보존할 수 있다면 더 좋습니다.

Itable이 제공하는 디폴트는 정말 형편없는 것입니다.Iterables의 대부분은 그 정보를 알고 있어도 사이즈는 폐기됩니다.

모순?

그러나 이 논의는 Expert Group이 처음에 반복자를 기반으로 한 스트림의 초기 설계에 대해 수행한 변경에 기초하고 있는 것으로 보입니다.

그래도 Collection과 같은 인터페이스에서는 스트림 방식이 다음과 같이 정의되어 있다는 것을 알 수 있습니다.

default Stream<E> stream() {
   return StreamSupport.stream(spliterator(), false);
}

Itable 인터페이스에서 사용되는 것과 동일한 코드일 수 있습니다.

그래서 제가 이 답변이 만족스럽지는 않지만 여전히 논의에 흥미로울 수 있다고 말한 것입니다.

리팩터링의 증거

메일링 리스트의 분석을 계속하면, splitIterator 메서드는 원래 Collection 인터페이스에 있었던 것 같으며, 2013년 어느 시점에서는 Itable로 업그레이드되었습니다.

splitIterator를 Collection에서 Itable로 끌어올립니다.

결론/이론

SplitIterator를 Collection에서 Itable로 업그레이드할 때 스트림 메서드도 함께 이동했어야 했던 것 같기 때문에 Itable에 메서드가 없는 것은 생략된 것일 수 있습니다.

만약 다른 이유들이 있다면 그것들은 분명하지 않다.다른 사람이 다른 이론을 가지고 있나요?

하실 수 .java.util.Collection는 " " 를 제공합니다.stream()★★★★

public class Hand extends AbstractCollection<Card> {
   private final List<Card> list = new ArrayList<>();
   private final int capacity;

   //...

   @Override
   public Iterator<Card> iterator() {
       return list.iterator();
   }

   @Override
   public int size() {
      return list.size();
   }
}

그 후:

new Hand().stream().map(...)

도 같은 요.Iterable은 매우 될 수 .AbstractCollection만으로 구현합니다.size()가 있었다:-) method (다행히 컬렉션의 사이즈가 )

, 「」, 「」를 덮어쓰는 것도 .Spliterator<E> spliterator().

언급URL : https://stackoverflow.com/questions/23114015/why-does-iterablet-not-provide-stream-and-parallelstream-methods