克服equals()不太可能使用参数类型的绝佳方法:Stream <string>似乎与String

时间:2019-02-18 11:30:03

标签: java java-8 java-stream

在寻找将Wrapper对象与Stream进行比较时,我正在寻找一种优雅的方式来克服。

Github工作链接:https://github.com/vishwaratna/Unlikely-argument-type-for-equals-Stream-String-/commit/d803f77c923e81fe7531ecb467561ac785d7aca5

参考问题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

3 个答案:

答案 0 :(得分:2)

首先,您可能打算这样做:

System.out.println(stulist.stream()
        .filter(s -> map.keySet().contains(s.getId()))
        .count());

第二,在代码中使用equals进行的比较是不正确的,因为它是在两种StringStream<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