Identity for BinaryOperator
Clash Royale CLAN TAG#URR8PPP
up vote
7
down vote
favorite
I see in Java8 in UnaryOperator Interface following piece of code which does nothing on parameter and returns same value.
static <T> UnaryOperator<T> identity()
return t -> t;
Is there anything for BinaryOperator which accepts two parameters of samekind and returns one value
static <T> BinaryOperator<T> identity()
return (t,t) -> t;
why I am asking this question is for below requirement,
List<String> list = Arrays.asList("Abcd","Abcd");
Map<String,Integer> map = list.stream().collect(Collectors.toMap(str->str,
str->(Integer)str.length(),(t1,t2)->t1));
System.out.println(map.size());
in above code I don't want to do anything for two values of same key, I just wanted return one value, because in my case for sure values will be same.
As am not using t2 value Sonar throwing error, So I am finding out is there any thing like UnaryOperator.identity() for BinaryOpertor also in java8
java lambda java-8 functional-programming
add a comment |Â
up vote
7
down vote
favorite
I see in Java8 in UnaryOperator Interface following piece of code which does nothing on parameter and returns same value.
static <T> UnaryOperator<T> identity()
return t -> t;
Is there anything for BinaryOperator which accepts two parameters of samekind and returns one value
static <T> BinaryOperator<T> identity()
return (t,t) -> t;
why I am asking this question is for below requirement,
List<String> list = Arrays.asList("Abcd","Abcd");
Map<String,Integer> map = list.stream().collect(Collectors.toMap(str->str,
str->(Integer)str.length(),(t1,t2)->t1));
System.out.println(map.size());
in above code I don't want to do anything for two values of same key, I just wanted return one value, because in my case for sure values will be same.
As am not using t2 value Sonar throwing error, So I am finding out is there any thing like UnaryOperator.identity() for BinaryOpertor also in java8
java lambda java-8 functional-programming
5
An identity, by definition, returns its input without any modification. If the input is two values, its output must also be two values. What you want is not an identity, but some sort of distinct or group operation before processing the values. (I don't speak modern Java, but in C# that would literally be.Distinct
and.GroupBy
.)
– Jeroen Mostert
yesterday
2
The problem is not in your code, but in the Sonar alert instead. Just turn it off.
– Federico Peralta Schaffner
yesterday
1
Some functional languages only have unary functions. In these languages, a function accepting a tuple is equivalent to a binary function in Java. Identity for such a function is easy when you think of it in this way: if a tuple is input, it must also be the output.
– user633183
yesterday
add a comment |Â
up vote
7
down vote
favorite
up vote
7
down vote
favorite
I see in Java8 in UnaryOperator Interface following piece of code which does nothing on parameter and returns same value.
static <T> UnaryOperator<T> identity()
return t -> t;
Is there anything for BinaryOperator which accepts two parameters of samekind and returns one value
static <T> BinaryOperator<T> identity()
return (t,t) -> t;
why I am asking this question is for below requirement,
List<String> list = Arrays.asList("Abcd","Abcd");
Map<String,Integer> map = list.stream().collect(Collectors.toMap(str->str,
str->(Integer)str.length(),(t1,t2)->t1));
System.out.println(map.size());
in above code I don't want to do anything for two values of same key, I just wanted return one value, because in my case for sure values will be same.
As am not using t2 value Sonar throwing error, So I am finding out is there any thing like UnaryOperator.identity() for BinaryOpertor also in java8
java lambda java-8 functional-programming
I see in Java8 in UnaryOperator Interface following piece of code which does nothing on parameter and returns same value.
static <T> UnaryOperator<T> identity()
return t -> t;
Is there anything for BinaryOperator which accepts two parameters of samekind and returns one value
static <T> BinaryOperator<T> identity()
return (t,t) -> t;
why I am asking this question is for below requirement,
List<String> list = Arrays.asList("Abcd","Abcd");
Map<String,Integer> map = list.stream().collect(Collectors.toMap(str->str,
str->(Integer)str.length(),(t1,t2)->t1));
System.out.println(map.size());
in above code I don't want to do anything for two values of same key, I just wanted return one value, because in my case for sure values will be same.
As am not using t2 value Sonar throwing error, So I am finding out is there any thing like UnaryOperator.identity() for BinaryOpertor also in java8
java lambda java-8 functional-programming
java lambda java-8 functional-programming
edited 23 hours ago


nullpointer
30.4k1054127
30.4k1054127
asked yesterday
Karunakar Reddy L
666
666
5
An identity, by definition, returns its input without any modification. If the input is two values, its output must also be two values. What you want is not an identity, but some sort of distinct or group operation before processing the values. (I don't speak modern Java, but in C# that would literally be.Distinct
and.GroupBy
.)
– Jeroen Mostert
yesterday
2
The problem is not in your code, but in the Sonar alert instead. Just turn it off.
– Federico Peralta Schaffner
yesterday
1
Some functional languages only have unary functions. In these languages, a function accepting a tuple is equivalent to a binary function in Java. Identity for such a function is easy when you think of it in this way: if a tuple is input, it must also be the output.
– user633183
yesterday
add a comment |Â
5
An identity, by definition, returns its input without any modification. If the input is two values, its output must also be two values. What you want is not an identity, but some sort of distinct or group operation before processing the values. (I don't speak modern Java, but in C# that would literally be.Distinct
and.GroupBy
.)
– Jeroen Mostert
yesterday
2
The problem is not in your code, but in the Sonar alert instead. Just turn it off.
– Federico Peralta Schaffner
yesterday
1
Some functional languages only have unary functions. In these languages, a function accepting a tuple is equivalent to a binary function in Java. Identity for such a function is easy when you think of it in this way: if a tuple is input, it must also be the output.
– user633183
yesterday
5
5
An identity, by definition, returns its input without any modification. If the input is two values, its output must also be two values. What you want is not an identity, but some sort of distinct or group operation before processing the values. (I don't speak modern Java, but in C# that would literally be
.Distinct
and .GroupBy
.)– Jeroen Mostert
yesterday
An identity, by definition, returns its input without any modification. If the input is two values, its output must also be two values. What you want is not an identity, but some sort of distinct or group operation before processing the values. (I don't speak modern Java, but in C# that would literally be
.Distinct
and .GroupBy
.)– Jeroen Mostert
yesterday
2
2
The problem is not in your code, but in the Sonar alert instead. Just turn it off.
– Federico Peralta Schaffner
yesterday
The problem is not in your code, but in the Sonar alert instead. Just turn it off.
– Federico Peralta Schaffner
yesterday
1
1
Some functional languages only have unary functions. In these languages, a function accepting a tuple is equivalent to a binary function in Java. Identity for such a function is easy when you think of it in this way: if a tuple is input, it must also be the output.
– user633183
yesterday
Some functional languages only have unary functions. In these languages, a function accepting a tuple is equivalent to a binary function in Java. Identity for such a function is easy when you think of it in this way: if a tuple is input, it must also be the output.
– user633183
yesterday
add a comment |Â
3 Answers
3
active
oldest
votes
up vote
6
down vote
Your question doesn't really make sense. If you were to paste your proposed BinaryOperator.identity
method into an IDE, you would immediately see that it would complain that the identifier t
is declared twice.
To fix this, we need a different identifier for each parameter:
return (t, u) -> t;
Now we can clearly see that this is not an identity function. It's a method which takes two arguments and returns the first one. Therefore the best name for this would be something like getFirst
.
To answer your question about whether there's anything like this in the JDK: no. Using an identity function is a common use case, so defining a method for that is useful. Arbitrarily returning the first argument of two is not a common use case, and it's not useful to have a method to do that.
Well, I agree to what you've stated here, except for the last part:Arbitrarily returning the first argument of two is not a common use case, and it's not useful to have a method to do that
. In fact it is quite useful, as OP is showing here. Another use case is when implementing collectors and you need to provide a combiner function that you know will never be used (because i.e. the stream is sequential). Besides,BinaryOperator
does providemaxBy(Comparator)
static method (and alsominBy
), so it's valid to wonder why there's no i.e.first
orsecond
methods...
– Federico Peralta Schaffner
22 hours ago
@FedericoPeraltaSchaffner "common" is kind of subjective. I've never needed that, and I work with the JDK on a daily basis. By contrast, I've neededFunction.identity
probably 100s of times. The JDK is supposed to be a collection of broadly useful tools. It's not designed to contain absolutely everything a developer might ever need. If you add agetFirst
, people will wonder wheregetSecond
is. If you add both of those forBinaryOperator
, why not add similar ones for the other 42 functional interfaces? Boom - you've now got ~100 basically useless methods cluttering the API.
– Michael
22 hours ago
I absolutely agree with you, I was playing the role of the devil's advocate a little bit... The problem with the question is not that there doesn't exist a method to choose the first or second element, but that Sonar is throwing an alert, when it shouldn't...
– Federico Peralta Schaffner
22 hours ago
add a comment |Â
up vote
5
down vote
Your code seemingly can be improved as
List<String> list = Arrays.asList("Abcd", "Abcd");
Map<String, Integer> map = list.stream()
.collect(Collectors.toMap(Function.identity(), String::length, (a, b) -> a));
System.out.println(map.size());
Or possibly for your use case I don't want to do anything for two values of same key, I just wanted return one value, you may just choose to randomly return any value in using an implementation as following:
private static <T> BinaryOperator<T> any()
return Math.random() < 0.5 ? ((x, y) -> x) : ((x, y) -> y);
and then in your code use it as
Map<String, Integer> map = list.stream()
.collect(Collectors.toMap(Function.identity(), String::length, any()));
Thanks to the suggestions from Holger, Eugene, and Federico, there are other efficient implementations of the any
method that can actually involve using :
private static <T> BinaryOperator<T> any()
// suggested by Holger
return ThreadLocalRandom.current().nextBoolean() ? ((x, y) -> x) : ((x, y) -> y);
// suggested by Eugene
long nt = System.nanoTime();
((nt >>> 32) ^ nt) > 0 ? ((x, y) -> x) : ((x, y) -> y);
that btw is a very interesting merger :)
– Eugene
yesterday
1
I guess you are right, it just looks weird to me.
– Eugene
yesterday
3
You know that your random implementation won't pick a random argument each time, but will choose one implementation when called, and then will return the same argument all times. btw I didn't downvote
– Federico Peralta Schaffner
yesterday
1
I remember I asked something about that here and Stuart Marks kindly answered... :D
– Federico Peralta Schaffner
23 hours ago
2
I’d useThreadLocalRandom.current().nextBoolean()
instead ofMath.random() < 0.5
. An alternative would be(a,b) -> assert Objects.equals(a, b); return a;
– Holger
20 hours ago
 |Â
show 16 more comments
up vote
4
down vote
T
means they have the same types, not the same values, that is not an identity per-se.
It just means that BinaryOperator
will be used for the same types, but providing an identity
for different values... this somehow sounds like foldLeft
or foldRight
or foldLeftIdentity/foldRightIdentity
, which java does not have.
what's your thought on the implementation ofany
for returning any value as in the merger?
– nullpointer
yesterday
1
@nullpointer :) that is all I can say. probablyMath.random
is too expensive here, I would go for something cheaper likelong nt = System.nanoTime(); ((nt >>> 32) ^ nt) > 0 ? ... : ...
but I've seen this somewhere else already :) (of course the cheapest and fastest random would have to be taken here)
– Eugene
23 hours ago
add a comment |Â
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
6
down vote
Your question doesn't really make sense. If you were to paste your proposed BinaryOperator.identity
method into an IDE, you would immediately see that it would complain that the identifier t
is declared twice.
To fix this, we need a different identifier for each parameter:
return (t, u) -> t;
Now we can clearly see that this is not an identity function. It's a method which takes two arguments and returns the first one. Therefore the best name for this would be something like getFirst
.
To answer your question about whether there's anything like this in the JDK: no. Using an identity function is a common use case, so defining a method for that is useful. Arbitrarily returning the first argument of two is not a common use case, and it's not useful to have a method to do that.
Well, I agree to what you've stated here, except for the last part:Arbitrarily returning the first argument of two is not a common use case, and it's not useful to have a method to do that
. In fact it is quite useful, as OP is showing here. Another use case is when implementing collectors and you need to provide a combiner function that you know will never be used (because i.e. the stream is sequential). Besides,BinaryOperator
does providemaxBy(Comparator)
static method (and alsominBy
), so it's valid to wonder why there's no i.e.first
orsecond
methods...
– Federico Peralta Schaffner
22 hours ago
@FedericoPeraltaSchaffner "common" is kind of subjective. I've never needed that, and I work with the JDK on a daily basis. By contrast, I've neededFunction.identity
probably 100s of times. The JDK is supposed to be a collection of broadly useful tools. It's not designed to contain absolutely everything a developer might ever need. If you add agetFirst
, people will wonder wheregetSecond
is. If you add both of those forBinaryOperator
, why not add similar ones for the other 42 functional interfaces? Boom - you've now got ~100 basically useless methods cluttering the API.
– Michael
22 hours ago
I absolutely agree with you, I was playing the role of the devil's advocate a little bit... The problem with the question is not that there doesn't exist a method to choose the first or second element, but that Sonar is throwing an alert, when it shouldn't...
– Federico Peralta Schaffner
22 hours ago
add a comment |Â
up vote
6
down vote
Your question doesn't really make sense. If you were to paste your proposed BinaryOperator.identity
method into an IDE, you would immediately see that it would complain that the identifier t
is declared twice.
To fix this, we need a different identifier for each parameter:
return (t, u) -> t;
Now we can clearly see that this is not an identity function. It's a method which takes two arguments and returns the first one. Therefore the best name for this would be something like getFirst
.
To answer your question about whether there's anything like this in the JDK: no. Using an identity function is a common use case, so defining a method for that is useful. Arbitrarily returning the first argument of two is not a common use case, and it's not useful to have a method to do that.
Well, I agree to what you've stated here, except for the last part:Arbitrarily returning the first argument of two is not a common use case, and it's not useful to have a method to do that
. In fact it is quite useful, as OP is showing here. Another use case is when implementing collectors and you need to provide a combiner function that you know will never be used (because i.e. the stream is sequential). Besides,BinaryOperator
does providemaxBy(Comparator)
static method (and alsominBy
), so it's valid to wonder why there's no i.e.first
orsecond
methods...
– Federico Peralta Schaffner
22 hours ago
@FedericoPeraltaSchaffner "common" is kind of subjective. I've never needed that, and I work with the JDK on a daily basis. By contrast, I've neededFunction.identity
probably 100s of times. The JDK is supposed to be a collection of broadly useful tools. It's not designed to contain absolutely everything a developer might ever need. If you add agetFirst
, people will wonder wheregetSecond
is. If you add both of those forBinaryOperator
, why not add similar ones for the other 42 functional interfaces? Boom - you've now got ~100 basically useless methods cluttering the API.
– Michael
22 hours ago
I absolutely agree with you, I was playing the role of the devil's advocate a little bit... The problem with the question is not that there doesn't exist a method to choose the first or second element, but that Sonar is throwing an alert, when it shouldn't...
– Federico Peralta Schaffner
22 hours ago
add a comment |Â
up vote
6
down vote
up vote
6
down vote
Your question doesn't really make sense. If you were to paste your proposed BinaryOperator.identity
method into an IDE, you would immediately see that it would complain that the identifier t
is declared twice.
To fix this, we need a different identifier for each parameter:
return (t, u) -> t;
Now we can clearly see that this is not an identity function. It's a method which takes two arguments and returns the first one. Therefore the best name for this would be something like getFirst
.
To answer your question about whether there's anything like this in the JDK: no. Using an identity function is a common use case, so defining a method for that is useful. Arbitrarily returning the first argument of two is not a common use case, and it's not useful to have a method to do that.
Your question doesn't really make sense. If you were to paste your proposed BinaryOperator.identity
method into an IDE, you would immediately see that it would complain that the identifier t
is declared twice.
To fix this, we need a different identifier for each parameter:
return (t, u) -> t;
Now we can clearly see that this is not an identity function. It's a method which takes two arguments and returns the first one. Therefore the best name for this would be something like getFirst
.
To answer your question about whether there's anything like this in the JDK: no. Using an identity function is a common use case, so defining a method for that is useful. Arbitrarily returning the first argument of two is not a common use case, and it's not useful to have a method to do that.
answered 23 hours ago
Michael
15.9k62964
15.9k62964
Well, I agree to what you've stated here, except for the last part:Arbitrarily returning the first argument of two is not a common use case, and it's not useful to have a method to do that
. In fact it is quite useful, as OP is showing here. Another use case is when implementing collectors and you need to provide a combiner function that you know will never be used (because i.e. the stream is sequential). Besides,BinaryOperator
does providemaxBy(Comparator)
static method (and alsominBy
), so it's valid to wonder why there's no i.e.first
orsecond
methods...
– Federico Peralta Schaffner
22 hours ago
@FedericoPeraltaSchaffner "common" is kind of subjective. I've never needed that, and I work with the JDK on a daily basis. By contrast, I've neededFunction.identity
probably 100s of times. The JDK is supposed to be a collection of broadly useful tools. It's not designed to contain absolutely everything a developer might ever need. If you add agetFirst
, people will wonder wheregetSecond
is. If you add both of those forBinaryOperator
, why not add similar ones for the other 42 functional interfaces? Boom - you've now got ~100 basically useless methods cluttering the API.
– Michael
22 hours ago
I absolutely agree with you, I was playing the role of the devil's advocate a little bit... The problem with the question is not that there doesn't exist a method to choose the first or second element, but that Sonar is throwing an alert, when it shouldn't...
– Federico Peralta Schaffner
22 hours ago
add a comment |Â
Well, I agree to what you've stated here, except for the last part:Arbitrarily returning the first argument of two is not a common use case, and it's not useful to have a method to do that
. In fact it is quite useful, as OP is showing here. Another use case is when implementing collectors and you need to provide a combiner function that you know will never be used (because i.e. the stream is sequential). Besides,BinaryOperator
does providemaxBy(Comparator)
static method (and alsominBy
), so it's valid to wonder why there's no i.e.first
orsecond
methods...
– Federico Peralta Schaffner
22 hours ago
@FedericoPeraltaSchaffner "common" is kind of subjective. I've never needed that, and I work with the JDK on a daily basis. By contrast, I've neededFunction.identity
probably 100s of times. The JDK is supposed to be a collection of broadly useful tools. It's not designed to contain absolutely everything a developer might ever need. If you add agetFirst
, people will wonder wheregetSecond
is. If you add both of those forBinaryOperator
, why not add similar ones for the other 42 functional interfaces? Boom - you've now got ~100 basically useless methods cluttering the API.
– Michael
22 hours ago
I absolutely agree with you, I was playing the role of the devil's advocate a little bit... The problem with the question is not that there doesn't exist a method to choose the first or second element, but that Sonar is throwing an alert, when it shouldn't...
– Federico Peralta Schaffner
22 hours ago
Well, I agree to what you've stated here, except for the last part:
Arbitrarily returning the first argument of two is not a common use case, and it's not useful to have a method to do that
. In fact it is quite useful, as OP is showing here. Another use case is when implementing collectors and you need to provide a combiner function that you know will never be used (because i.e. the stream is sequential). Besides, BinaryOperator
does provide maxBy(Comparator)
static method (and also minBy
), so it's valid to wonder why there's no i.e. first
or second
methods...– Federico Peralta Schaffner
22 hours ago
Well, I agree to what you've stated here, except for the last part:
Arbitrarily returning the first argument of two is not a common use case, and it's not useful to have a method to do that
. In fact it is quite useful, as OP is showing here. Another use case is when implementing collectors and you need to provide a combiner function that you know will never be used (because i.e. the stream is sequential). Besides, BinaryOperator
does provide maxBy(Comparator)
static method (and also minBy
), so it's valid to wonder why there's no i.e. first
or second
methods...– Federico Peralta Schaffner
22 hours ago
@FedericoPeraltaSchaffner "common" is kind of subjective. I've never needed that, and I work with the JDK on a daily basis. By contrast, I've needed
Function.identity
probably 100s of times. The JDK is supposed to be a collection of broadly useful tools. It's not designed to contain absolutely everything a developer might ever need. If you add a getFirst
, people will wonder where getSecond
is. If you add both of those for BinaryOperator
, why not add similar ones for the other 42 functional interfaces? Boom - you've now got ~100 basically useless methods cluttering the API.– Michael
22 hours ago
@FedericoPeraltaSchaffner "common" is kind of subjective. I've never needed that, and I work with the JDK on a daily basis. By contrast, I've needed
Function.identity
probably 100s of times. The JDK is supposed to be a collection of broadly useful tools. It's not designed to contain absolutely everything a developer might ever need. If you add a getFirst
, people will wonder where getSecond
is. If you add both of those for BinaryOperator
, why not add similar ones for the other 42 functional interfaces? Boom - you've now got ~100 basically useless methods cluttering the API.– Michael
22 hours ago
I absolutely agree with you, I was playing the role of the devil's advocate a little bit... The problem with the question is not that there doesn't exist a method to choose the first or second element, but that Sonar is throwing an alert, when it shouldn't...
– Federico Peralta Schaffner
22 hours ago
I absolutely agree with you, I was playing the role of the devil's advocate a little bit... The problem with the question is not that there doesn't exist a method to choose the first or second element, but that Sonar is throwing an alert, when it shouldn't...
– Federico Peralta Schaffner
22 hours ago
add a comment |Â
up vote
5
down vote
Your code seemingly can be improved as
List<String> list = Arrays.asList("Abcd", "Abcd");
Map<String, Integer> map = list.stream()
.collect(Collectors.toMap(Function.identity(), String::length, (a, b) -> a));
System.out.println(map.size());
Or possibly for your use case I don't want to do anything for two values of same key, I just wanted return one value, you may just choose to randomly return any value in using an implementation as following:
private static <T> BinaryOperator<T> any()
return Math.random() < 0.5 ? ((x, y) -> x) : ((x, y) -> y);
and then in your code use it as
Map<String, Integer> map = list.stream()
.collect(Collectors.toMap(Function.identity(), String::length, any()));
Thanks to the suggestions from Holger, Eugene, and Federico, there are other efficient implementations of the any
method that can actually involve using :
private static <T> BinaryOperator<T> any()
// suggested by Holger
return ThreadLocalRandom.current().nextBoolean() ? ((x, y) -> x) : ((x, y) -> y);
// suggested by Eugene
long nt = System.nanoTime();
((nt >>> 32) ^ nt) > 0 ? ((x, y) -> x) : ((x, y) -> y);
that btw is a very interesting merger :)
– Eugene
yesterday
1
I guess you are right, it just looks weird to me.
– Eugene
yesterday
3
You know that your random implementation won't pick a random argument each time, but will choose one implementation when called, and then will return the same argument all times. btw I didn't downvote
– Federico Peralta Schaffner
yesterday
1
I remember I asked something about that here and Stuart Marks kindly answered... :D
– Federico Peralta Schaffner
23 hours ago
2
I’d useThreadLocalRandom.current().nextBoolean()
instead ofMath.random() < 0.5
. An alternative would be(a,b) -> assert Objects.equals(a, b); return a;
– Holger
20 hours ago
 |Â
show 16 more comments
up vote
5
down vote
Your code seemingly can be improved as
List<String> list = Arrays.asList("Abcd", "Abcd");
Map<String, Integer> map = list.stream()
.collect(Collectors.toMap(Function.identity(), String::length, (a, b) -> a));
System.out.println(map.size());
Or possibly for your use case I don't want to do anything for two values of same key, I just wanted return one value, you may just choose to randomly return any value in using an implementation as following:
private static <T> BinaryOperator<T> any()
return Math.random() < 0.5 ? ((x, y) -> x) : ((x, y) -> y);
and then in your code use it as
Map<String, Integer> map = list.stream()
.collect(Collectors.toMap(Function.identity(), String::length, any()));
Thanks to the suggestions from Holger, Eugene, and Federico, there are other efficient implementations of the any
method that can actually involve using :
private static <T> BinaryOperator<T> any()
// suggested by Holger
return ThreadLocalRandom.current().nextBoolean() ? ((x, y) -> x) : ((x, y) -> y);
// suggested by Eugene
long nt = System.nanoTime();
((nt >>> 32) ^ nt) > 0 ? ((x, y) -> x) : ((x, y) -> y);
that btw is a very interesting merger :)
– Eugene
yesterday
1
I guess you are right, it just looks weird to me.
– Eugene
yesterday
3
You know that your random implementation won't pick a random argument each time, but will choose one implementation when called, and then will return the same argument all times. btw I didn't downvote
– Federico Peralta Schaffner
yesterday
1
I remember I asked something about that here and Stuart Marks kindly answered... :D
– Federico Peralta Schaffner
23 hours ago
2
I’d useThreadLocalRandom.current().nextBoolean()
instead ofMath.random() < 0.5
. An alternative would be(a,b) -> assert Objects.equals(a, b); return a;
– Holger
20 hours ago
 |Â
show 16 more comments
up vote
5
down vote
up vote
5
down vote
Your code seemingly can be improved as
List<String> list = Arrays.asList("Abcd", "Abcd");
Map<String, Integer> map = list.stream()
.collect(Collectors.toMap(Function.identity(), String::length, (a, b) -> a));
System.out.println(map.size());
Or possibly for your use case I don't want to do anything for two values of same key, I just wanted return one value, you may just choose to randomly return any value in using an implementation as following:
private static <T> BinaryOperator<T> any()
return Math.random() < 0.5 ? ((x, y) -> x) : ((x, y) -> y);
and then in your code use it as
Map<String, Integer> map = list.stream()
.collect(Collectors.toMap(Function.identity(), String::length, any()));
Thanks to the suggestions from Holger, Eugene, and Federico, there are other efficient implementations of the any
method that can actually involve using :
private static <T> BinaryOperator<T> any()
// suggested by Holger
return ThreadLocalRandom.current().nextBoolean() ? ((x, y) -> x) : ((x, y) -> y);
// suggested by Eugene
long nt = System.nanoTime();
((nt >>> 32) ^ nt) > 0 ? ((x, y) -> x) : ((x, y) -> y);
Your code seemingly can be improved as
List<String> list = Arrays.asList("Abcd", "Abcd");
Map<String, Integer> map = list.stream()
.collect(Collectors.toMap(Function.identity(), String::length, (a, b) -> a));
System.out.println(map.size());
Or possibly for your use case I don't want to do anything for two values of same key, I just wanted return one value, you may just choose to randomly return any value in using an implementation as following:
private static <T> BinaryOperator<T> any()
return Math.random() < 0.5 ? ((x, y) -> x) : ((x, y) -> y);
and then in your code use it as
Map<String, Integer> map = list.stream()
.collect(Collectors.toMap(Function.identity(), String::length, any()));
Thanks to the suggestions from Holger, Eugene, and Federico, there are other efficient implementations of the any
method that can actually involve using :
private static <T> BinaryOperator<T> any()
// suggested by Holger
return ThreadLocalRandom.current().nextBoolean() ? ((x, y) -> x) : ((x, y) -> y);
// suggested by Eugene
long nt = System.nanoTime();
((nt >>> 32) ^ nt) > 0 ? ((x, y) -> x) : ((x, y) -> y);
edited 6 hours ago
answered yesterday


nullpointer
30.4k1054127
30.4k1054127
that btw is a very interesting merger :)
– Eugene
yesterday
1
I guess you are right, it just looks weird to me.
– Eugene
yesterday
3
You know that your random implementation won't pick a random argument each time, but will choose one implementation when called, and then will return the same argument all times. btw I didn't downvote
– Federico Peralta Schaffner
yesterday
1
I remember I asked something about that here and Stuart Marks kindly answered... :D
– Federico Peralta Schaffner
23 hours ago
2
I’d useThreadLocalRandom.current().nextBoolean()
instead ofMath.random() < 0.5
. An alternative would be(a,b) -> assert Objects.equals(a, b); return a;
– Holger
20 hours ago
 |Â
show 16 more comments
that btw is a very interesting merger :)
– Eugene
yesterday
1
I guess you are right, it just looks weird to me.
– Eugene
yesterday
3
You know that your random implementation won't pick a random argument each time, but will choose one implementation when called, and then will return the same argument all times. btw I didn't downvote
– Federico Peralta Schaffner
yesterday
1
I remember I asked something about that here and Stuart Marks kindly answered... :D
– Federico Peralta Schaffner
23 hours ago
2
I’d useThreadLocalRandom.current().nextBoolean()
instead ofMath.random() < 0.5
. An alternative would be(a,b) -> assert Objects.equals(a, b); return a;
– Holger
20 hours ago
that btw is a very interesting merger :)
– Eugene
yesterday
that btw is a very interesting merger :)
– Eugene
yesterday
1
1
I guess you are right, it just looks weird to me.
– Eugene
yesterday
I guess you are right, it just looks weird to me.
– Eugene
yesterday
3
3
You know that your random implementation won't pick a random argument each time, but will choose one implementation when called, and then will return the same argument all times. btw I didn't downvote
– Federico Peralta Schaffner
yesterday
You know that your random implementation won't pick a random argument each time, but will choose one implementation when called, and then will return the same argument all times. btw I didn't downvote
– Federico Peralta Schaffner
yesterday
1
1
I remember I asked something about that here and Stuart Marks kindly answered... :D
– Federico Peralta Schaffner
23 hours ago
I remember I asked something about that here and Stuart Marks kindly answered... :D
– Federico Peralta Schaffner
23 hours ago
2
2
I’d use
ThreadLocalRandom.current().nextBoolean()
instead of Math.random() < 0.5
. An alternative would be (a,b) -> assert Objects.equals(a, b); return a;
– Holger
20 hours ago
I’d use
ThreadLocalRandom.current().nextBoolean()
instead of Math.random() < 0.5
. An alternative would be (a,b) -> assert Objects.equals(a, b); return a;
– Holger
20 hours ago
 |Â
show 16 more comments
up vote
4
down vote
T
means they have the same types, not the same values, that is not an identity per-se.
It just means that BinaryOperator
will be used for the same types, but providing an identity
for different values... this somehow sounds like foldLeft
or foldRight
or foldLeftIdentity/foldRightIdentity
, which java does not have.
what's your thought on the implementation ofany
for returning any value as in the merger?
– nullpointer
yesterday
1
@nullpointer :) that is all I can say. probablyMath.random
is too expensive here, I would go for something cheaper likelong nt = System.nanoTime(); ((nt >>> 32) ^ nt) > 0 ? ... : ...
but I've seen this somewhere else already :) (of course the cheapest and fastest random would have to be taken here)
– Eugene
23 hours ago
add a comment |Â
up vote
4
down vote
T
means they have the same types, not the same values, that is not an identity per-se.
It just means that BinaryOperator
will be used for the same types, but providing an identity
for different values... this somehow sounds like foldLeft
or foldRight
or foldLeftIdentity/foldRightIdentity
, which java does not have.
what's your thought on the implementation ofany
for returning any value as in the merger?
– nullpointer
yesterday
1
@nullpointer :) that is all I can say. probablyMath.random
is too expensive here, I would go for something cheaper likelong nt = System.nanoTime(); ((nt >>> 32) ^ nt) > 0 ? ... : ...
but I've seen this somewhere else already :) (of course the cheapest and fastest random would have to be taken here)
– Eugene
23 hours ago
add a comment |Â
up vote
4
down vote
up vote
4
down vote
T
means they have the same types, not the same values, that is not an identity per-se.
It just means that BinaryOperator
will be used for the same types, but providing an identity
for different values... this somehow sounds like foldLeft
or foldRight
or foldLeftIdentity/foldRightIdentity
, which java does not have.
T
means they have the same types, not the same values, that is not an identity per-se.
It just means that BinaryOperator
will be used for the same types, but providing an identity
for different values... this somehow sounds like foldLeft
or foldRight
or foldLeftIdentity/foldRightIdentity
, which java does not have.
edited yesterday
answered yesterday


Eugene
59.8k980139
59.8k980139
what's your thought on the implementation ofany
for returning any value as in the merger?
– nullpointer
yesterday
1
@nullpointer :) that is all I can say. probablyMath.random
is too expensive here, I would go for something cheaper likelong nt = System.nanoTime(); ((nt >>> 32) ^ nt) > 0 ? ... : ...
but I've seen this somewhere else already :) (of course the cheapest and fastest random would have to be taken here)
– Eugene
23 hours ago
add a comment |Â
what's your thought on the implementation ofany
for returning any value as in the merger?
– nullpointer
yesterday
1
@nullpointer :) that is all I can say. probablyMath.random
is too expensive here, I would go for something cheaper likelong nt = System.nanoTime(); ((nt >>> 32) ^ nt) > 0 ? ... : ...
but I've seen this somewhere else already :) (of course the cheapest and fastest random would have to be taken here)
– Eugene
23 hours ago
what's your thought on the implementation of
any
for returning any value as in the merger?– nullpointer
yesterday
what's your thought on the implementation of
any
for returning any value as in the merger?– nullpointer
yesterday
1
1
@nullpointer :) that is all I can say. probably
Math.random
is too expensive here, I would go for something cheaper like long nt = System.nanoTime(); ((nt >>> 32) ^ nt) > 0 ? ... : ...
but I've seen this somewhere else already :) (of course the cheapest and fastest random would have to be taken here)– Eugene
23 hours ago
@nullpointer :) that is all I can say. probably
Math.random
is too expensive here, I would go for something cheaper like long nt = System.nanoTime(); ((nt >>> 32) ^ nt) > 0 ? ... : ...
but I've seen this somewhere else already :) (of course the cheapest and fastest random would have to be taken here)– Eugene
23 hours ago
add a comment |Â
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
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52296075%2fidentity-for-binaryoperator%23new-answer', 'question_page');
);
Post as a guest
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
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
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
5
An identity, by definition, returns its input without any modification. If the input is two values, its output must also be two values. What you want is not an identity, but some sort of distinct or group operation before processing the values. (I don't speak modern Java, but in C# that would literally be
.Distinct
and.GroupBy
.)– Jeroen Mostert
yesterday
2
The problem is not in your code, but in the Sonar alert instead. Just turn it off.
– Federico Peralta Schaffner
yesterday
1
Some functional languages only have unary functions. In these languages, a function accepting a tuple is equivalent to a binary function in Java. Identity for such a function is easy when you think of it in this way: if a tuple is input, it must also be the output.
– user633183
yesterday