0

以下は Optional の間違った使用例ではないかと思っていました。それはおそらくそうです、それは厄介に見えるからです。

(nullを返す「レガシー」コードの呼び出しに関するものです。)

  private static class Person {
    private Address address;
    private String name;
  }

  private static class Address {
    private Integer housenr;
    private String houseletter;
    private String street;
  }

  public String getAddress(Person person) {
    return Optional.ofNullable(person.getAddress())
      .map(x -> Optional.ofNullable(x.getHousenr()).map(y -> y + " ").orElse("") +
          Optional.ofNullable(x.getHouseletter()).map(y -> y + " ").orElse("") +
          Optional.ofNullable(x.getStreet()).orElse(""))
      .orElse("<unknown>");
  }

  // unit test if string representation of an address is properly generated
  assertThat(getAddress(charlesBabbage))
      .isEqualTo("4 l Regentstreet");

Person クラスと Address クラスのメソッドにコードを入れたほうがいいので、あまり気にしません。

または、「古い方法」で行う必要があります。

  public String getAddress(Person person) {
    if (person.getAddress() == null) {
      return "<unknown>";
    }
    StringBuilder builder = new StringBuilder();
    if (person.getAddress().getHousenr() != null) {
      builder.append(person.getAddress().getHousenr() + " ");
    }
    if (person.getAddress().getHouseletter() != null) {
      builder.append(person.getAddress().getHouseletter() + " ");
    }
    if (person.getAddress().getStreet() != null) {
      builder.append(person.getAddress().getStreet() + " ");
    }
    return builder.toString();
  }

これは単なる例であることに注意してください。接辞、私書箱、町/市、自治体、州、国 (外国の住所は言うまでもありません) などのフィールドをさらに追加すると、問題が悪化します。

4

2 に答える 2

1

どちらの例でも、要素を文字列に追加する前に要素が null でないことを確認するコードを繰り返しています。Stream を使用して結合することで、この反復作業を減らすことができます。

public String getAddress(Person person) {
    return Optional.ofNullable(person.getAddress())
            .map(x -> Stream.of(x.getHousenr(), x.getHouseletter(), x.getStreet())
                        .filter(Objects::nonNull)
                        .map(Object::toString)
                        .collect(Collectors.joining(" "))
            )
            .orElse("<unknown>");
}

または同様に Optional なし:

public String getAddress(Person person) {
    Address address = person.getAddress();
    if (address == null) {
        return "<unknown>";
    }
    return Stream.of(address.getHousenr(), address.getHouseletter(), address.getStreet())
            .filter(Objects::nonNull)
            .map(Object::toString)
            .collect(Collectors.joining(" "))
}
于 2021-01-14T10:51:42.077 に答える