Collect both matching and non-matching in one stream processing?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
14
down vote

favorite
3












Is there a way to collect both matching and not matching elements of stream in one processing?
Take this example:



final List<Integer> numbers = Arrays.asList( 1, 2, 3, 4, 5 );
final List<Integer> even = numbers.stream().filter( n -> n % 2 == 0 ).collect( Collectors.toList() );
final List<Integer> odd = numbers.stream().filter( n -> n % 2 != 0 ).collect( Collectors.toList() );


Is there a way to avoid running through the list of numbers twice? Something like "collector for matches and collector for no-matches"?










share|improve this question



















  • 5




    See Collectors.partitioningBy.
    – Slaw
    yesterday














up vote
14
down vote

favorite
3












Is there a way to collect both matching and not matching elements of stream in one processing?
Take this example:



final List<Integer> numbers = Arrays.asList( 1, 2, 3, 4, 5 );
final List<Integer> even = numbers.stream().filter( n -> n % 2 == 0 ).collect( Collectors.toList() );
final List<Integer> odd = numbers.stream().filter( n -> n % 2 != 0 ).collect( Collectors.toList() );


Is there a way to avoid running through the list of numbers twice? Something like "collector for matches and collector for no-matches"?










share|improve this question



















  • 5




    See Collectors.partitioningBy.
    – Slaw
    yesterday












up vote
14
down vote

favorite
3









up vote
14
down vote

favorite
3






3





Is there a way to collect both matching and not matching elements of stream in one processing?
Take this example:



final List<Integer> numbers = Arrays.asList( 1, 2, 3, 4, 5 );
final List<Integer> even = numbers.stream().filter( n -> n % 2 == 0 ).collect( Collectors.toList() );
final List<Integer> odd = numbers.stream().filter( n -> n % 2 != 0 ).collect( Collectors.toList() );


Is there a way to avoid running through the list of numbers twice? Something like "collector for matches and collector for no-matches"?










share|improve this question















Is there a way to collect both matching and not matching elements of stream in one processing?
Take this example:



final List<Integer> numbers = Arrays.asList( 1, 2, 3, 4, 5 );
final List<Integer> even = numbers.stream().filter( n -> n % 2 == 0 ).collect( Collectors.toList() );
final List<Integer> odd = numbers.stream().filter( n -> n % 2 != 0 ).collect( Collectors.toList() );


Is there a way to avoid running through the list of numbers twice? Something like "collector for matches and collector for no-matches"?







java java-stream






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited yesterday









Oleksandr

7,62043467




7,62043467










asked yesterday









Torgeist

1789




1789







  • 5




    See Collectors.partitioningBy.
    – Slaw
    yesterday












  • 5




    See Collectors.partitioningBy.
    – Slaw
    yesterday







5




5




See Collectors.partitioningBy.
– Slaw
yesterday




See Collectors.partitioningBy.
– Slaw
yesterday












2 Answers
2






active

oldest

votes

















up vote
22
down vote



accepted










You may do it like so,



Map<Boolean, List<Integer>> oddAndEvenMap = numbers.stream()
.collect(Collectors.partitioningBy(n -> n % 2 == 0));
final List<Integer> even = oddAndEvenMap.get(true);
final List<Integer> odd = oddAndEvenMap.get(false);





share|improve this answer




















  • Thank you very much, that was it - how could I miss this?! ;) Especially helpful is the partioningBy combined with another collector, like so: Map<Boolean,Map<Integer,Boolean>> infos = numbers.stream().collect( Collectors.partitioningBy( n -> n % 2 == 0, Collectors.toMap( n->n, n-> expensiveCalculation(n) ) ) );
    – Torgeist
    yesterday

















up vote
3
down vote













If you have more than 2 groups (instead of odd and even here using %2) for example to group ints in remainder classes %3 you can use a Function:



Function<Integer, Integer> fun = i -> i%3;
List<Integer> a = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Map<Integer, List<Integer>> collect = a.stream().collect(Collectors.groupingBy(fun));

System.out.println(collect);
//0=[3, 6, 9], 1=[1, 4, 7, 10], 2=[2, 5, 8]


Or imagine you have a list of strings which you want to group by starting char
instead of grouping matching and non-matching (for e.g. starts with a or not)
you could do something like :



Function<String, Character> fun = s -> s.charAt(0);
List<String> a = Arrays.asList("baz","buzz","azz","ayy","foo","doo");
Map<Character, List<String>> collect = a.stream().collect(Collectors.groupingBy(fun));

System.out.println(collect);
//a=[azz, ayy], b=[baz, buzz], d=[doo], f=[foo]





share|improve this answer






















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53296841%2fcollect-both-matching-and-non-matching-in-one-stream-processing%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    22
    down vote



    accepted










    You may do it like so,



    Map<Boolean, List<Integer>> oddAndEvenMap = numbers.stream()
    .collect(Collectors.partitioningBy(n -> n % 2 == 0));
    final List<Integer> even = oddAndEvenMap.get(true);
    final List<Integer> odd = oddAndEvenMap.get(false);





    share|improve this answer




















    • Thank you very much, that was it - how could I miss this?! ;) Especially helpful is the partioningBy combined with another collector, like so: Map<Boolean,Map<Integer,Boolean>> infos = numbers.stream().collect( Collectors.partitioningBy( n -> n % 2 == 0, Collectors.toMap( n->n, n-> expensiveCalculation(n) ) ) );
      – Torgeist
      yesterday














    up vote
    22
    down vote



    accepted










    You may do it like so,



    Map<Boolean, List<Integer>> oddAndEvenMap = numbers.stream()
    .collect(Collectors.partitioningBy(n -> n % 2 == 0));
    final List<Integer> even = oddAndEvenMap.get(true);
    final List<Integer> odd = oddAndEvenMap.get(false);





    share|improve this answer




















    • Thank you very much, that was it - how could I miss this?! ;) Especially helpful is the partioningBy combined with another collector, like so: Map<Boolean,Map<Integer,Boolean>> infos = numbers.stream().collect( Collectors.partitioningBy( n -> n % 2 == 0, Collectors.toMap( n->n, n-> expensiveCalculation(n) ) ) );
      – Torgeist
      yesterday












    up vote
    22
    down vote



    accepted







    up vote
    22
    down vote



    accepted






    You may do it like so,



    Map<Boolean, List<Integer>> oddAndEvenMap = numbers.stream()
    .collect(Collectors.partitioningBy(n -> n % 2 == 0));
    final List<Integer> even = oddAndEvenMap.get(true);
    final List<Integer> odd = oddAndEvenMap.get(false);





    share|improve this answer












    You may do it like so,



    Map<Boolean, List<Integer>> oddAndEvenMap = numbers.stream()
    .collect(Collectors.partitioningBy(n -> n % 2 == 0));
    final List<Integer> even = oddAndEvenMap.get(true);
    final List<Integer> odd = oddAndEvenMap.get(false);






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered yesterday









    Ravindra Ranwala

    7,51831332




    7,51831332











    • Thank you very much, that was it - how could I miss this?! ;) Especially helpful is the partioningBy combined with another collector, like so: Map<Boolean,Map<Integer,Boolean>> infos = numbers.stream().collect( Collectors.partitioningBy( n -> n % 2 == 0, Collectors.toMap( n->n, n-> expensiveCalculation(n) ) ) );
      – Torgeist
      yesterday
















    • Thank you very much, that was it - how could I miss this?! ;) Especially helpful is the partioningBy combined with another collector, like so: Map<Boolean,Map<Integer,Boolean>> infos = numbers.stream().collect( Collectors.partitioningBy( n -> n % 2 == 0, Collectors.toMap( n->n, n-> expensiveCalculation(n) ) ) );
      – Torgeist
      yesterday















    Thank you very much, that was it - how could I miss this?! ;) Especially helpful is the partioningBy combined with another collector, like so: Map<Boolean,Map<Integer,Boolean>> infos = numbers.stream().collect( Collectors.partitioningBy( n -> n % 2 == 0, Collectors.toMap( n->n, n-> expensiveCalculation(n) ) ) );
    – Torgeist
    yesterday




    Thank you very much, that was it - how could I miss this?! ;) Especially helpful is the partioningBy combined with another collector, like so: Map<Boolean,Map<Integer,Boolean>> infos = numbers.stream().collect( Collectors.partitioningBy( n -> n % 2 == 0, Collectors.toMap( n->n, n-> expensiveCalculation(n) ) ) );
    – Torgeist
    yesterday












    up vote
    3
    down vote













    If you have more than 2 groups (instead of odd and even here using %2) for example to group ints in remainder classes %3 you can use a Function:



    Function<Integer, Integer> fun = i -> i%3;
    List<Integer> a = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
    Map<Integer, List<Integer>> collect = a.stream().collect(Collectors.groupingBy(fun));

    System.out.println(collect);
    //0=[3, 6, 9], 1=[1, 4, 7, 10], 2=[2, 5, 8]


    Or imagine you have a list of strings which you want to group by starting char
    instead of grouping matching and non-matching (for e.g. starts with a or not)
    you could do something like :



    Function<String, Character> fun = s -> s.charAt(0);
    List<String> a = Arrays.asList("baz","buzz","azz","ayy","foo","doo");
    Map<Character, List<String>> collect = a.stream().collect(Collectors.groupingBy(fun));

    System.out.println(collect);
    //a=[azz, ayy], b=[baz, buzz], d=[doo], f=[foo]





    share|improve this answer


























      up vote
      3
      down vote













      If you have more than 2 groups (instead of odd and even here using %2) for example to group ints in remainder classes %3 you can use a Function:



      Function<Integer, Integer> fun = i -> i%3;
      List<Integer> a = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
      Map<Integer, List<Integer>> collect = a.stream().collect(Collectors.groupingBy(fun));

      System.out.println(collect);
      //0=[3, 6, 9], 1=[1, 4, 7, 10], 2=[2, 5, 8]


      Or imagine you have a list of strings which you want to group by starting char
      instead of grouping matching and non-matching (for e.g. starts with a or not)
      you could do something like :



      Function<String, Character> fun = s -> s.charAt(0);
      List<String> a = Arrays.asList("baz","buzz","azz","ayy","foo","doo");
      Map<Character, List<String>> collect = a.stream().collect(Collectors.groupingBy(fun));

      System.out.println(collect);
      //a=[azz, ayy], b=[baz, buzz], d=[doo], f=[foo]





      share|improve this answer
























        up vote
        3
        down vote










        up vote
        3
        down vote









        If you have more than 2 groups (instead of odd and even here using %2) for example to group ints in remainder classes %3 you can use a Function:



        Function<Integer, Integer> fun = i -> i%3;
        List<Integer> a = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
        Map<Integer, List<Integer>> collect = a.stream().collect(Collectors.groupingBy(fun));

        System.out.println(collect);
        //0=[3, 6, 9], 1=[1, 4, 7, 10], 2=[2, 5, 8]


        Or imagine you have a list of strings which you want to group by starting char
        instead of grouping matching and non-matching (for e.g. starts with a or not)
        you could do something like :



        Function<String, Character> fun = s -> s.charAt(0);
        List<String> a = Arrays.asList("baz","buzz","azz","ayy","foo","doo");
        Map<Character, List<String>> collect = a.stream().collect(Collectors.groupingBy(fun));

        System.out.println(collect);
        //a=[azz, ayy], b=[baz, buzz], d=[doo], f=[foo]





        share|improve this answer














        If you have more than 2 groups (instead of odd and even here using %2) for example to group ints in remainder classes %3 you can use a Function:



        Function<Integer, Integer> fun = i -> i%3;
        List<Integer> a = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
        Map<Integer, List<Integer>> collect = a.stream().collect(Collectors.groupingBy(fun));

        System.out.println(collect);
        //0=[3, 6, 9], 1=[1, 4, 7, 10], 2=[2, 5, 8]


        Or imagine you have a list of strings which you want to group by starting char
        instead of grouping matching and non-matching (for e.g. starts with a or not)
        you could do something like :



        Function<String, Character> fun = s -> s.charAt(0);
        List<String> a = Arrays.asList("baz","buzz","azz","ayy","foo","doo");
        Map<Character, List<String>> collect = a.stream().collect(Collectors.groupingBy(fun));

        System.out.println(collect);
        //a=[azz, ayy], b=[baz, buzz], d=[doo], f=[foo]






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited yesterday

























        answered yesterday









        Eritrean

        2,8091814




        2,8091814



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53296841%2fcollect-both-matching-and-non-matching-in-one-stream-processing%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown






            Popular posts from this blog

            Peggy Mitchell

            Palaiologos

            The Forum (Inglewood, California)