36 votes

Quel est le meilleur moyen de diviser une collection en 2 collections différentes?

J'ai un ensemble de chiffres:

  Set<Integer> mySet = [ 1,2,3,4,5,6,7,8,9]
 

Je veux le diviser en 2 séries de chances et de chances.

Ma façon était d'utiliser le filtre deux fois:

 Set<Integer> set1 = mySet.stream().filter(y -> y % 2 == 0).collect(Collectors.toSet())
Set<Integer> set2 =mySet.stream().filter(y -> y % 2 != 0).collect(Collectors.toSet())
 

Je n'aime pas cette solution car je revois l'ensemble du jeu deux fois.

Y a-t-il une façon plus intelligente de le faire?

39voto

Andy Turner Points 13883
 Map<Boolean, List<Integer>> partitioned = 
    set.stream().collect(Collectors.partitioningBy(x -> x%2 == 0));
 

Les éléments en partitioned.get(true) sont pairs; les éléments en partitioned.get(false) sont impairs.

Contrairement à ce qui est utilisé avec groupingBy , il est garanti que les deux listes true et false seront présentes sur la carte, même si elles sont vides. (Non documenté dans Java 8, mais c'était vrai; la documentation de Java 9 l'indique maintenant explicitement).

13voto

RAZ_Muh_Taz Points 3610

Boucle simple et si / sinon serait une solution simple et propre

 Set<Integer> setEven = new HashSet<>();
Set<Integer> setOdd = new HashSet<>();

for (Integer val : mySet) {
    if (val % 2 == 0)
        setEven.add(val);
    else
        setOdd.add(val);
}
 

Ou utiliser un opérateur ternaire fonctionne bien pour simplifier encore plus le code

 for(Integer val : mySet) {
    ((val % 2 == 0) ? setEven : setOdd).add(val);
}
 

13voto

Amit Bera Points 5628

Vous pouvez utiliser Collectors#partitioningBy comme ci-dessous.

 Map<Boolean,List<Integer>> evenOddMap  = mySet.stream().collect(Collectors.partitioningBy(e -> e % 2 == 0));
System.out.println("Even : "+evenOddMap.get(true));
System.out.println("Odd : "+evenOddMap.get(false));
 

11voto

tsolakp Points 4658

Vous pouvez utiliser Collectors.partitioningBy :

         Map< Boolean, Set<Integer> > map =
        mySet.stream().collect( Collectors.partitioningBy( y -> y % 2 == 0, 
        Collectors.toSet() ) );

        Set<Integer> odds = map.get(Boolean.TRUE);
        Set<Integer> evens = map.get(Boolean.FALSE);
 

MODIFIER:

Je vois qu'il y a quelques réponses similaires. La légère différence ici est qu’elle montre comment obtenir les collections sous forme de Set au lieu de List au cas où OP le souhaiterait ainsi.

1voto

Amar Dev Points 534

Si vous avez déjà des collections pour contenir des valeurs, la liste ci-dessous peut constituer une solution.

 data.stream().forEach(x -> {
if(x%2==0){
//add to collection holding even nums
} else {
//add to collection holding odd nums
}
})
 

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