如何识别原始类型
how to recognize raw type
我有这个练习:
List<Integer> iList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
Predicate<Integer> p = x -> x%2 == 0;
List newList = iList.stream()
.filter(p)
.filter(x -> x>3)
.collect(Collectors.toList());
System.out.println(newList);
在我看来,newList 是原始类型而不是泛型,因为它被初始化为 List newList
而不是 List<Integer>
。
这个练习怎么可能有正常的结果而不是编译错误?
如果我写:
List iList = Arrays.asList(1,2,3,4,5,6,7);
iList.stream()
.filter(x -> x%2==0)
.filter(x -> x>3)
.collect(Collectors.toList());
它不编译。为什么在第一种情况下代码可以编译?
你是对的,这是原始类型:
List newList = iList.stream().filter(p).filter(x>x>3).collect(Collectors.toList());
System.out.println(newList);
然而,原始类型是完全合法的,不会导致编译错误。它们只是非常糟糕的使用习惯。您的第二个代码片段证明了这一点:
List iList= Arrays.asList(1,2,3,4,5,6,7);
iList.stream().filter(x -> x%2 ==0).filter(x -> x>3).collect(Collectors.toList());
这里因为 iList
是原始类型,编译器不知道 iList
包含 int
并将它们视为对象,所以你不能使用 %
运算符在这里。我得到的实际错误是:
bad operand types for binary operator '%'
first type: Object
second type: int
bad operand types for binary operator '>'
first type: Object
second type: int
请注意,这会忽略您的 lambda 表达式中的语法错误。正确的语法是 x -> x > 3
而不是 x>x>3
Stream
将原始对象序列识别为简单的 Stream<Object>
。如果您想将其视为 Stream<Integer>
,则必须使用 Stream::mapToInt
显式声明此事实并将整个 Stream
:
装箱
List<Integer> newList = iList.stream() // Stream
.mapToInt(obj -> Integer.valueOf(obj.toString())) // IntStream
.boxed() // Stream<Integer>
.filter(x -> x % 2 == 0)
.filter(x -> x > 3)
.collect(Collectors.toList()); // List<Integer>
在第一种情况下,显然 Stream
将 self 声明为 Stream<Integer>
,因为它是从 List<Integer>
.
创建的
请注意,您的 lambda 语法错误,应该是 x -> x % 2 == 0
和箭头 ->
。
List newList
只是 return 类型的流链。
实际上您正在使用 List<Integer> iList
这不是原始类型。因此没有编译错误
我有这个练习:
List<Integer> iList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
Predicate<Integer> p = x -> x%2 == 0;
List newList = iList.stream()
.filter(p)
.filter(x -> x>3)
.collect(Collectors.toList());
System.out.println(newList);
在我看来,newList 是原始类型而不是泛型,因为它被初始化为 List newList
而不是 List<Integer>
。
这个练习怎么可能有正常的结果而不是编译错误?
如果我写:
List iList = Arrays.asList(1,2,3,4,5,6,7);
iList.stream()
.filter(x -> x%2==0)
.filter(x -> x>3)
.collect(Collectors.toList());
它不编译。为什么在第一种情况下代码可以编译?
你是对的,这是原始类型:
List newList = iList.stream().filter(p).filter(x>x>3).collect(Collectors.toList());
System.out.println(newList);
然而,原始类型是完全合法的,不会导致编译错误。它们只是非常糟糕的使用习惯。您的第二个代码片段证明了这一点:
List iList= Arrays.asList(1,2,3,4,5,6,7);
iList.stream().filter(x -> x%2 ==0).filter(x -> x>3).collect(Collectors.toList());
这里因为 iList
是原始类型,编译器不知道 iList
包含 int
并将它们视为对象,所以你不能使用 %
运算符在这里。我得到的实际错误是:
bad operand types for binary operator '%'
first type: Object
second type: int
bad operand types for binary operator '>'
first type: Object
second type: int
请注意,这会忽略您的 lambda 表达式中的语法错误。正确的语法是 x -> x > 3
而不是 x>x>3
Stream
将原始对象序列识别为简单的 Stream<Object>
。如果您想将其视为 Stream<Integer>
,则必须使用 Stream::mapToInt
显式声明此事实并将整个 Stream
:
List<Integer> newList = iList.stream() // Stream
.mapToInt(obj -> Integer.valueOf(obj.toString())) // IntStream
.boxed() // Stream<Integer>
.filter(x -> x % 2 == 0)
.filter(x -> x > 3)
.collect(Collectors.toList()); // List<Integer>
在第一种情况下,显然 Stream
将 self 声明为 Stream<Integer>
,因为它是从 List<Integer>
.
请注意,您的 lambda 语法错误,应该是 x -> x % 2 == 0
和箭头 ->
。
List newList
只是 return 类型的流链。
实际上您正在使用 List<Integer> iList
这不是原始类型。因此没有编译错误