在现有的Java 7代码中使用Java 8 Optional [英] Use Java 8 Optional in existing Java 7 code

查看:80
本文介绍了在现有的Java 7代码中使用Java 8 Optional的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个作业需要将以下Java 8之前的代码转换为Java 8代码.以下只是一种使我难以完成的方法:

I have an assignment in which I need to convert the following pre-Java 8 code to Java 8 code. Below is just one method which is giving me hard time to finish up:

  public static List<VehicleMake> loadMatching(Region region, String nameStartsWith, VehicleLoader loader) {
    if ((nameStartsWith == null) || (region == null) || (loader == null)) {
        throw new IllegalArgumentException("The VehicleLoader and both region and nameStartsWith are required when loading VehicleMake matches");
    }
    List<VehicleMake> regionMakes = loader.getVehicleMakesByRegion(region.name());
    if (regionMakes == null) {
        return null;
    }
    List<VehicleMake> matches = new ArrayList<>(regionMakes.size());
    for (VehicleMake make : regionMakes) {
        if ((make.getName() == null) || !make.getName().startsWith(nameStartsWith)) {
            continue;
        }
        matches.add(make);
    }
    return matches;
}

我想使用Optional<T>删除空检查,而不修改以前创建的类和接口.

I want to remove the null checks by using Optional<T> without modifying previously created classes and interfaces.

我尝试通过更改方法的返回类型并执行以下操作开始,但是编译器抛出此错误:
Bad return type in method reference,因为VehicleMake类没有可选的实例字段.
以下是我的代码尝试:

I tried to begin by changing the method return type and doing the following but compiler is throwing this error:
Bad return type in method reference since the VehicleMake class doesn't have optional instance fields.
Following is my code attempt:

   public static Optional<List<VehicleMake>> loadMatchingJava8(Region region, String nameStartsWith, VehicleLoader loader) {
    Optional<List<VehicleMake>> regionMakes = Optional.ofNullable(loader).ifPresent(loader.getVehicleMakesByRegion(Optional.ofNullable(region).ifPresent(region.name())));
    /*

    TODO rest of the conversion
     */
}

通过不将参数传递给方法引用来删除flatMap并更正了代码.但是现在它不让我将region.name()传递给getVehicleMakesByRegion()

Removed the flatMap and corrected code by not passing argument to method reference. But now it is not letting me pass region.name() to getVehicleMakesByRegion()

将消费者传递给ifPresent():

Optional<List<VehicleMake>> regionMakes = Optional.ofNullable(loader).ifPresent(()-> loader.getVehicleMakesByRegion(Optional.ofNullable(region).ifPresent(()->region.name()));

推荐答案

您可以将最初的null支票替换为

You may replace your initial null checks with

Optional.ofNullable(nameStartsWith)
        .flatMap(x -> Optional.ofNullable(region))
        .flatMap(x -> Optional.ofNullable(loader))
        .orElseThrow(() -> new IllegalArgumentException(
            "The VehicleLoader and both region and nameStartsWith"
          + " are required when loading VehicleMake matches"));

但这是对该API的滥用.更糟的是,这浪费了资源,无法实现在错误情况下提供毫无意义的异常的可疑目标.

but it’s an abuse of that API. Even worse, it wastes resource for the questionable goal of providing a rather meaningless exception in the error case.

Objects.requireNonNull(region, "region is null");
Objects.requireNonNull(nameStartsWith, "nameStartsWith is null");
Objects.requireNonNull(loader, "loader is null");

简洁明了,在错误情况下会抛出异常并给出准确的消息.这将是NullPointerException而不是IllegalArgumentException,但这即使是更改也将导致对实际问题的更精确描述.

which is concise and will throw an exception with a precise message in the error case. It will be a NullPointerException rather than an IllegalArgumentException, but even that’s a change that will lead to a more precise description of the actual problem.

关于该方法的其余部分,我强烈建议不要将Collection最初设置为null.然后,您不必测试getVehicleMakesByRegionnull的结果,也不会自己返回null.

Regarding the rest of the method, I strongly advice to never let Collections be null in the first place. Then, you don’t have to test the result of getVehicleMakesByRegion for null and won’t return null by yourself.

但是,如果您必须保留原始逻辑,则可以使用

However, if you have to stay with the original logic, you may achieve it using

return Optional.ofNullable(loader.getVehicleMakesByRegion(region.name()))
               .map(regionMakes -> regionMakes.stream()
                    .filter(make -> Optional.ofNullable(make.getName())
                                            .filter(name->name.startsWith(nameStartsWith))
                                            .isPresent())
                    .collect(Collectors.toList()))
               .orElse(null);

旨在用于拒绝 null引用的初始代码不应与旨在用于处理 null引用的实际操作混合使用.

The initial code, which is intended to reject null references, should not get mixed with the actual operation which is intended to handle null references.

这篇关于在现有的Java 7代码中使用Java 8 Optional的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆