如何识别原始类型

时间:2019-04-18 17:59:44

标签: java java-8 java-stream generic-programming raw-types

我有这个练习:

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());

它不能编译。为什么在第一种情况下代码会编译?

3 个答案:

答案 0 :(得分:4)

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很明显将自己声明为Stream<Integer>,因为它是根据List<Integer>创建的。


请注意,lambda的语法错误,应为x -> x % 2 == 0,带有箭头->

答案 1 :(得分:2)

您是正确的,这是原始类型:

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并将它们视为对象,因此您不能使用{{1} }运算子。我得到的实际错误是:

%

请注意,这将忽略lambda中的语法错误。正确的语法是bad operand types for binary operator '%' first type: Object second type: int bad operand types for binary operator '>' first type: Object second type: int 而不是x -> x > 3

答案 2 :(得分:2)

List newList只是流链的返回类型。

实际上,您正在使用非原始类型的List<Integer> iList。因此没有编译错误