如何使用 optional 和 filter along 从 wsdl2java 生成的 chained/cascaded 个对象中检索对象

how to use optional and filter along to retrieve an object from chained/cascaded objects generated by wsdl2java

我理解在处理 Java 中的分层对象时建议使用 flatMap,尤其是在从 XML 文件创建的对象中提取值时。

不依赖 Optional 并且由于 getCommercieleNaam() 会给我一个列表,我编码:

NaamOndernemingLijstCommercieelType naamOndernemingLijstCommercieel = onderneming.getNamen()
        .getCommercieleNamen();
NaamOndernemingType naamOndernemingType = naamOndernemingLijstCommercieel.getCommercieleNaam().stream()
        .filter(x -> x.getTaalcode().getValue() == "nl").findFirst().get();

简而言之,它将抛出级联对象和 return 为荷兰语找到的名字。我认为这是非常不安全的,而不是检查所有对象是否为空,我更喜欢使用 Optional.

然后我尝试按照我的理解编写代码,这是正确的方法,但我不知道如何应用过滤器以便仅从列表中检索符合条件的对象(语言 == "nl" in我的场景):

    Optional<NamenOndernemingType> optionalNamenOnderneming = onderneming.getNamen(); 
    NaamOndernemingType naamOndernemingType = optionalNamenOnderneming.flatMap(NamenOndernemingType::getCommercieleNamen)
            .flatMap(NaamOndernemingLijstCommercieelType::getCommercieleNaam)
            .filter(x -> "nl".equals(x.toString()));

PS.: 在荷兰语中,naam 表示名称(单数)而 Namen 表示名称(复数)

嗯,我得到的最接近的是

    Optional<NamenOndernemingType> optionalNamenOnderneming = Optional.ofNullable(onderneming.getNamen());
    List<NaamOndernemingType> listNaamOndernemingType = optionalNamenOnderneming
            .flatMap(NamenOndernemingType::getCommercieleNamen)
            .map(NaamOndernemingLijstCommercieelType::getCommercieleNaam);

但它既不起作用,在我解决这个问题后,我还需要过滤。

*已编辑

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "NamenOndernemingType", propOrder = {
    "maatschappelijkeNamen",
    "afgekorteNamen",
    "commercieleNamen"
})
public class NamenOndernemingType {

...

    public NaamOndernemingLijstCommercieelType getCommercieleNamen() {
        return commercieleNamen;
    }


@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "NaamOndernemingLijstCommercieelType", propOrder = {
    "commercieleNaam"
})
public class NaamOndernemingLijstCommercieelType {
...

    public List<NaamOndernemingType> getCommercieleNaam() {

* 解*

Optional.ofNullable(onderneming.getNamen()).map(NamenOndernemingType::getCommercieleNamen)
                .map(NaamOndernemingLijstCommercieelType::getCommercieleNaam).get().stream().filter(Objects::nonNull)
                .filter(x -> x.getTaalcode().getValue() == "nl").findFirst()
                .ifPresent(o -> myMethod("onderneming_commerciele_naam", o.getNaam().getValue()));

PS.: 未来的读者我觉得值得阅读我的其他问题作为 weel:

考虑到您已经说过 getCommercieleNaam return 是 List<NaamOndernemingType>,所以我认为您在这里不需要 map 因此一旦我们展平我们将有一个 Stream<NaamOndernemingType> 然后我们可以找到所有以 "nl" 作为字符串表示的对象。

List<NaamOndernemingType> listNaamOndernemingType = optionalNamenOnderneming
           .flatMap(NaamOndernemingLijstCommercieelType::getCommercieleNaam)              
           .filter(Objects::nonNull)
           .filter(x -> "nl".equals(x.toString()))
           .orElse(null);

鉴于 Optional 没有 collect 作为 终端 操作,我们可以简单地使用 orElse 到 return 值(如果存在),否则 return null。在这种情况下 valueList<NaamOndernemingType>.

注意 - 如果你想将 Stream<Stream<R>> 更改为 Stream<T>,你只需要调用 flatMap 否则你只需要调用map 会 return a Stream<R>.

感谢Aominè的推荐和基于

的讨论

我找到了这个解决方案:

Optional.ofNullable(onderneming.getNamen()).map(NamenOndernemingType::getCommercieleNamen)
                .map(NaamOndernemingLijstCommercieelType::getCommercieleNaam).get().stream().filter(Objects::nonNull)
                .filter(x -> x.getTaalcode().getValue() == "nl").findFirst()
                .ifPresent(o -> myMethod("onderneming_commerciele_naam", o.getNaam().getValue()));