v-> v> 5

时间:2019-01-09 12:22:17

标签: java lambda java-8 java-stream

我有一个给定的函数调用,而java给我一个错误,因为对象不能与int进行比较(当然...)。有人可以向我解释我必须更改的内容吗?

我尝试用不同的方式支撑lambda表达式,但没有任何有用的结果。我认为lambda表达式是正确的,并且filter-function有点错误,但是我无法找出我的错误...

// function call
filter(v -> v > 5)

// function
public Optional<T> filter(Predicate<T> tester) {
    if(isPresent() && tester.test(get())) {
        return this;
    } else {
    return Optional.empty();
    }
}

我希望看到一个Optional.empty-Object,但是会遇到Java错误,因为v > 5对象v与int不具有可比性。

4 个答案:

答案 0 :(得分:4)

您必须将T设为与int相当的包装器类。例如

IntStream.range(0, 10)
         .filter(v -> v > 5)
         .forEach(System.out::println);

很好,因为vint

T未知时,您不能使用此表达式。

您可以做的是假设T必须是数字,例如

filter( v -> ((Number) v).doubleValue() > 5)

这会产生ClassCastExpection,但是T是另一种类型。

真正的解决方案是使T成为Number

例如

class MyClass<T extends Number> {
    public Optional<T> filter(Predicate<T> test) {

或将其设置为int之类的特定类型

class MyClass {
    public IntOptional filter(IntPredicate test) {

答案 1 :(得分:3)

在Java原语中,类型(例如int)和对象(例如Object)在类型层次结构中没有共同的祖先。因此,谓词和其他流构造有两种味道,例如在使用int时必须使用IntPredicate,在使用Predicate时必须使用Object

编写过滤器函数的方法是使用OptionalIntIntPredicate

public OptionalInt filter(IntPredicate tester) {
    if (isPresent() && tester.test(get())) {
        return ...
    } else {
        return OptionalInt.empty();
    }
}

答案 2 :(得分:3)

v -> v > 5可能具有不同的含义。这取决于上下文。

  1. 可能是(Object v) -> v > 5导致编译错误,因为>无法应用于Object

    Stream.<Object>of("123", 123).filter(v -> v > 5);
    
  2. 可能是(Integer v) -> v > 5,这意味着将执行拆箱和自动装箱以便进行比较并返回结果:

    Stream.<Integer>of(123, 123).filter(v -> v > 5);
    
  3. 它可能是(int v) -> v > 5,表示它是IntPredicate的实例,在这里一切顺利:

    IntStream.of(123, 123).filter(v -> v > 5);
    

答案 3 :(得分:2)

  

我认为lambda表达式是正确的,并且   过滤器功能略有错误,但我无法找出我的   错误...

你是对的。
您的方法似乎击败了为该类声明的泛型类型,因为您的方法首先是在泛型类中定义的。

假设您的类名为Foo,这里的filter()方法依赖于通用的T类型作为return / parameter类型:

public class Foo<T>{
     // ...
    public Optional<T> filter(Predicate<T> tester) { 
      // ...
    }
}

可以推断。
因此您得到Predicate中的T。但是T取决于类中定义的泛型类型,还取决于声明Foo类实例的方式。
看来这里T不是Number

或者,您也可以依赖于声明的Foo变量的推断。
如果您这样做:

Foo<Integer> foo = new Foo<>();
Optional<Integer> optInt = foo.filter(v -> v > 5);

它将编译得很好,因为将从Integer推断出Foo<Integer>

因此,我认为要解决您的问题,您应该将Number或Integer声明为通用类型的基类:

public class Foo<T extends Integer>{
     // ...
    public Optional<T> filter(Predicate<T> tester) { 
      // ...
    }
}

或像前面的示例一样依赖客户端的推断。