Re: [問題] Lambda語法

作者: JustinHere (良葛格)   2015-10-14 09:16:21
方向不太對,仔細看原本的 for 迴圈,其實主要是在 filter 出想要的 Order
,才從後續留下的 Order 取得細節,因此,比較好的寫法是:
orders.stream()
.filter(order -> order.getOrdertails().getAmount() > 5 && order.getOrderDetail().getProduct() != null)
.forEach(order -> {
OrderDetail orderDetail = order.getOrdertails()
String s = String.format("%s Buy %s * %d",
order.getId(),
orderDetail.getProduct().getName(),
orderDetail.getAmount());
System.out.println(s);
});
關鍵在於,原本的 for 迴圈用了兩個 if,其實就是 && 兩個情況的意思 …
當然,如果想要更讀性更好一些,可以將 filter 與 forEach 中的邏輯提取至方法,
然後用方法參考:
orders.stream()
.filter(OrderUtil::amountGTFiveAndHasProduct)
.forEach(OrderUtil::printIdNameAmount);
public class OrderUtil {
public static boolean amountGTFiveAndHasProduct(Order order) {
return order.getOrdertails().getAmount() > 5 &&
order.getOrderDetail().getProduct() != null;
}
public static void printIdNameAmount(Order order) {
OrderDetail orderDetail = order.getOrdertails()
String s = String.format("%s Buy %s * %d",
order.getId(),
orderDetail.getProduct().getName(),
orderDetail.getAmount());
System.out.println(s);
}
}
※ 引述《kojilin (阿~~小達達)》之銘言:
: ※ 引述《Argosde ()》之銘言:
: : 最近在學Java8 Lambda語法
: : 自己在練習兩層for迴圈的重構
: : 遇到一個狀況,不知道是我使用觀念錯誤還是有不知道的方法
: : 兩層For迴圈版本
: : for(Order order : orders){
: : for(OrderDetail orderDetail : order.getOrdertails()){
: : if(orderDetail.getAmount()>5){
: : Product product = orderDetail.getProduct();
: : if(product!=null){
: : String s = String.format("%s Buy %s * %d", order.getId(), product.getName(), orderDetail.getAmount());
: : System.out.println(s);
: : }
: : }
: : }
: : }
: : Lambda版本
: : orders.stream()
: : .flatMap(order -> order.getOrdertails().stream())
: : .filter(orderDetail -> ordertail.getAmount()>5)
: : .map(orderDetail1 -> orderDetail1.getProduct())
: : .forEach(product -> {
: : ?
: : });
: : 在?的地方沒辦法呼叫到上層資料,不知道是不是Lambda不適用這種狀況還是有其他方法
: : 第一次發問,請多指教...
: 這種情況下我就不一定會用 stream, 但你真要做可以像這樣,建一個容器
: class Pair<T1, T2>
: 然後
: orders.stream()
: .flatMap(order -> order.getOrdertails().stream()
: .map(detail -> new Pair<>(order, detail)))
: .filter(orderDetail -> orderDetail.getT2().getAmount() > 5)
: .map(orderDetail -> new Pair<>(orderDetail, orderDetail.getT2().getProduct()))
: .forEach(product -> {
: });
: 另一種就是醜一點,巢狀 stream,但程式碼就更難讀@@...
: orders.stream()
: .forEach(order -> order.getOrdertails()
: .stream()
: .filter(orderDetail -> orderDetail.getAmount() > 5)
: .forEach(orderDetail -> {
: }));
: koji
作者: james732 (好人超)   2015-10-14 11:06:00
推良葛格
作者: swpoker (swpoker)   2015-10-14 15:20:00
其實都lambda 當然函式也要匿名阿
作者: Argosde   2015-10-15 22:36:00
order 1-n* orderDetail 1-1* productfilter會變成 getOrderdetails().stream().anyMatch(...)這樣filter會篩選到orderDetails嗎?

Links booklink

Contact Us: admin [ a t ] ucptt.com