263 votes

Pourquoi Iterable<T> pas fournir les méthodes stream() et parallelStream() ?</T>

Je me demande pourquoi l' Iterable interface ne permet pas de fournir l' stream() et parallelStream() méthodes. Considérons la classe suivante:

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();
    }
}

C'est une mise en œuvre d'une Main que vous pouvez avoir des cartes dans votre main tout en jouant à un Jeu de Cartes à collectionner.

Essentiellement, il enroule une List<Card>, assure une capacité maximale et offre d'autres fonctionnalités utiles. C'est mieux que de mettre en œuvre directement en tant que List<Card>.

Maintenant, pour convienience j'ai pensé qu'il serait bien de mettre en œuvre Iterable<Card>, de sorte que vous pouvez utiliser renforcée pour boucles si vous souhaitez faire une boucle sur elle. (Ma Hand de la classe fournit également un get(int index) méthode, d'où l' Iterable<Card> est justifié à mon avis.)

L' Iterable interface fournit les suivantes (à gauche en sortant de javadoc):

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);
    }
}

Maintenant, pouvez-vous obtenir un flux avec:

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

Donc sur la vraie question:

  • Pourquoi est - Iterable<T> pas fournir une valeur par défaut des méthodes qui implémentent stream() et parallelStream(), je ne vois rien qui pourrait la rendre impossible ou indésirable?

Une question connexe, j'ai trouvé est la suivante: Pourquoi ne Stream<T> ne pas mettre en œuvre objet iterable<T>?
Qui est curieusement il suggère de faire un peu l'inverse.

321voto

Brian Goetz Points 6062

Ce n'était pas une omission; il y avait une discussion détaillée sur le EG liste au mois de juin 2013.

La discussion définitive du Groupe d'Experts est lié à ce fil.

Alors qu'il semblait "évident" (même pour le Groupe d'Experts, d'abord) stream() semblait faire sens sur Iterable, le fait que l'objet iterable était si général est devenu un problème, parce que l'évidence de la signature:

Stream<T> stream()

n'était pas toujours ce que vous allez vouloir. Certaines choses qui ont été Iterable<Integer> serait plutôt de leur flux de retour de méthode un IntStream, par exemple. Mais en mettant l' stream() méthode de ce haut dans la hiérarchie de la rendrait impossible. Donc, au lieu de cela, nous avons fait c'est vraiment facile de faire de l' Stream d'un Iterable, en fournissant un spliterator() méthode. La mise en œuvre de Flux de Collecte est juste:

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

Tout client peut obtenir le flux qu'ils veulent à partir d'un Iterable avec:

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

En fin de compte, nous avons conclu que l'ajout d' stream() de Iterable serait une erreur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X