小心 Java 選用方法
來源:
Dev.to根據 Oracle 的說法, Optional物件是「一個可能包含也可能不包含非空值的容器物件」。Optional首先出現在Java 8中,並已被SpringBoot團隊在許多專案中使用。
Options最常見的用途是在 Spring Data 專案中。讓我們來看看 JpaRepository 介面和範例方法。例如,我們有一個具有整數類型 Id 的
User對象,並且我們有一個 JpaRepository 。
@Repository
public interface IUserRepo extends JpaRepository<User, Integer>
{
Optional<User> findByUserName(String userName);
}
我們定義了一個方法,透過使用者名稱尋找使用者並傳回
User的
Optional。
便利方式可選
許多方法中都包含可選,使我們能夠編寫乾淨且可讀的程式碼。
然而,有一種方法會產生危險的意外行為。
認識 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時,您需要:
- 將每個訂單與產品清單相符。
- 顯示每種產品的價格。
- 透過將所有價格加在一起來總結所有價格。
那麼讓我們用 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 和Reduce 在您需要從
Collection中提取資訊的情況下很有幫助。
GO TO FULL VERSION