JavaRush /Java 博客 /Random-ZH /喝咖啡休息#97。小心 Java 可选方法。如何在 Java 中显示列表中的元素并对其求和

喝咖啡休息#97。小心 Java 可选方法。如何在 Java 中显示列表中的元素并对其求和

已在 Random-ZH 群组中发布

小心 Java 可选方法

来源:Dev.to根据 Oracle 的说法, Optional喝咖啡休息#97。 小心 Java 可选方法。 如何在 Java 中显示列表中的元素并对其求和 - 1对象是“一个可能包含也可能不包含非空值的容器对象”。Optional首先出现在Java 8中,并已被SpringBoot团队在许多项目中使用。Options最常见的用途是在 Spring Data 项目中。让我们看一下 JpaRepository 接口和示例方法。例如,我们有一个具有整数类型 Id 的User对象,并且我们有一个 JpaRepository 。
@Repository
public interface IUserRepo extends JpaRepository<User, Integer>
{
    Optional<User> findByUserName(String userName);
}
我们定义了一个方法,通过用户名查找用户并返回UserOptional

便捷方式可选

许多方法中都包含可选,使我们能够编写干净且可读的代码。 然而,有一种方法会产生危险的意外行为。

认识 orElse 方法

根据 Oracle 文档:
public T orElse(T other)
如果有则返回该值,否则返回其他值。现在我们可以添加一个方法调用作为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";
}
测试成功,但是您会注意到控制台上打印了 “我正在运行”这一行。

为什么会发生这种情况?

Java 运行一个方法来提供Else情况下将返回的值。

所以要小心!

如果orElse中的方法可能有副作用, 您必须小心,因为它仍然会运行。

该怎么办?

您可以使用OrElseGet方法,该方法采用供应商方法来执行(如果可选存在) 。

如何在 Java 中显示列表中的元素并对其求和

来源:DZone 在这篇文章中,您将学习如何在 Java 中显示和汇总列表中的元素数量。映射列表中的项目意味着该列表中的每个项目都将转换为不同的对象。对列表中的元素求和意味着该列表中的所有元素将组合成一个对象,该对象不一定与原始对象类型相同。假设我们有一个订单列表,每个订单都有一个产品列表。
record Order(String customer, List<Product> products) {
}

record Product(String brand, String modelName, BigDecimal price) {
}
如果您想知道订单清单上有多少钱,您会怎么做?对于每个订单,您将需要获取其中包含的产品列表,并且对于这些列表中的每个产品,您将需要获取其成本。之后,您需要将所有这些价格相加,这就是您得到结果的方式。将上面的内容转换为Map / Reduce时,您需要:
  1. 将每个订单与产品列表相匹配。
  2. 显示每种产品的价格。
  3. 通过将所有价格加在一起来总结所有价格。
那么让我们用 Java 来做:
public class OrderMapReducer {
    public BigDecimal getTotal(List<Order> orders) {
        return orders.stream() // 1
                     .map(Order::products) // 2
                     .flatMap(List::stream) // 3
                     .map(Product::price) // 4
                     .reduce(BigDecimal::add) // 5
                     .orElse(BigDecimal.ZERO); // 6
    }
}
  1. 我们创建订单流。
  2. 我们将每个订单与其产品列表进行匹配。
  3. 我们将每个产品列表与流程进行匹配。请注意,我们必须在这里使用flatMap,否则我们最终会得到Stream <Stream <Product>>
  4. 对于每种产品,我们都会显示其价格。
  5. 让我们总结一下所有的价格。
  6. 如果订单列表空,则返回零。
就这样!现在我们可以创建一个测试来确保一切都按预期工作。
@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 和Reduce 在您需要从Collection中提取信息的情况下很有帮助。
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION