Java 如何识别原始类型

Java 如何识别原始类型,java,generics,java-8,java-stream,raw-types,Java,Generics,Java 8,Java Stream,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) .coll

我有以下练习:

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

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

您是对的,这是一种原始类型:

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
请注意,这将忽略lambdas中的语法错误。正确的语法是x->x>3而不是x>x>3

流将原始对象序列识别为简单流。如果要将其视为流,则必须使用Stream::mapToInt显式声明此事实,并装箱整个流:

在第一种情况下,流显然要声明自己为流,因为它是从列表创建的

注意,lambda的语法错误,应该是x->x%2==0,带箭头->。

List newList只是流链的返回类型


实际上,您使用的是列表iList,它不是原始类型。因此,没有编译错误

原始类型是完全合法的,但是非常糟糕的做法,正如您的第二个代码段未编译所示。第二个代码段不会编译为简单的打字错误。默认情况下,原始类型导致编译错误的想法是错误的。但为什么代码在第一种情况下编译,而在第二种情况下不编译?@Adryr83因为编译器将内容视为对象,所以不能对它们使用%或>。我在这两种情况下使用了相同的方法。我知道对于raw类型,我只能使用Object方法。但为什么在第一种情况下,编译器会编译?在这两种情况下我都应该有编译错误。@Adryr83为什么?你可以有一份清单。错误是当您尝试将列表用作List@Adryr83这里只有newList是原始类型。你唯一要做的就是打印它,这对列表是有效的
bad operand types for binary operator '%'
  first type:  Object
  second type: int

bad operand types for binary operator '>'
  first type:  Object
  second type: int
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>