在寻找将Wrapper对象与Stream进行比较时,我正在寻找一种优雅的方式来克服。
参考问题:Filtering keys from map to list attribute in java-8
最近我在将List
的成员与Map
的键进行比较时遇到了它。
我知道还有其他方法可以比较而不做我正在做的事情,但是如果有的话,我正在寻找普通演员。
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());
我的代码正确编译,但是输出为“ 0” ,而我希望输出为 2 。
我确定这是由于类型不匹配引起的,但是为什么编译器不是这样 引发错误?
警告我: Unlikely argument type for equals(): Stream<String> seems to be unrelated to String
答案 0 :(得分:2)
首先,您可能打算这样做:
System.out.println(stulist.stream()
.filter(s -> map.keySet().contains(s.getId()))
.count());
第二,在代码中使用equals
进行的比较是不正确的,因为它是在两种String
和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)))
答案 1 :(得分:1)
您可以使用map.containsKey
避免在每个学生条目的条目集上运行流:
long count = stulist.stream().map(student::getId).filter(map::containsKey).count();
收到警告是因为检测到您正在测试String.equals(Stream<String>)
,这当然很可能是错误(在您的示例中,肯定是)。
如果您要使用当前的逻辑,则必须进行正确的检查:
long count = stulist.stream()
.filter(s -> map.entrySet()
.stream()
.map(Map.Entry::getKey)
.anyMatch(s.getId()::equals))
.count();
答案 2 :(得分:1)
基本上,要了解为什么编译器没有给出错误,您应该研究String.equals()方法的实现
s.getId().equals(map.entrySet().stream().map(Map.Entry::getKey))
现在,让我们回到这一行:
s.getId()
我们知道String
的类型为map.entrySet().stream().map(Map.Entry::getKey)
,而Stream<String>
的类型为Stream<String>
。
由于instanceof String
不是String.equals()
,因此很明显,每次与false
比较时,s.getId()
方法将返回map.entrySet().stream().map(Map.Entry::getKey)
String.equals()
(因此, 0 在末尾计数)。并且编译器不会发出错误,因为实际上没有发生任何非法(考虑到count
的实现)。
在没有警告的情况下找到System.out.println(
stulist.stream()
.map(Student::getId)
.filter(map::containsKey)
.count());
的最干净的方法可能是:
WHERE