检查Lambda表达式

时间:2017-03-31 03:41:57

标签: java lambda java-8

我有这段代码:

 Function<Integer, String> converter = (num) -> Integer.toString(num);

正如我在这里看到的那样,“num”是函数的参数,但是,如果我的用户意外输入了一个浮点数,则会出现错误。 我只在函数代码中创建“num”参数? 如何添加if(!(num instanceOf Integer)) {//throw exception}之类的异常。

5 个答案:

答案 0 :(得分:1)

要将检查添加到lambda表达式,只需将其用作函数:

Function<Number , String> converter = (num) -> {
    final String result;
    if (num instanceof Integer) {
        result = Integer.toString((int)num);
    } else {
        result = "show some error";
       //Or throw an exception
    }
    return result;
};

更好的方法是调用方法,因为这可能会使更长的方法变得混乱。

也许有点像这样:

Function<Number , String> converter = e -> convertString(e);

public static String convertString(Number num) {
    final String result;
    if (num instanceof Integer) {
        result = Integer.toString((int)num);
    } else {
        result = "show some error";
    }
    return result;
}

您也可以使用FooClass :: convertString。

答案 1 :(得分:0)

一旦尝试通过转换器,就会出现编译时错误。

public static void main(String[] args) {
        Function<Integer, String> converter = (num) -> Integer.toString(num);
        Stream<String> stream = asList(1, 3, 4.5).stream().map(converter); //compilation error here as soon as you enter a float in asList.
        stream.forEach(System.out::println);
    }

答案 2 :(得分:0)

您可以创建一个包装器方法,该方法返回包含在try catch中的转换器函数。

Function<Integer, String> converter = num -> num.toString();

System.out.println(wrapper(converter).apply(5));

private static Function<Integer, String> wrapper(Function<Integer, String> function) {
        return x -> {
            try {
                return function.apply(x);
            } catch (Exception e) {
                return "Error";
            }
        };
    }

答案 3 :(得分:0)

声明

Function<Integer, String> converter = num -> Integer.toString(num);

只是

的简写
Function<Integer, String> converter = (Integer num) -> Integer.toString(num);

让编译器使用目标类型num推断Function<Integer, String>的类型。虽然Function是一个通用接口,其类型参数可以使用未经检查的操作进行忽略,但lambda表达式的形式参数具有不能被污染的指定类型。即。

((Function)converter).apply(1f); // should raise "unchecked" warning
在输入lambda表达式的代码之前,

将抛出java.lang.ClassCastException: java.lang.Float cannot be cast to java.lang.Integer

就像你写的那样

Function<Integer, String> converter = MyClass::myLambdaCode;
…
private static String myLambdaCode(Integer num) {
    return Integer.toString(num);
}

更简洁。但从技术上讲,它是一样的。使用不是Integer实例的对象输入代码是不可能的。检查num是否是Integer之外的其他内容没有意义。它始终是(除非null)。如果它是null,那么NullPointerExceptionInteger.toString(num)抛出,所以事先检查一下,只是为了做同样的事情,即抛出异常,这已经过时了。

答案 4 :(得分:0)

根据KISS的首选内容是在Function调用之前检查其类型。

if(input instanceof Integer){
    return converter.apply((Integer)input);
}else{
    //throw exception;
}

或者您需要使用Optional过滤输入。

Function<Integer, String> converter = (num) -> Integer.toString(num);

String result = Optional.ofNullable(input)
            .filter(Integer.class::isInstance)
            .map(Integer.class::cast)
            .map(converter).orElseThrow(IllegalArgumentException::new);

或者你可以合并Optional&amp; Function声明两个函数,一个是检查类型,另一个是转换器,但我认为这是不必要的,并且在你的情况下过度编码。

Function<Object, Integer> typeChecking = (input) -> (Integer) Optional.ofNullable(input)
        .filter(Integer.class::isInstance)
        .orElseThrow(IllegalArgumentException::new);

Function<Integer, String> intToString = (num) -> Integer.toString(num);

Function<Object, String> converter = typeChecking.andThen(intToString);

检查lambda表达式中的参数类型会导致lambda膨胀,并且通常是不必要的,因为如果定义具有完全参数类型的FunctionInterface,则不能将不兼容的类型传递给lambda表达式,如果你确实喜欢@Holger将抛出CalssCastException。