JavaRush /Java Blog /Random-KO /커피 브레이크 #97. Java Optional 메소드에 주의하십시오. Java 목록의 요소를 표시하고...

커피 브레이크 #97. Java Optional 메소드에 주의하십시오. Java 목록의 요소를 표시하고 합산하는 방법

Random-KO 그룹에 게시되었습니다

Java Optional 메소드에 주의하세요

출처: Dev.to Oracle에 따르면 Optional커피 브레이크 #97.  Java Optional 메소드에 주의하십시오.  Java 목록의 요소를 표시하고 합산하는 방법 - 1 개체는 "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은 깨끗하고 읽기 쉬운 코드를 작성할 수 있는 많은 메서드에 포함되어 있습니다.
  • 지도(..).또는(...)
  • 지도(...).또는Else(...)
  • 전체 목록은 Oracle 설명서 에서 찾을 수 있습니다 .
그러나 위험할 정도로 예상치 못한 동작이 발생하는 방법이 하나 있습니다.

orElse 메소드를 만나보세요

오라클 문서에 따르면:
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 내부의 메소드는 계속 실행되므로 부작용이 있을 수 있으므로 주의해야 합니다 .

무엇을 해야 할까요?

Optional이 존재하는 경우 공급자 메서드를 실행하는 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. 주문 목록이 비어 있으면 0 을 반환합니다.
그게 다야! 이제 모든 것이 예상대로 작동하는지 확인하는 테스트를 만들 수 있습니다.
@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 에서 정보를 추출해야 하는 경우에 도움이 됩니다 .
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION