Java 使用“可选”填充地图中的值

Java 使用“可选”填充地图中的值,java,Java,我是Java新手,还在学习Optionals。我理解它是用来避免空指针异常的 我有一段代码,我想在其中使用optional,如下所示: final MetadataExtractor<FCAddress> metadataExtractor = t -> { final Map<String, String> metadata = new HashMap<>(); metadata.put("senderCount

我是Java新手,还在学习Optionals。我理解它是用来避免空指针异常的

我有一段代码,我想在其中使用optional,如下所示:

    final MetadataExtractor<FCAddress> metadataExtractor = t -> {
        final Map<String, String> metadata = new HashMap<>();
        metadata.put("senderCountryCode", t.getCountryCode());
        metadata.put("senderState", t.getState());
        metadata.put("senderPostalCode",t.getPostalCode());
        return metadata;
    };
final MetadataExtractor MetadataExtractor=t->{
最终映射元数据=新HashMap();
put(“senderCountryCode”,t.getCountryCode());
put(“senderState”,t.getState());
put(“senderPostalCode”,t.getPostalCode());
返回元数据;
};
在这里,我的用例是,如果SenderState为空,即t.getState()为空,我希望映射字段为空,即不填充

我试过这样的方法:

    final MetadataExtractor<FCAddress> metadataExtractor = t -> {
        final Map<String, String> metadata = new HashMap<>();
        metadata.put("senderCountryCode", t.getCountryCode());
        Optional<String> senderState = Optional.of(t.getState());
        senderState.ifPresent(metadata.put("senderState", t.getState());
        metadata.put("senderPostalCode",t.getPostalCode());
        return metadata;
    };
final MetadataExtractor MetadataExtractor=t->{
最终映射元数据=新HashMap();
put(“senderCountryCode”,t.getCountryCode());
Optional senderState=Optional.of(t.getState());
ifPresent(metadata.put(“senderState”,t.getState());
put(“senderPostalCode”,t.getPostalCode());
返回元数据;
};
但这会产生一个编译错误,我在这方面哪里出错了? 错误是:“如果存在 (java.util.function.Consumer) 在“可选”中,无法应用“

仍在学习Optionals。我理解它用于避免空指针异常

不一定。它们是一种手段,让你拥有一些代表“无”的东西

关于您的实际编译错误:

senderState.ifPresent(metadata.put("senderState", t.getState());
ifPresent()
想要一个消费者

public void ifPresent(Consumer<? super T> consumer)

应该这样做。

在此特定代码中,
可选
的使用没有用处,因为您不希望向映射中添加
可选
,而只跳过

不创建新对象的最简单解决方案是添加对值
t.getState()
的检查,如下所示:

final MetadataExtractor<FCAddress> metadataExtractor = t -> {
    final Map<String, String> metadata = new HashMap<>();
    metadata.put("senderCountryCode", t.getCountryCode());
    if (t.getState() != null) {
       metadata.put("senderState", t.getState());
    }
    metadata.put("senderPostalCode",t.getPostalCode());
    return metadata;
};
请注意,此解决方案将创建两个不必要的对象:

  • 显式
    可选
    发送者状态
  • 以及
    消费者的另一个对象,该对象在
    ifPresent
    方法中创建为lambda表达式

您需要将消费者(lambda)传递给ifPresent:

senderState.ifPresent(state->metadata.put(“state”,state);
//重要提示:使用者始终会收到一个参数。
//空值“()->”无效!
lambda仅在senderState存在的情况下执行(即不为null)

顺便说一句,通过使用
可选.of nullable(…)
来构造您的
发送者状态是非常重要的!否则,它将抛出一个NPE


查看一个深入的教程:

只是为了展示一种完全不同的解决问题的方法:

将所有内容放入映射,然后在以下操作之后删除空值:

metadata.values().removeIf(Objects::isNull);

这在语法上要整洁得多,但可能会更快,也可能不会更快,因为先做了某件事,然后又撤销了它,而不是一开始就不做。

为什么要在这里使用
可选的
?如果出现错误(编译或运行时),只需使用简单的旧if然后把它包括在你的问题中。
ifPresent
接受一个
Consumer
。你给它一个字符串。@AxelH OP使用的是ifPresent,而不是is。不,OP不想
map
@AndyTurner-yep……如果t.getState()为null,我的badof()将抛出一个异常。要使它工作,请使用nullable()必须使用。@AndyTurner一旦进入lambda,就不需要使用
t.getState()
,而是
state
final MetadataExtractor<FCAddress> metadataExtractor = t -> {
    final Map<String, String> metadata = new HashMap<>();
    metadata.put("senderCountryCode", t.getCountryCode());

    // Here you create a not useful object that can be replaced with a simple if
    Optional<String> senderState = Optional.ofNullable(t.getState());

    // Here you create a second not necessary object because a lambda
    // espression is an instance of an anonimous class implementing
    // the corresponding interface
    senderState.ifPresent(() -> 
         metadata.put("senderState", t.getState()
    );
    metadata.put("senderPostalCode",t.getPostalCode());
    return metadata;
};
metadata.values().removeIf(Objects::isNull);