Return List from Method in Java 8?
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
add a comment |
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
7
Questions about working code belong on Code Review.
– Michael
Nov 14 '18 at 14:36
I was interested inIntStream
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 usesum()
. Further,if (sum % 2 != 0)
is obsolete, as at this place, the condition must betrue
. When you remove it, you can remove that unreachablereturn null;
too. Besides that, you are usingmapToInt
, hence you are usingIntStream
.
– Holger
Nov 14 '18 at 19:02
add a comment |
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
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
java java-8 java-stream
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 inIntStream
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 usesum()
. Further,if (sum % 2 != 0)
is obsolete, as at this place, the condition must betrue
. When you remove it, you can remove that unreachablereturn null;
too. Besides that, you are usingmapToInt
, hence you are usingIntStream
.
– Holger
Nov 14 '18 at 19:02
add a comment |
7
Questions about working code belong on Code Review.
– Michael
Nov 14 '18 at 14:36
I was interested inIntStream
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 usesum()
. Further,if (sum % 2 != 0)
is obsolete, as at this place, the condition must betrue
. When you remove it, you can remove that unreachablereturn null;
too. Besides that, you are usingmapToInt
, hence you are usingIntStream
.
– 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
add a comment |
4 Answers
4
active
oldest
votes
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());
}
@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 notreturn 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
add a comment |
long sum = integers.stream().reduce(0, (u, v) -> u + v);
return integers.stream().filter(x -> (x % 2)==(sum % 2)).distinct().collect(Collectors.toList());
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. TryoddOrEven(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
add a comment |
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.
The fact that you are getting better than linear scaling is an indicator that your benchmark is flawed. Further, you are ignoring thedistinct()
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
|
show 1 more comment
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);
}
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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());
}
@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 notreturn 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
add a comment |
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());
}
@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 notreturn 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
add a comment |
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());
}
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());
}
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 notreturn 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
add a comment |
@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 notreturn 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
add a comment |
long sum = integers.stream().reduce(0, (u, v) -> u + v);
return integers.stream().filter(x -> (x % 2)==(sum % 2)).distinct().collect(Collectors.toList());
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. TryoddOrEven(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
add a comment |
long sum = integers.stream().reduce(0, (u, v) -> u + v);
return integers.stream().filter(x -> (x % 2)==(sum % 2)).distinct().collect(Collectors.toList());
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. TryoddOrEven(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
add a comment |
long sum = integers.stream().reduce(0, (u, v) -> u + v);
return integers.stream().filter(x -> (x % 2)==(sum % 2)).distinct().collect(Collectors.toList());
long sum = integers.stream().reduce(0, (u, v) -> u + v);
return integers.stream().filter(x -> (x % 2)==(sum % 2)).distinct().collect(Collectors.toList());
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. TryoddOrEven(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
add a comment |
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. TryoddOrEven(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
add a comment |
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.
The fact that you are getting better than linear scaling is an indicator that your benchmark is flawed. Further, you are ignoring thedistinct()
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
|
show 1 more comment
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.
The fact that you are getting better than linear scaling is an indicator that your benchmark is flawed. Further, you are ignoring thedistinct()
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
|
show 1 more comment
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.
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.
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 thedistinct()
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
|
show 1 more comment
The fact that you are getting better than linear scaling is an indicator that your benchmark is flawed. Further, you are ignoring thedistinct()
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
|
show 1 more comment
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);
}
add a comment |
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);
}
add a comment |
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);
}
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);
}
answered Nov 14 '18 at 15:19
EritreanEritrean
3,4001914
3,4001914
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 usesum()
. Further,if (sum % 2 != 0)
is obsolete, as at this place, the condition must betrue
. When you remove it, you can remove that unreachablereturn null;
too. Besides that, you are usingmapToInt
, hence you are usingIntStream
.– Holger
Nov 14 '18 at 19:02