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











up vote
17
down vote

favorite
4












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
    Nov 14 at 9:32















up vote
17
down vote

favorite
4












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
    Nov 14 at 9:32













up vote
17
down vote

favorite
4









up vote
17
down vote

favorite
4






4





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 Nov 14 at 9:28









Oleksandr

7,72543467




7,72543467










asked Nov 14 at 9:27









Torgeist

1939




1939








  • 5




    See Collectors.partitioningBy.
    – Slaw
    Nov 14 at 9:32














  • 5




    See Collectors.partitioningBy.
    – Slaw
    Nov 14 at 9:32








5




5




See Collectors.partitioningBy.
– Slaw
Nov 14 at 9:32




See Collectors.partitioningBy.
– Slaw
Nov 14 at 9:32












2 Answers
2






active

oldest

votes

















up vote
24
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
    Nov 14 at 10:22


















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
    24
    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
      Nov 14 at 10:22















    up vote
    24
    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
      Nov 14 at 10:22













    up vote
    24
    down vote



    accepted







    up vote
    24
    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 Nov 14 at 9:31









    Ravindra Ranwala

    7,56331332




    7,56331332












    • 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
      Nov 14 at 10:22


















    • 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
      Nov 14 at 10:22
















    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
    Nov 14 at 10:22




    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
    Nov 14 at 10:22












    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 Nov 14 at 10:51

























        answered Nov 14 at 10:33









        Eritrean

        2,8341814




        2,8341814






























             

            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

            Plaza Victoria

            In PowerPoint, is there a keyboard shortcut for bulleted / numbered list?

            How to put 3 figures in Latex with 2 figures side by side and 1 below these side by side images but in...