Java Optional メソッドには注意してください
出典:
Dev.to Oracle によると、 Optionalオブジェクトは「null 以外の値を含む場合と含まない場合があるコンテナ オブジェクト」です。Optional は Java 8 で初めて登場し、SpringBoot チームによって多くのプロジェクトで使用されてきました。
Optionalsの最も一般的な使用法は、Spring Data プロジェクト内です。JpaRepository インターフェースとメソッドの例を見てみましょう。たとえば、整数型 ID を持つ
Userオブジェクトがあり、それに対する JpaRepository があります。
@Repository
public interface IUserRepo extends JpaRepository<User, Integer>
{
Optional<User> findByUserName(String userName);
}
ユーザーを名前で検索し、 Userの
Optional を返すメソッドを定義しました。
便利な方法 オプション
Optional は、クリーンで読みやすいコードを作成できるようにする多くのメソッドに含まれています。
ただし、危険な予期しない動作を伴う方法が 1 つあります。
orElse メソッドの登場
Oracle のドキュメントによると、次のようになります。
public T orElse(T other)
値がある場合は値を返し、それ以外の場合は別の値を返します。
これで、 Optionalパラメーターが空の場合に実行されるメソッド呼び出しを
orElseパラメーターとして追加できるようになりました。
はい、その通りですが、 Optionalに値があるかどうかに関係なく、とにかく動作すると私が言ったらどうでしょうか。確認しよう:
@Test
public void orElseTest()
{
String result = Optional.of("hello").orElse(someMethod());
assertThat(result).isEqualTo("hello");
}
private String someMethod()
{
System.out.println("I am running !!");
return "hola";
}
テストは成功しましたが、コンソールに 「
I am running 」という行が出力されていることがわかります。
なぜこうなった?
Java は、 Elseの場合に返される値を提供するメソッドを実行します。
ので注意してください!
orElse内のメソッドは引き続き実行されるため、副作用がある可能性がある場合は注意する必要があります。
何をするか?
OrElseGetメソッドを使用できます。このメソッドは、
Optional が存在する場合にサプライヤー メソッドを実行します。
Java でリストの要素を表示および合計する方法
出典:
DZone この記事では、Java でリストの要素数を表示および集計する方法を学びます。リストから項目をマッピングするということは、リスト内の各項目が別のオブジェクトに変換されることを
意味します。リストの要素を合計すると、そのリストのすべての要素が 1 つのオブジェクトに結合されることを意味しますが、元のオブジェクトと同じ型である必要はありません。注文のリストがあり、各注文に製品のリストがあるとします。
record Order(String customer, List<Product> products) {
}
record Product(String brand, String modelName, BigDecimal price) {
}
注文リストからどれくらいの金額が入ってくるかを知りたい場合はどうしますか? 注文ごとに、その注文に含まれる製品のリストを取得する必要があり、これらのリスト内の各製品のコストを取得する必要があります。その後、これらすべての価格を合計する必要があり、これが結果を得る方法です。上記を
Map /
Reduceに変換するには、次のものが必要です。
- 各注文を製品リストと照合します。
- 各商品の価格を表示します。
- すべての価格を合計して合計します。
それでは Java でやってみましょう:
public class OrderMapReducer {
public BigDecimal getTotal(List<Order> orders) {
return orders.stream()
.map(Order::products)
.flatMap(List::stream)
.map(Product::price)
.reduce(BigDecimal::add)
.orElse(BigDecimal.ZERO);
}
}
- ご注文の流れを作成させていただきます。
- 各注文をその製品リストと照合します。
- 各製品リストとフローを対応させます。ここではflatMap を使用する必要があることに注意してください。そうしないと、 Stream <Stream <Product>>が使用されてしまいます。
- 各商品ごとに価格を表示しております。
- すべての価格を合計してみましょう。
- 注文リストが空の場合は、ゼロを返します。
それだけです!これで、すべてが期待どおりに動作していることを確認するテストを作成できます。
@Test
void getTotalPrice() {
List<Order> orders = createOrders();
OrderMapReducer orderMapReducer = new OrderMapReducer();
assertEquals(new BigDecimal(17800), orderMapReducer.getTotal(orders));
}
private static List<Order> createOrders() {
var strato = new Product("Fender", "Stratocaster", new BigDecimal(3500));
var sg = new Product("Gibson", "SG", new BigDecimal(4800));
var lesPaul = new Product("Gibson", "Les Paul", new BigDecimal(4500));
var rr = new Product("Jackson", "RR", new BigDecimal(5000));
return List.of(
new Order("David Gilmour", List.of(strato)),
new Order("Toni Iommi", List.of(sg)),
new Order("Randy Rhoads", List.of(lesPaul, rr))
);
}
ご覧のとおり、 Map and Reduce は、
Collectionから情報を抽出する必要がある場合に役立ちます。
GO TO FULL VERSION