使用流时,非常相似的两段代码的行为有所不同。
我不明白编译器的错误试图传达什么。
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static java.util.stream.Collectors.toList;
public class Main {
public static void main(String[] args) {
// Pythangorian stream
List<List<Integer>> ret = IntStream.range(1, 10).boxed()
.flatMap(a -> IntStream.range(a, 10)
// This works fine...
// .mapToObj(b -> Arrays.asList(a, b, a*a + b*b))
.mapToObj(b -> Arrays.asList(a, b, Math.sqrt(a*a + b*b)))
// .filter(t -> Math.sqrt(t.get(2)) % 1 == 0))
.filter(t -> t.get(2) % 1 == 0))
.collect(toList());
System.out.println(ret);
}
}
如果在Math.sqrt
中使用mapToObj
,则会出现编译器错误。如果没有,它工作正常。错误消息是这样的:
Error:(21, 62) java: bad operand types for binary operator '%'
first type: java.lang.Number&java.lang.Comparable<? extends java.lang.Number&java.lang.Comparable<?>>
second type: int
Error:(22, 25) java: incompatible types: inference variable T has incompatible bounds
equality constraints: java.util.List<java.lang.Integer>
lower bounds: java.util.List<java.lang.Number&java.lang.Comparable<? extends java.lang.Number&java.lang.Comparable<?>>>
有人可以告诉我此错误消息在说什么吗?我知道我对Java的一点了解是主要的问题。您能指导我在哪里找到了解这一点的方法吗?
答案 0 :(得分:4)
原因是您尝试将Clean All -> Build
更改为collect
,但应改用List<Integer>
。此外,您的List<? extends Number>
方法可以删除,因为此条件始终为真,即,任何整数都可以除以1,而没有余数。
工作代码如下:
filter
原因是List<List<? extends Number>> ret = IntStream.range(1, 10)
.boxed()
.flatMap(a -> IntStream.range(a, 10)
.mapToObj(b -> Arrays.asList(a, b, Math.sqrt(a * a + b * b))))
.collect(toList());
返回Math.sqrt()
,并且double
和a
是整数,因此不能将这三个全部b
都collect
。第二种方法是将List<Integer>
转换为collect
,并使用从整数到双精度的显式转换:
List<Double>