Return List from Method in Java 8?












3















I have the following method (see below). The code is working but I got сomments that there is a lot of repeating and that I should use IntStream.



Could you specify how to better optimize the code? Thanks in advance.



public static List<Integer> oddOrEven(List<Integer> integers) {
long sum = integers.stream().mapToInt(i ->i).summaryStatistics().getSum();
if (sum % 2 == 0) {
return integers.stream().filter(x -> x % 2==0).distinct().collect(Collectors.toList());
} else if (sum % 2 != 0) {
return integers.stream().filter(x -> x % 2 != 0).distinct().collect(Collectors.toList());
}
return null;
}









share|improve this question




















  • 7





    Questions about working code belong on Code Review.

    – Michael
    Nov 14 '18 at 14:36











  • I was interested in IntStream part. If you receive a List of integers, why would someone emphasize it? It fits better for creating a stream from nothing.

    – vahdet
    Nov 14 '18 at 14:39











  • Instead of .summaryStatistics().getSum() you can simply use sum(). Further, if (sum % 2 != 0) is obsolete, as at this place, the condition must be true. When you remove it, you can remove that unreachable return null; too. Besides that, you are using mapToInt, hence you are using IntStream.

    – Holger
    Nov 14 '18 at 19:02
















3















I have the following method (see below). The code is working but I got сomments that there is a lot of repeating and that I should use IntStream.



Could you specify how to better optimize the code? Thanks in advance.



public static List<Integer> oddOrEven(List<Integer> integers) {
long sum = integers.stream().mapToInt(i ->i).summaryStatistics().getSum();
if (sum % 2 == 0) {
return integers.stream().filter(x -> x % 2==0).distinct().collect(Collectors.toList());
} else if (sum % 2 != 0) {
return integers.stream().filter(x -> x % 2 != 0).distinct().collect(Collectors.toList());
}
return null;
}









share|improve this question




















  • 7





    Questions about working code belong on Code Review.

    – Michael
    Nov 14 '18 at 14:36











  • I was interested in IntStream part. If you receive a List of integers, why would someone emphasize it? It fits better for creating a stream from nothing.

    – vahdet
    Nov 14 '18 at 14:39











  • Instead of .summaryStatistics().getSum() you can simply use sum(). Further, if (sum % 2 != 0) is obsolete, as at this place, the condition must be true. When you remove it, you can remove that unreachable return null; too. Besides that, you are using mapToInt, hence you are using IntStream.

    – Holger
    Nov 14 '18 at 19:02














3












3








3








I have the following method (see below). The code is working but I got сomments that there is a lot of repeating and that I should use IntStream.



Could you specify how to better optimize the code? Thanks in advance.



public static List<Integer> oddOrEven(List<Integer> integers) {
long sum = integers.stream().mapToInt(i ->i).summaryStatistics().getSum();
if (sum % 2 == 0) {
return integers.stream().filter(x -> x % 2==0).distinct().collect(Collectors.toList());
} else if (sum % 2 != 0) {
return integers.stream().filter(x -> x % 2 != 0).distinct().collect(Collectors.toList());
}
return null;
}









share|improve this question
















I have the following method (see below). The code is working but I got сomments that there is a lot of repeating and that I should use IntStream.



Could you specify how to better optimize the code? Thanks in advance.



public static List<Integer> oddOrEven(List<Integer> integers) {
long sum = integers.stream().mapToInt(i ->i).summaryStatistics().getSum();
if (sum % 2 == 0) {
return integers.stream().filter(x -> x % 2==0).distinct().collect(Collectors.toList());
} else if (sum % 2 != 0) {
return integers.stream().filter(x -> x % 2 != 0).distinct().collect(Collectors.toList());
}
return null;
}






java java-8 java-stream






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 14 '18 at 14:49









Eran

285k37463551




285k37463551










asked Nov 14 '18 at 14:32









EugeneEugene

222




222








  • 7





    Questions about working code belong on Code Review.

    – Michael
    Nov 14 '18 at 14:36











  • I was interested in IntStream part. If you receive a List of integers, why would someone emphasize it? It fits better for creating a stream from nothing.

    – vahdet
    Nov 14 '18 at 14:39











  • Instead of .summaryStatistics().getSum() you can simply use sum(). Further, if (sum % 2 != 0) is obsolete, as at this place, the condition must be true. When you remove it, you can remove that unreachable return null; too. Besides that, you are using mapToInt, hence you are using IntStream.

    – Holger
    Nov 14 '18 at 19:02














  • 7





    Questions about working code belong on Code Review.

    – Michael
    Nov 14 '18 at 14:36











  • I was interested in IntStream part. If you receive a List of integers, why would someone emphasize it? It fits better for creating a stream from nothing.

    – vahdet
    Nov 14 '18 at 14:39











  • Instead of .summaryStatistics().getSum() you can simply use sum(). Further, if (sum % 2 != 0) is obsolete, as at this place, the condition must be true. When you remove it, you can remove that unreachable return null; too. Besides that, you are using mapToInt, hence you are using IntStream.

    – Holger
    Nov 14 '18 at 19:02








7




7





Questions about working code belong on Code Review.

– Michael
Nov 14 '18 at 14:36





Questions about working code belong on Code Review.

– Michael
Nov 14 '18 at 14:36













I was interested in IntStream part. If you receive a List of integers, why would someone emphasize it? It fits better for creating a stream from nothing.

– vahdet
Nov 14 '18 at 14:39





I was interested in IntStream part. If you receive a List of integers, why would someone emphasize it? It fits better for creating a stream from nothing.

– vahdet
Nov 14 '18 at 14:39













Instead of .summaryStatistics().getSum() you can simply use sum(). Further, if (sum % 2 != 0) is obsolete, as at this place, the condition must be true. When you remove it, you can remove that unreachable return null; too. Besides that, you are using mapToInt, hence you are using IntStream.

– Holger
Nov 14 '18 at 19:02





Instead of .summaryStatistics().getSum() you can simply use sum(). Further, if (sum % 2 != 0) is obsolete, as at this place, the condition must be true. When you remove it, you can remove that unreachable return null; too. Besides that, you are using mapToInt, hence you are using IntStream.

– Holger
Nov 14 '18 at 19:02












4 Answers
4






active

oldest

votes


















8














It looks like you only need the sum of the elements in order to check if it's odd or even. To know that, it's enough to check if the number of odd elements is odd or even.



You can split the input into odd and even lists, and decide which one to return based on the size of the odd List:



public static List<Integer> oddOrEven(List<Integer> integers) {
Map<Boolean,List<Integer>>
oddsAndEvens = integers.stream()
.collect(Collectors.partitioningBy(i->i%2==0));
return oddsAndEvens.get(false).size() % 2 == 0 ? // check if there's an even number of odd
// elements, which means the sum is even
oddsAndEvens.get(true) : // return the even elements
oddsAndEvens.get(false); // return the odd elements
}


Testing:



System.out.println (oddOrEven(Arrays.asList (1,2,3,4,5)));
System.out.println (oddOrEven(Arrays.asList (1,2,3,4,5,3)));


Output:



[1, 3, 5]
[2, 4]


EDIT:



In my original answer I missed the distinct() step, which should be performed after we decide whether to return the odd or even elements. I'm afraid this requires adding a second Stream pipeline:



public static List<Integer> oddOrEven(List<Integer> integers) {
Map<Boolean,List<Integer>>
oddsAndEvens = integers.stream()
.collect(Collectors.partitioningBy(i->i%2==0));
return oddsAndEvens.get(false).size() % 2 == 0 ?
oddsAndEvens.get(true).stream().distinct().collect(Collectors.toList()) :
oddsAndEvens.get(false).stream().distinct().collect(Collectors.toList());
}


or (with Holger's suggestion):



public static List<Integer> oddOrEven(List<Integer> integers) {
Map<Boolean,List<Integer>>
oddsAndEvens = integers.stream()
.collect(Collectors.partitioningBy(i->i%2==0));
return oddsAndEvens.get(oddsAndEvens.get(false).size() % 2 == 0)
.stream()
.distinct()
.collect(Collectors.toList());
}





share|improve this answer


























  • @Floegipoky I missed the distinct() call in the OP's code. Thanks for pointing it out. I'll modify the answer later.

    – Eran
    Nov 14 '18 at 16:49






  • 2





    Why not return oddsAndEvens.get(oddsAndEvens.get(false).size() % 2 == 0);?

    – Holger
    Nov 14 '18 at 18:59











  • @Holger nice improvement

    – Eran
    Nov 15 '18 at 6:19











  • Also instead of distinct you can collect to Set (which will make it even easier for the consumer of your method to know that there are only distinct items) - you can use Collectors.toSet or if you want to preserve the order Collectors.toCollection(LinkedHashSet::new). That's just an idea ;)

    – Veselin Davidov
    Nov 15 '18 at 15:27





















2














 long sum = integers.stream().reduce(0, (u, v) -> u + v);
return integers.stream().filter(x -> (x % 2)==(sum % 2)).distinct().collect(Collectors.toList());





share|improve this answer


























  • Thank you so much. It's a wrap!)

    – Eugene
    Nov 14 '18 at 14:57











  • This will not work if the list contains negative numbers. Try oddOrEven(Arrays.asList(1, -2)), for example.

    – Hoopje
    Nov 14 '18 at 14:57






  • 2





    yeah an abs() is needed or a bit check like (x & 1) ==(sum & 1)

    – Veselin Davidov
    Nov 14 '18 at 15:06



















1














I will give you one simpler solution which uses the standard java language constructs without creating other parasite objects which streams create. I don't say streams are bad. What I am saying is that if you pass a List to a method and return a List then the conversion to stream and collecting back to list is extra work you don't need and you shouldn't do. You can try it for educational purposes and to learn streams but in this particular case you just lose performance and if you start doing it like that everywhere in real application it will add up and it can become significant problem. Even though premature optimization is not a good thing the same can be said to doing everything with streams just because they are in Java and not care about performance at all.



If we have even number of odd numbers then the sum is also even. So here is some code with bitwise operators (just for fun - you can write it with standard i % 2 etc.):



public static Collection<Integer> oddOrEven(List<Integer> integers) {
int mod = 0;
for (Integer i : integers) {
if((i & 1) == 1) mod=mod^1;
}
Set<Integer> result = new HashSet<>();
for (Integer i : integers){
if (((i & 1) ^ mod)==0)
result.add(i);

}
return result; //Converting to set because we want distinct results.
// If the order is important we can use treeset or convert to list
}


You can do some testing against the other Stream based solutions. The solution using standard java construct without the extra overload will be the same speed or faster in most cases. For example using map is nice but with bigger list with lots of repeating numbers at some point the amount of collisions can make it many times slower than the other ways. The complexity of all algorithms is linear but the amount of work in one iteration can vary with the different stream solutions (as well as the old school approach) and if one doesn't know what is the loss there maybe sticking to the well known and easy to predict scenario is better.






share|improve this answer


























  • The fact that you are getting better than linear scaling is an indicator that your benchmark is flawed. Further, you are ignoring the distinct() aspect of the stream solution, so the results are not comparable anyway.

    – Holger
    Nov 14 '18 at 19:11











  • Actually there are many benchmarks showing such results in similar situations. I am not saying that streams shouldn't be used but different solutions of the same problem have pros and cons. And many people go for the hype of streams without understanding/thinking about the cons. If your app is not built around streams with the extra conversions you rarely win something else than a modern looking code. And in this case we don't even benefit from good stuff from streams like lazyness. It was simple benchmark probably not 100% correct but I wanted to show a point

    – Veselin Davidov
    Nov 14 '18 at 21:58













  • It does not even qualify to be called “benchmark”. It starts with the fact that did not document the measuring method at all. You could have made up these numbers as well. Combining this with the fact that you are comparing code doing entirely different things (the missing distinct) and that the result numbers are obviously irregular, hence, entirely meaningless, makes this answer worthless. It’s a pity, as the code examples are not bad.

    – Holger
    Nov 15 '18 at 8:03











  • I just want to give the readers another point of view. If they want they can do their own benchmarks or read some in the internet. If they like the stream solution better or find it more readable - great. I can give my testing code but it will overload the response. For example here is a nice blog that covers such issues blog.jooq.org/2015/12/08/… there are many public benchmarks comparing List->stream->List to standard java for construct

    – Veselin Davidov
    Nov 15 '18 at 8:38











  • I have no problems with your point of view. You already stated it at the beginning of the answer. But I would remove these numbers if I were you. They are not necessary anyway.

    – Holger
    Nov 15 '18 at 15:09



















0














public static List<Integer> oddOrEven(List<Integer> integers) {
Function<Integer, Integer> fun = i -> i%2;
Map<Integer, List<Integer>> map = integers.stream().collect(Collectors.groupingBy(fun));
return map.get(1).size()%2 == 0? map.get(0): map.get(1);
}





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',
    autoActivateHeartbeat: false,
    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%2f53302605%2freturn-listinteger-from-method-in-java-8%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    8














    It looks like you only need the sum of the elements in order to check if it's odd or even. To know that, it's enough to check if the number of odd elements is odd or even.



    You can split the input into odd and even lists, and decide which one to return based on the size of the odd List:



    public static List<Integer> oddOrEven(List<Integer> integers) {
    Map<Boolean,List<Integer>>
    oddsAndEvens = integers.stream()
    .collect(Collectors.partitioningBy(i->i%2==0));
    return oddsAndEvens.get(false).size() % 2 == 0 ? // check if there's an even number of odd
    // elements, which means the sum is even
    oddsAndEvens.get(true) : // return the even elements
    oddsAndEvens.get(false); // return the odd elements
    }


    Testing:



    System.out.println (oddOrEven(Arrays.asList (1,2,3,4,5)));
    System.out.println (oddOrEven(Arrays.asList (1,2,3,4,5,3)));


    Output:



    [1, 3, 5]
    [2, 4]


    EDIT:



    In my original answer I missed the distinct() step, which should be performed after we decide whether to return the odd or even elements. I'm afraid this requires adding a second Stream pipeline:



    public static List<Integer> oddOrEven(List<Integer> integers) {
    Map<Boolean,List<Integer>>
    oddsAndEvens = integers.stream()
    .collect(Collectors.partitioningBy(i->i%2==0));
    return oddsAndEvens.get(false).size() % 2 == 0 ?
    oddsAndEvens.get(true).stream().distinct().collect(Collectors.toList()) :
    oddsAndEvens.get(false).stream().distinct().collect(Collectors.toList());
    }


    or (with Holger's suggestion):



    public static List<Integer> oddOrEven(List<Integer> integers) {
    Map<Boolean,List<Integer>>
    oddsAndEvens = integers.stream()
    .collect(Collectors.partitioningBy(i->i%2==0));
    return oddsAndEvens.get(oddsAndEvens.get(false).size() % 2 == 0)
    .stream()
    .distinct()
    .collect(Collectors.toList());
    }





    share|improve this answer


























    • @Floegipoky I missed the distinct() call in the OP's code. Thanks for pointing it out. I'll modify the answer later.

      – Eran
      Nov 14 '18 at 16:49






    • 2





      Why not return oddsAndEvens.get(oddsAndEvens.get(false).size() % 2 == 0);?

      – Holger
      Nov 14 '18 at 18:59











    • @Holger nice improvement

      – Eran
      Nov 15 '18 at 6:19











    • Also instead of distinct you can collect to Set (which will make it even easier for the consumer of your method to know that there are only distinct items) - you can use Collectors.toSet or if you want to preserve the order Collectors.toCollection(LinkedHashSet::new). That's just an idea ;)

      – Veselin Davidov
      Nov 15 '18 at 15:27


















    8














    It looks like you only need the sum of the elements in order to check if it's odd or even. To know that, it's enough to check if the number of odd elements is odd or even.



    You can split the input into odd and even lists, and decide which one to return based on the size of the odd List:



    public static List<Integer> oddOrEven(List<Integer> integers) {
    Map<Boolean,List<Integer>>
    oddsAndEvens = integers.stream()
    .collect(Collectors.partitioningBy(i->i%2==0));
    return oddsAndEvens.get(false).size() % 2 == 0 ? // check if there's an even number of odd
    // elements, which means the sum is even
    oddsAndEvens.get(true) : // return the even elements
    oddsAndEvens.get(false); // return the odd elements
    }


    Testing:



    System.out.println (oddOrEven(Arrays.asList (1,2,3,4,5)));
    System.out.println (oddOrEven(Arrays.asList (1,2,3,4,5,3)));


    Output:



    [1, 3, 5]
    [2, 4]


    EDIT:



    In my original answer I missed the distinct() step, which should be performed after we decide whether to return the odd or even elements. I'm afraid this requires adding a second Stream pipeline:



    public static List<Integer> oddOrEven(List<Integer> integers) {
    Map<Boolean,List<Integer>>
    oddsAndEvens = integers.stream()
    .collect(Collectors.partitioningBy(i->i%2==0));
    return oddsAndEvens.get(false).size() % 2 == 0 ?
    oddsAndEvens.get(true).stream().distinct().collect(Collectors.toList()) :
    oddsAndEvens.get(false).stream().distinct().collect(Collectors.toList());
    }


    or (with Holger's suggestion):



    public static List<Integer> oddOrEven(List<Integer> integers) {
    Map<Boolean,List<Integer>>
    oddsAndEvens = integers.stream()
    .collect(Collectors.partitioningBy(i->i%2==0));
    return oddsAndEvens.get(oddsAndEvens.get(false).size() % 2 == 0)
    .stream()
    .distinct()
    .collect(Collectors.toList());
    }





    share|improve this answer


























    • @Floegipoky I missed the distinct() call in the OP's code. Thanks for pointing it out. I'll modify the answer later.

      – Eran
      Nov 14 '18 at 16:49






    • 2





      Why not return oddsAndEvens.get(oddsAndEvens.get(false).size() % 2 == 0);?

      – Holger
      Nov 14 '18 at 18:59











    • @Holger nice improvement

      – Eran
      Nov 15 '18 at 6:19











    • Also instead of distinct you can collect to Set (which will make it even easier for the consumer of your method to know that there are only distinct items) - you can use Collectors.toSet or if you want to preserve the order Collectors.toCollection(LinkedHashSet::new). That's just an idea ;)

      – Veselin Davidov
      Nov 15 '18 at 15:27
















    8












    8








    8







    It looks like you only need the sum of the elements in order to check if it's odd or even. To know that, it's enough to check if the number of odd elements is odd or even.



    You can split the input into odd and even lists, and decide which one to return based on the size of the odd List:



    public static List<Integer> oddOrEven(List<Integer> integers) {
    Map<Boolean,List<Integer>>
    oddsAndEvens = integers.stream()
    .collect(Collectors.partitioningBy(i->i%2==0));
    return oddsAndEvens.get(false).size() % 2 == 0 ? // check if there's an even number of odd
    // elements, which means the sum is even
    oddsAndEvens.get(true) : // return the even elements
    oddsAndEvens.get(false); // return the odd elements
    }


    Testing:



    System.out.println (oddOrEven(Arrays.asList (1,2,3,4,5)));
    System.out.println (oddOrEven(Arrays.asList (1,2,3,4,5,3)));


    Output:



    [1, 3, 5]
    [2, 4]


    EDIT:



    In my original answer I missed the distinct() step, which should be performed after we decide whether to return the odd or even elements. I'm afraid this requires adding a second Stream pipeline:



    public static List<Integer> oddOrEven(List<Integer> integers) {
    Map<Boolean,List<Integer>>
    oddsAndEvens = integers.stream()
    .collect(Collectors.partitioningBy(i->i%2==0));
    return oddsAndEvens.get(false).size() % 2 == 0 ?
    oddsAndEvens.get(true).stream().distinct().collect(Collectors.toList()) :
    oddsAndEvens.get(false).stream().distinct().collect(Collectors.toList());
    }


    or (with Holger's suggestion):



    public static List<Integer> oddOrEven(List<Integer> integers) {
    Map<Boolean,List<Integer>>
    oddsAndEvens = integers.stream()
    .collect(Collectors.partitioningBy(i->i%2==0));
    return oddsAndEvens.get(oddsAndEvens.get(false).size() % 2 == 0)
    .stream()
    .distinct()
    .collect(Collectors.toList());
    }





    share|improve this answer















    It looks like you only need the sum of the elements in order to check if it's odd or even. To know that, it's enough to check if the number of odd elements is odd or even.



    You can split the input into odd and even lists, and decide which one to return based on the size of the odd List:



    public static List<Integer> oddOrEven(List<Integer> integers) {
    Map<Boolean,List<Integer>>
    oddsAndEvens = integers.stream()
    .collect(Collectors.partitioningBy(i->i%2==0));
    return oddsAndEvens.get(false).size() % 2 == 0 ? // check if there's an even number of odd
    // elements, which means the sum is even
    oddsAndEvens.get(true) : // return the even elements
    oddsAndEvens.get(false); // return the odd elements
    }


    Testing:



    System.out.println (oddOrEven(Arrays.asList (1,2,3,4,5)));
    System.out.println (oddOrEven(Arrays.asList (1,2,3,4,5,3)));


    Output:



    [1, 3, 5]
    [2, 4]


    EDIT:



    In my original answer I missed the distinct() step, which should be performed after we decide whether to return the odd or even elements. I'm afraid this requires adding a second Stream pipeline:



    public static List<Integer> oddOrEven(List<Integer> integers) {
    Map<Boolean,List<Integer>>
    oddsAndEvens = integers.stream()
    .collect(Collectors.partitioningBy(i->i%2==0));
    return oddsAndEvens.get(false).size() % 2 == 0 ?
    oddsAndEvens.get(true).stream().distinct().collect(Collectors.toList()) :
    oddsAndEvens.get(false).stream().distinct().collect(Collectors.toList());
    }


    or (with Holger's suggestion):



    public static List<Integer> oddOrEven(List<Integer> integers) {
    Map<Boolean,List<Integer>>
    oddsAndEvens = integers.stream()
    .collect(Collectors.partitioningBy(i->i%2==0));
    return oddsAndEvens.get(oddsAndEvens.get(false).size() % 2 == 0)
    .stream()
    .distinct()
    .collect(Collectors.toList());
    }






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 15 '18 at 6:18

























    answered Nov 14 '18 at 14:37









    EranEran

    285k37463551




    285k37463551













    • @Floegipoky I missed the distinct() call in the OP's code. Thanks for pointing it out. I'll modify the answer later.

      – Eran
      Nov 14 '18 at 16:49






    • 2





      Why not return oddsAndEvens.get(oddsAndEvens.get(false).size() % 2 == 0);?

      – Holger
      Nov 14 '18 at 18:59











    • @Holger nice improvement

      – Eran
      Nov 15 '18 at 6:19











    • Also instead of distinct you can collect to Set (which will make it even easier for the consumer of your method to know that there are only distinct items) - you can use Collectors.toSet or if you want to preserve the order Collectors.toCollection(LinkedHashSet::new). That's just an idea ;)

      – Veselin Davidov
      Nov 15 '18 at 15:27





















    • @Floegipoky I missed the distinct() call in the OP's code. Thanks for pointing it out. I'll modify the answer later.

      – Eran
      Nov 14 '18 at 16:49






    • 2





      Why not return oddsAndEvens.get(oddsAndEvens.get(false).size() % 2 == 0);?

      – Holger
      Nov 14 '18 at 18:59











    • @Holger nice improvement

      – Eran
      Nov 15 '18 at 6:19











    • Also instead of distinct you can collect to Set (which will make it even easier for the consumer of your method to know that there are only distinct items) - you can use Collectors.toSet or if you want to preserve the order Collectors.toCollection(LinkedHashSet::new). That's just an idea ;)

      – Veselin Davidov
      Nov 15 '18 at 15:27



















    @Floegipoky I missed the distinct() call in the OP's code. Thanks for pointing it out. I'll modify the answer later.

    – Eran
    Nov 14 '18 at 16:49





    @Floegipoky I missed the distinct() call in the OP's code. Thanks for pointing it out. I'll modify the answer later.

    – Eran
    Nov 14 '18 at 16:49




    2




    2





    Why not return oddsAndEvens.get(oddsAndEvens.get(false).size() % 2 == 0);?

    – Holger
    Nov 14 '18 at 18:59





    Why not return oddsAndEvens.get(oddsAndEvens.get(false).size() % 2 == 0);?

    – Holger
    Nov 14 '18 at 18:59













    @Holger nice improvement

    – Eran
    Nov 15 '18 at 6:19





    @Holger nice improvement

    – Eran
    Nov 15 '18 at 6:19













    Also instead of distinct you can collect to Set (which will make it even easier for the consumer of your method to know that there are only distinct items) - you can use Collectors.toSet or if you want to preserve the order Collectors.toCollection(LinkedHashSet::new). That's just an idea ;)

    – Veselin Davidov
    Nov 15 '18 at 15:27







    Also instead of distinct you can collect to Set (which will make it even easier for the consumer of your method to know that there are only distinct items) - you can use Collectors.toSet or if you want to preserve the order Collectors.toCollection(LinkedHashSet::new). That's just an idea ;)

    – Veselin Davidov
    Nov 15 '18 at 15:27















    2














     long sum = integers.stream().reduce(0, (u, v) -> u + v);
    return integers.stream().filter(x -> (x % 2)==(sum % 2)).distinct().collect(Collectors.toList());





    share|improve this answer


























    • Thank you so much. It's a wrap!)

      – Eugene
      Nov 14 '18 at 14:57











    • This will not work if the list contains negative numbers. Try oddOrEven(Arrays.asList(1, -2)), for example.

      – Hoopje
      Nov 14 '18 at 14:57






    • 2





      yeah an abs() is needed or a bit check like (x & 1) ==(sum & 1)

      – Veselin Davidov
      Nov 14 '18 at 15:06
















    2














     long sum = integers.stream().reduce(0, (u, v) -> u + v);
    return integers.stream().filter(x -> (x % 2)==(sum % 2)).distinct().collect(Collectors.toList());





    share|improve this answer


























    • Thank you so much. It's a wrap!)

      – Eugene
      Nov 14 '18 at 14:57











    • This will not work if the list contains negative numbers. Try oddOrEven(Arrays.asList(1, -2)), for example.

      – Hoopje
      Nov 14 '18 at 14:57






    • 2





      yeah an abs() is needed or a bit check like (x & 1) ==(sum & 1)

      – Veselin Davidov
      Nov 14 '18 at 15:06














    2












    2








    2







     long sum = integers.stream().reduce(0, (u, v) -> u + v);
    return integers.stream().filter(x -> (x % 2)==(sum % 2)).distinct().collect(Collectors.toList());





    share|improve this answer















     long sum = integers.stream().reduce(0, (u, v) -> u + v);
    return integers.stream().filter(x -> (x % 2)==(sum % 2)).distinct().collect(Collectors.toList());






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 14 '18 at 14:54

























    answered Nov 14 '18 at 14:38









    IlyaIlya

    21719




    21719













    • Thank you so much. It's a wrap!)

      – Eugene
      Nov 14 '18 at 14:57











    • This will not work if the list contains negative numbers. Try oddOrEven(Arrays.asList(1, -2)), for example.

      – Hoopje
      Nov 14 '18 at 14:57






    • 2





      yeah an abs() is needed or a bit check like (x & 1) ==(sum & 1)

      – Veselin Davidov
      Nov 14 '18 at 15:06



















    • Thank you so much. It's a wrap!)

      – Eugene
      Nov 14 '18 at 14:57











    • This will not work if the list contains negative numbers. Try oddOrEven(Arrays.asList(1, -2)), for example.

      – Hoopje
      Nov 14 '18 at 14:57






    • 2





      yeah an abs() is needed or a bit check like (x & 1) ==(sum & 1)

      – Veselin Davidov
      Nov 14 '18 at 15:06

















    Thank you so much. It's a wrap!)

    – Eugene
    Nov 14 '18 at 14:57





    Thank you so much. It's a wrap!)

    – Eugene
    Nov 14 '18 at 14:57













    This will not work if the list contains negative numbers. Try oddOrEven(Arrays.asList(1, -2)), for example.

    – Hoopje
    Nov 14 '18 at 14:57





    This will not work if the list contains negative numbers. Try oddOrEven(Arrays.asList(1, -2)), for example.

    – Hoopje
    Nov 14 '18 at 14:57




    2




    2





    yeah an abs() is needed or a bit check like (x & 1) ==(sum & 1)

    – Veselin Davidov
    Nov 14 '18 at 15:06





    yeah an abs() is needed or a bit check like (x & 1) ==(sum & 1)

    – Veselin Davidov
    Nov 14 '18 at 15:06











    1














    I will give you one simpler solution which uses the standard java language constructs without creating other parasite objects which streams create. I don't say streams are bad. What I am saying is that if you pass a List to a method and return a List then the conversion to stream and collecting back to list is extra work you don't need and you shouldn't do. You can try it for educational purposes and to learn streams but in this particular case you just lose performance and if you start doing it like that everywhere in real application it will add up and it can become significant problem. Even though premature optimization is not a good thing the same can be said to doing everything with streams just because they are in Java and not care about performance at all.



    If we have even number of odd numbers then the sum is also even. So here is some code with bitwise operators (just for fun - you can write it with standard i % 2 etc.):



    public static Collection<Integer> oddOrEven(List<Integer> integers) {
    int mod = 0;
    for (Integer i : integers) {
    if((i & 1) == 1) mod=mod^1;
    }
    Set<Integer> result = new HashSet<>();
    for (Integer i : integers){
    if (((i & 1) ^ mod)==0)
    result.add(i);

    }
    return result; //Converting to set because we want distinct results.
    // If the order is important we can use treeset or convert to list
    }


    You can do some testing against the other Stream based solutions. The solution using standard java construct without the extra overload will be the same speed or faster in most cases. For example using map is nice but with bigger list with lots of repeating numbers at some point the amount of collisions can make it many times slower than the other ways. The complexity of all algorithms is linear but the amount of work in one iteration can vary with the different stream solutions (as well as the old school approach) and if one doesn't know what is the loss there maybe sticking to the well known and easy to predict scenario is better.






    share|improve this answer


























    • The fact that you are getting better than linear scaling is an indicator that your benchmark is flawed. Further, you are ignoring the distinct() aspect of the stream solution, so the results are not comparable anyway.

      – Holger
      Nov 14 '18 at 19:11











    • Actually there are many benchmarks showing such results in similar situations. I am not saying that streams shouldn't be used but different solutions of the same problem have pros and cons. And many people go for the hype of streams without understanding/thinking about the cons. If your app is not built around streams with the extra conversions you rarely win something else than a modern looking code. And in this case we don't even benefit from good stuff from streams like lazyness. It was simple benchmark probably not 100% correct but I wanted to show a point

      – Veselin Davidov
      Nov 14 '18 at 21:58













    • It does not even qualify to be called “benchmark”. It starts with the fact that did not document the measuring method at all. You could have made up these numbers as well. Combining this with the fact that you are comparing code doing entirely different things (the missing distinct) and that the result numbers are obviously irregular, hence, entirely meaningless, makes this answer worthless. It’s a pity, as the code examples are not bad.

      – Holger
      Nov 15 '18 at 8:03











    • I just want to give the readers another point of view. If they want they can do their own benchmarks or read some in the internet. If they like the stream solution better or find it more readable - great. I can give my testing code but it will overload the response. For example here is a nice blog that covers such issues blog.jooq.org/2015/12/08/… there are many public benchmarks comparing List->stream->List to standard java for construct

      – Veselin Davidov
      Nov 15 '18 at 8:38











    • I have no problems with your point of view. You already stated it at the beginning of the answer. But I would remove these numbers if I were you. They are not necessary anyway.

      – Holger
      Nov 15 '18 at 15:09
















    1














    I will give you one simpler solution which uses the standard java language constructs without creating other parasite objects which streams create. I don't say streams are bad. What I am saying is that if you pass a List to a method and return a List then the conversion to stream and collecting back to list is extra work you don't need and you shouldn't do. You can try it for educational purposes and to learn streams but in this particular case you just lose performance and if you start doing it like that everywhere in real application it will add up and it can become significant problem. Even though premature optimization is not a good thing the same can be said to doing everything with streams just because they are in Java and not care about performance at all.



    If we have even number of odd numbers then the sum is also even. So here is some code with bitwise operators (just for fun - you can write it with standard i % 2 etc.):



    public static Collection<Integer> oddOrEven(List<Integer> integers) {
    int mod = 0;
    for (Integer i : integers) {
    if((i & 1) == 1) mod=mod^1;
    }
    Set<Integer> result = new HashSet<>();
    for (Integer i : integers){
    if (((i & 1) ^ mod)==0)
    result.add(i);

    }
    return result; //Converting to set because we want distinct results.
    // If the order is important we can use treeset or convert to list
    }


    You can do some testing against the other Stream based solutions. The solution using standard java construct without the extra overload will be the same speed or faster in most cases. For example using map is nice but with bigger list with lots of repeating numbers at some point the amount of collisions can make it many times slower than the other ways. The complexity of all algorithms is linear but the amount of work in one iteration can vary with the different stream solutions (as well as the old school approach) and if one doesn't know what is the loss there maybe sticking to the well known and easy to predict scenario is better.






    share|improve this answer


























    • The fact that you are getting better than linear scaling is an indicator that your benchmark is flawed. Further, you are ignoring the distinct() aspect of the stream solution, so the results are not comparable anyway.

      – Holger
      Nov 14 '18 at 19:11











    • Actually there are many benchmarks showing such results in similar situations. I am not saying that streams shouldn't be used but different solutions of the same problem have pros and cons. And many people go for the hype of streams without understanding/thinking about the cons. If your app is not built around streams with the extra conversions you rarely win something else than a modern looking code. And in this case we don't even benefit from good stuff from streams like lazyness. It was simple benchmark probably not 100% correct but I wanted to show a point

      – Veselin Davidov
      Nov 14 '18 at 21:58













    • It does not even qualify to be called “benchmark”. It starts with the fact that did not document the measuring method at all. You could have made up these numbers as well. Combining this with the fact that you are comparing code doing entirely different things (the missing distinct) and that the result numbers are obviously irregular, hence, entirely meaningless, makes this answer worthless. It’s a pity, as the code examples are not bad.

      – Holger
      Nov 15 '18 at 8:03











    • I just want to give the readers another point of view. If they want they can do their own benchmarks or read some in the internet. If they like the stream solution better or find it more readable - great. I can give my testing code but it will overload the response. For example here is a nice blog that covers such issues blog.jooq.org/2015/12/08/… there are many public benchmarks comparing List->stream->List to standard java for construct

      – Veselin Davidov
      Nov 15 '18 at 8:38











    • I have no problems with your point of view. You already stated it at the beginning of the answer. But I would remove these numbers if I were you. They are not necessary anyway.

      – Holger
      Nov 15 '18 at 15:09














    1












    1








    1







    I will give you one simpler solution which uses the standard java language constructs without creating other parasite objects which streams create. I don't say streams are bad. What I am saying is that if you pass a List to a method and return a List then the conversion to stream and collecting back to list is extra work you don't need and you shouldn't do. You can try it for educational purposes and to learn streams but in this particular case you just lose performance and if you start doing it like that everywhere in real application it will add up and it can become significant problem. Even though premature optimization is not a good thing the same can be said to doing everything with streams just because they are in Java and not care about performance at all.



    If we have even number of odd numbers then the sum is also even. So here is some code with bitwise operators (just for fun - you can write it with standard i % 2 etc.):



    public static Collection<Integer> oddOrEven(List<Integer> integers) {
    int mod = 0;
    for (Integer i : integers) {
    if((i & 1) == 1) mod=mod^1;
    }
    Set<Integer> result = new HashSet<>();
    for (Integer i : integers){
    if (((i & 1) ^ mod)==0)
    result.add(i);

    }
    return result; //Converting to set because we want distinct results.
    // If the order is important we can use treeset or convert to list
    }


    You can do some testing against the other Stream based solutions. The solution using standard java construct without the extra overload will be the same speed or faster in most cases. For example using map is nice but with bigger list with lots of repeating numbers at some point the amount of collisions can make it many times slower than the other ways. The complexity of all algorithms is linear but the amount of work in one iteration can vary with the different stream solutions (as well as the old school approach) and if one doesn't know what is the loss there maybe sticking to the well known and easy to predict scenario is better.






    share|improve this answer















    I will give you one simpler solution which uses the standard java language constructs without creating other parasite objects which streams create. I don't say streams are bad. What I am saying is that if you pass a List to a method and return a List then the conversion to stream and collecting back to list is extra work you don't need and you shouldn't do. You can try it for educational purposes and to learn streams but in this particular case you just lose performance and if you start doing it like that everywhere in real application it will add up and it can become significant problem. Even though premature optimization is not a good thing the same can be said to doing everything with streams just because they are in Java and not care about performance at all.



    If we have even number of odd numbers then the sum is also even. So here is some code with bitwise operators (just for fun - you can write it with standard i % 2 etc.):



    public static Collection<Integer> oddOrEven(List<Integer> integers) {
    int mod = 0;
    for (Integer i : integers) {
    if((i & 1) == 1) mod=mod^1;
    }
    Set<Integer> result = new HashSet<>();
    for (Integer i : integers){
    if (((i & 1) ^ mod)==0)
    result.add(i);

    }
    return result; //Converting to set because we want distinct results.
    // If the order is important we can use treeset or convert to list
    }


    You can do some testing against the other Stream based solutions. The solution using standard java construct without the extra overload will be the same speed or faster in most cases. For example using map is nice but with bigger list with lots of repeating numbers at some point the amount of collisions can make it many times slower than the other ways. The complexity of all algorithms is linear but the amount of work in one iteration can vary with the different stream solutions (as well as the old school approach) and if one doesn't know what is the loss there maybe sticking to the well known and easy to predict scenario is better.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 15 '18 at 15:23

























    answered Nov 14 '18 at 15:29









    Veselin DavidovVeselin Davidov

    5,8751617




    5,8751617













    • The fact that you are getting better than linear scaling is an indicator that your benchmark is flawed. Further, you are ignoring the distinct() aspect of the stream solution, so the results are not comparable anyway.

      – Holger
      Nov 14 '18 at 19:11











    • Actually there are many benchmarks showing such results in similar situations. I am not saying that streams shouldn't be used but different solutions of the same problem have pros and cons. And many people go for the hype of streams without understanding/thinking about the cons. If your app is not built around streams with the extra conversions you rarely win something else than a modern looking code. And in this case we don't even benefit from good stuff from streams like lazyness. It was simple benchmark probably not 100% correct but I wanted to show a point

      – Veselin Davidov
      Nov 14 '18 at 21:58













    • It does not even qualify to be called “benchmark”. It starts with the fact that did not document the measuring method at all. You could have made up these numbers as well. Combining this with the fact that you are comparing code doing entirely different things (the missing distinct) and that the result numbers are obviously irregular, hence, entirely meaningless, makes this answer worthless. It’s a pity, as the code examples are not bad.

      – Holger
      Nov 15 '18 at 8:03











    • I just want to give the readers another point of view. If they want they can do their own benchmarks or read some in the internet. If they like the stream solution better or find it more readable - great. I can give my testing code but it will overload the response. For example here is a nice blog that covers such issues blog.jooq.org/2015/12/08/… there are many public benchmarks comparing List->stream->List to standard java for construct

      – Veselin Davidov
      Nov 15 '18 at 8:38











    • I have no problems with your point of view. You already stated it at the beginning of the answer. But I would remove these numbers if I were you. They are not necessary anyway.

      – Holger
      Nov 15 '18 at 15:09



















    • The fact that you are getting better than linear scaling is an indicator that your benchmark is flawed. Further, you are ignoring the distinct() aspect of the stream solution, so the results are not comparable anyway.

      – Holger
      Nov 14 '18 at 19:11











    • Actually there are many benchmarks showing such results in similar situations. I am not saying that streams shouldn't be used but different solutions of the same problem have pros and cons. And many people go for the hype of streams without understanding/thinking about the cons. If your app is not built around streams with the extra conversions you rarely win something else than a modern looking code. And in this case we don't even benefit from good stuff from streams like lazyness. It was simple benchmark probably not 100% correct but I wanted to show a point

      – Veselin Davidov
      Nov 14 '18 at 21:58













    • It does not even qualify to be called “benchmark”. It starts with the fact that did not document the measuring method at all. You could have made up these numbers as well. Combining this with the fact that you are comparing code doing entirely different things (the missing distinct) and that the result numbers are obviously irregular, hence, entirely meaningless, makes this answer worthless. It’s a pity, as the code examples are not bad.

      – Holger
      Nov 15 '18 at 8:03











    • I just want to give the readers another point of view. If they want they can do their own benchmarks or read some in the internet. If they like the stream solution better or find it more readable - great. I can give my testing code but it will overload the response. For example here is a nice blog that covers such issues blog.jooq.org/2015/12/08/… there are many public benchmarks comparing List->stream->List to standard java for construct

      – Veselin Davidov
      Nov 15 '18 at 8:38











    • I have no problems with your point of view. You already stated it at the beginning of the answer. But I would remove these numbers if I were you. They are not necessary anyway.

      – Holger
      Nov 15 '18 at 15:09

















    The fact that you are getting better than linear scaling is an indicator that your benchmark is flawed. Further, you are ignoring the distinct() aspect of the stream solution, so the results are not comparable anyway.

    – Holger
    Nov 14 '18 at 19:11





    The fact that you are getting better than linear scaling is an indicator that your benchmark is flawed. Further, you are ignoring the distinct() aspect of the stream solution, so the results are not comparable anyway.

    – Holger
    Nov 14 '18 at 19:11













    Actually there are many benchmarks showing such results in similar situations. I am not saying that streams shouldn't be used but different solutions of the same problem have pros and cons. And many people go for the hype of streams without understanding/thinking about the cons. If your app is not built around streams with the extra conversions you rarely win something else than a modern looking code. And in this case we don't even benefit from good stuff from streams like lazyness. It was simple benchmark probably not 100% correct but I wanted to show a point

    – Veselin Davidov
    Nov 14 '18 at 21:58







    Actually there are many benchmarks showing such results in similar situations. I am not saying that streams shouldn't be used but different solutions of the same problem have pros and cons. And many people go for the hype of streams without understanding/thinking about the cons. If your app is not built around streams with the extra conversions you rarely win something else than a modern looking code. And in this case we don't even benefit from good stuff from streams like lazyness. It was simple benchmark probably not 100% correct but I wanted to show a point

    – Veselin Davidov
    Nov 14 '18 at 21:58















    It does not even qualify to be called “benchmark”. It starts with the fact that did not document the measuring method at all. You could have made up these numbers as well. Combining this with the fact that you are comparing code doing entirely different things (the missing distinct) and that the result numbers are obviously irregular, hence, entirely meaningless, makes this answer worthless. It’s a pity, as the code examples are not bad.

    – Holger
    Nov 15 '18 at 8:03





    It does not even qualify to be called “benchmark”. It starts with the fact that did not document the measuring method at all. You could have made up these numbers as well. Combining this with the fact that you are comparing code doing entirely different things (the missing distinct) and that the result numbers are obviously irregular, hence, entirely meaningless, makes this answer worthless. It’s a pity, as the code examples are not bad.

    – Holger
    Nov 15 '18 at 8:03













    I just want to give the readers another point of view. If they want they can do their own benchmarks or read some in the internet. If they like the stream solution better or find it more readable - great. I can give my testing code but it will overload the response. For example here is a nice blog that covers such issues blog.jooq.org/2015/12/08/… there are many public benchmarks comparing List->stream->List to standard java for construct

    – Veselin Davidov
    Nov 15 '18 at 8:38





    I just want to give the readers another point of view. If they want they can do their own benchmarks or read some in the internet. If they like the stream solution better or find it more readable - great. I can give my testing code but it will overload the response. For example here is a nice blog that covers such issues blog.jooq.org/2015/12/08/… there are many public benchmarks comparing List->stream->List to standard java for construct

    – Veselin Davidov
    Nov 15 '18 at 8:38













    I have no problems with your point of view. You already stated it at the beginning of the answer. But I would remove these numbers if I were you. They are not necessary anyway.

    – Holger
    Nov 15 '18 at 15:09





    I have no problems with your point of view. You already stated it at the beginning of the answer. But I would remove these numbers if I were you. They are not necessary anyway.

    – Holger
    Nov 15 '18 at 15:09











    0














    public static List<Integer> oddOrEven(List<Integer> integers) {
    Function<Integer, Integer> fun = i -> i%2;
    Map<Integer, List<Integer>> map = integers.stream().collect(Collectors.groupingBy(fun));
    return map.get(1).size()%2 == 0? map.get(0): map.get(1);
    }





    share|improve this answer




























      0














      public static List<Integer> oddOrEven(List<Integer> integers) {
      Function<Integer, Integer> fun = i -> i%2;
      Map<Integer, List<Integer>> map = integers.stream().collect(Collectors.groupingBy(fun));
      return map.get(1).size()%2 == 0? map.get(0): map.get(1);
      }





      share|improve this answer


























        0












        0








        0







        public static List<Integer> oddOrEven(List<Integer> integers) {
        Function<Integer, Integer> fun = i -> i%2;
        Map<Integer, List<Integer>> map = integers.stream().collect(Collectors.groupingBy(fun));
        return map.get(1).size()%2 == 0? map.get(0): map.get(1);
        }





        share|improve this answer













        public static List<Integer> oddOrEven(List<Integer> integers) {
        Function<Integer, Integer> fun = i -> i%2;
        Map<Integer, List<Integer>> map = integers.stream().collect(Collectors.groupingBy(fun));
        return map.get(1).size()%2 == 0? map.get(0): map.get(1);
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 14 '18 at 15:19









        EritreanEritrean

        3,4001914




        3,4001914






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53302605%2freturn-listinteger-from-method-in-java-8%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

            Bressuire

            Vorschmack

            Quarantine