ระวังด้วยเมธอด Java Optional
แหล่งที่มา:
Dev.to ตาม Oracle วัตถุ
เสริมคือ "วัตถุคอนเทนเนอร์ที่อาจมีหรือไม่มีค่าที่ไม่ใช่ค่าว่าง" ตัวเลือกเสริมปรากฏครั้งแรกใน Java 8 และถูกใช้โดยทีม SpringBoot ในหลายโครงการ
การใช้งาน Optionalsที่พบบ่อยที่สุดคือในโปรเจ็กต์ Spring Data ลองดูอินเทอร์เฟซ JpaRepository และวิธีการตัวอย่าง ตัวอย่างเช่น เรามี อ็อบเจ็กต์
Userที่มี Id ประเภทจำนวนเต็ม และเรามี JpaRepository สำหรับมัน
@Repository
public interface IUserRepo extends JpaRepository<User, Integer>
{
Optional<User> findByUserName(String userName);
}
เราได้กำหนดวิธีการค้นหาผู้ใช้ตามชื่อของผู้ใช้และส่งกลับตัว
เลือกสำหรับ
User
เลือกวิธีการที่สะดวกได้
ตัวเลือกเพิ่มเติมรวมอยู่ในวิธีการต่างๆ มากมายที่ช่วยให้เราสามารถเขียนโค้ดที่ชัดเจนและอ่านง่าย
- แผนที่(..).หรือ(...)
- แผนที่(...).หรืออื่น(...)
- รายการทั้งหมดสามารถพบได้ในเอกสารประกอบของ Oracle
อย่างไรก็ตาม มีวิธีหนึ่งที่มีพฤติกรรมที่ไม่คาดคิดและเป็นอันตราย
พบกับวิธี 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ซึ่งใช้วิธีการของซัพพลายเออร์ในการดำเนินการ ถ้ามี
Optional อยู่
วิธีแสดงและรวมองค์ประกอบจากรายการใน Java
ที่มา:
DZone ในโพสต์นี้ คุณจะได้เรียนรู้วิธีการแสดงและสรุปจำนวนองค์ประกอบจากรายการใน Java การแมปรายการจากรายการ
หมายความว่าแต่ละรายการในรายการนั้นจะถูกแปลงเป็นออบเจ็กต์อื่น การรวมองค์ประกอบจากรายการหมายความว่าองค์ประกอบทั้งหมดจากรายการนั้นจะถูกรวมเป็นออบเจ็กต์เดียว ซึ่งไม่จำเป็นต้องเป็นประเภทเดียวกันกับออบเจ็กต์ดั้งเดิม สมมติว่าเรามีรายการคำสั่งซื้อ และแต่ละคำสั่งซื้อก็มีรายการสินค้า
record Order(String customer, List<Product> products) {
}
record Product(String brand, String modelName, BigDecimal price) {
}
คุณจะทำอย่างไรถ้าคุณต้องการทราบว่าเงินมาจากรายการสั่งซื้อเป็นจำนวนเท่าใด สำหรับคำสั่งซื้อแต่ละรายการ คุณจะต้องได้รับรายการผลิตภัณฑ์ที่มีอยู่ในนั้น และสำหรับผลิตภัณฑ์แต่ละรายการในรายการเหล่านี้ คุณจะต้องทราบต้นทุน หลังจากนั้น คุณต้องสรุปราคาเหล่านี้ทั้งหมด และนี่คือวิธีที่คุณจะได้ผลลัพธ์ เมื่อแปลข้างต้นเป็น
แผนที่ /
ลดคุณต้อง:
- จับคู่คำสั่งซื้อแต่ละรายการกับรายการผลิตภัณฑ์
- แสดงราคาสินค้าแต่ละรายการ
- รวมราคาทั้งหมดเข้าด้วยกัน
เรามาทำกันใน 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 และ ลด จะช่วยในกรณีที่คุณต้องการดึงข้อมูลจาก
Collection
GO TO FULL VERSION