Question

Existe-t-il dans Java 8 un moyen d'utiliser Stream :: collect (collecteur) sur des streams primitifs ?

Normalement un Stream<Integer> à titre d'exemple, il existe deux méthodes de collecte :

Cependant IntStream n'a qu'une seule méthode de collecte :

Maintenant, comme exemple de code, j'ai ce qui suit :

@Override
public void run() {
    result = LongStream.range(1, maximum).boxed()
            .collect(Collectors.toMap(i -> i, i -> (int)Iterators.longStream(new CollatzGenerator(i)).count()))
            .entrySet().stream()
            .max(Comparator.comparingLong(Map.Entry::getValue))
            .get().getKey();
}

Comme vous pouvez le voir, j'ai d'abord boxé les primitives afin de pouvoir utiliser un Collectors. méthode.

Existe-t-il un moyen d'utiliser des primitives tout en conservant le même code avec Collectors.toMap ?

Était-ce utile?

La solution

Depuis Map est une interface générique, il n'y a aucun moyen de créer un Map sans boxe.Cependant, cela n’a pas de sens de rassembler des objets dans un Map du tout quand tout ce que vous voulez est de créer un autre flux (avec seulement deux valeurs enveloppées dans un Map.Entry).Vous pouvez simplement créer le Map.Entry instances sans collecter les valeurs :

LongStream.range(1, maximum)
  .mapToObj(i->new AbstractMap.SimpleEntry<>(i, Iterators.longStream(new CollatzGenerator(i)).count()))
  .max(Comparator.comparingLong(Map.Entry::getValue))
  .get().getKey();

Cela fait toujours de l'auto-boxing, mais une fois que vous êtes à ce stade, vous pouvez vous débarrasser du Map.Entry également en créant vous-même une classe de détenteurs de valeur appropriée :

static final class TwoLongs {
    final long key, value;
    TwoLongs(long k, long v) { key=k; value=v; }
    public long getKey() { return key; }
    public long getValue() { return value; }
}

Avec cette classe de titulaire, vous pouvez traiter vos données sans encadrer le longs :

LongStream.range(1, maximum)
  .mapToObj(i->new TwoLongs(i, Iterators.longStream(new CollatzGenerator(i)).count()))
  .max(Comparator.comparingLong(TwoLongs::getValue))
  .get().getKey();

Eh bien, c'est toujours une sorte de boxe, mais la création d'un élément (le TwoLongs instance) objet au lieu de trois (un Map.Entry et deux Longs).

Autres conseils

long result = LongStream.range(0, 9)
        .mapToObj(i -> new long[]{i, i})
        .max(Comparator.comparingLong(pair -> pair[1]))
        .get()[0];
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top