I am looking for elegant way to overcome while comparing any Wrapper object to Stream.
Github working link: https://github.com/vishwaratna/Unlikely-argument-type-for-equals-Stream-String-/commit/d803f77c923e81fe7531ecb467561ac785d7aca5
Question in reference: Filtering keys from map to list attribute in java-8
Recently i faced it while comparing member of List
to a key of a Map
.
I know there are other ways to compare without doing what i am doing but i am looking for in general casting, if it is available.
List<student> stulist = Arrays.asList(new student("1", "vishwa",null),
new student("3", "Ravi",null),
new student("2", "Ram",null));
Map<String,String> map = new HashMap() {{
put("1","20");
put("2","30");
}};
System.out.println( stulist.stream()
.filter(s->s.getId()
.equals(map.entrySet()
.stream()
.map(Map.Entry::getKey)))
.count());
My code is compiling properly but the output is coming as "0", whereas i expect output as 2.
I am sure it is due to type mismatch, but why the compiler is not throwing an error??
Warning that i am getting: Unlikely argument type for equals(): Stream<String> seems to be unrelated to String
Basically, to understand why compiler doesn't give an error, you should look into String.equals() method implementation
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
Now, let's go back to this line:
s.getId().equals(map.entrySet().stream().map(Map.Entry::getKey))
As we know s.getId()
is of type String
and map.entrySet().stream().map(Map.Entry::getKey)
is of type Stream<String>
.
Since Stream<String>
is not instanceof String
, it's clear that String.equals()
method will return false
each time s.getId()
is compared with map.entrySet().stream().map(Map.Entry::getKey)
(hence, 0 count at the end). And compiler doesn't issue error, because nothing illegal actually happened (taking into account implementation of String.equals()
).
Also, probably, cleanest way to find count
without warnings would be:
System.out.println(
stulist.stream()
.map(Student::getId)
.filter(map::containsKey)
.count());
First, what you might be intending to there could be:
System.out.println(stulist.stream()
.filter(s -> map.keySet().contains(s.getId()))
.count());
Second, the comparison using equals
in your code is incorrect since its between objects of two different types of String
and Stream<String>
.
// here the 's.getId' is a String while 'map.entrySet()...map()' provides 'Stream<String>'
.filter(s -> s.getId().equals(map.entrySet().stream().map(Map.Entry::getKey)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With