12 วิธีทั่วไปในการใช้ Java Streams
ที่มา: Dev.to Java Streams API ปรากฏตัวครั้งแรกใน Java 8 โดยมีวัตถุประสงค์คือเพื่อให้มีวิธีที่กะทัดรัดยิ่งขึ้นในการดำเนินการทั่วไปกับคอลเลกชันของอ็อบเจ็กต์ นอกจากนี้ Java Streams API ยังสามารถใช้เพื่อนำอัลกอริธึมที่ซับซ้อนไปใช้ได้อีกด้วย ในบทความนี้ เราจะพูดถึงกรณีการใช้งานทั่วไปของ Java Streams
-
stream() - สร้างกระแสจากคอลเลกชัน
-
collect() - รวบรวมกระแสเข้าสู่วัตถุ อ็อบเจ็กต์อาจเป็นคอลเล็กชัน คลาสดั้งเดิม หรือคลาสแบบกำหนดเอง
-
Collectorsเป็นคลาสที่ให้วิธีการคงที่ (มากมาย) สำหรับการรวบรวมสตรีม
1. การกรอง
-
ใช้เพื่อลบค่าออกจากคอลเลกชันตามเงื่อนไข
-
หากต้องการกรององค์ประกอบคอลเลกชันตามเงื่อนไข ให้ใช้เมธอดfilter() บันทึกเฉพาะองค์ประกอบที่ตรงกันเท่านั้น
List<Integer> evenNumbers = originalList.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
2. การประมวลผลล่วงหน้า
-
มีประโยชน์เมื่อจำเป็นต้องเปลี่ยนทุกค่าในคอลเลกชัน
-
เมธอดmap()ใช้เพื่อใช้ฟังก์ชันกับแต่ละองค์ประกอบของคอลเลกชันและส่งกลับคอลเลกชันใหม่ของค่าที่คำนวณได้
List<Integer> squares = originalList.stream()
.map(n -> n * n)
.collect(Collectors.toList());
3. การกลับใจใหม่
-
มีประโยชน์เมื่อเราต้องการแปลงคอลเลกชันเป็นคอลเลกชันอื่น
-
มีหลายวิธีในการบรรลุเป้าหมายนี้
ตัวอย่างที่ 1: สร้างแผนที่จากรายการ
แปลงรายการสตริงเป็นแผนผังของสตริงและความยาวMap<String, Integer> wordLengths = words.stream()
.collect(Collectors.toMap(
word -> word,
word -> word.length()));
ตัวอย่างที่ 2 การแปลงรายการเป็นชุด
นี่เป็นกรณีการใช้งานทั่วไปสำหรับการลบรายการที่ซ้ำกัน นอกจากนี้ หากเราต้องการนำองค์ประกอบกลับเข้าไปในรายการ เราสามารถใช้เมธอดstream()และcollect () สองครั้ง ตัวอย่างเช่น ลองแปลงรายการสตริงเป็นรายการสตริงเฉพาะ:// if we want to collect to a set
Set<String> uniqueWords = words.stream()
.collect(Collectors.toSet());
// OR
// if we want to start and end as a list
List<String> uniqueWords = words.stream()
.collect(Collectors.toSet()).stream().collect(Collectors.toList());
ตัวอย่างที่ 3 การแปลงรายการผลิตภัณฑ์ให้เป็นรายการชื่อ (แฟบ - การจัดตำแหน่ง)
List<String> productNames = products.stream()
.map(product -> product.getName())
.collect(Collectors.toList());
4. การลดลง
-
ลดการรวบรวมเป็นค่าเดียว
-
ลด ()วิธีการใช้เพื่อใช้ฟังก์ชันกับแต่ละองค์ประกอบของคอลเลกชันและส่งกลับค่าเดียว
int sum = numbers.stream()
.reduce(0, (a, b) -> a + b);
5. การจัดกลุ่ม
-
จัดกลุ่มองค์ประกอบของคอลเลกชันตามเงื่อนไขที่กำหนด
-
หากต้องการจัดกลุ่มองค์ประกอบ Collection ตามเงื่อนไข ให้ใช้เมธอดCollectors.groupingBy()
Map<String, List<Product>> productsByCategory = products.stream()
.collect(Collectors.groupingBy(product -> product.getCategory()));
6. การค้นหา
-
ค้นหาองค์ประกอบแรกหรือองค์ประกอบคอลเลกชันใดๆ ที่ตรงกับเงื่อนไข
-
เมธอด findFirst()และfindAny()ใช้สำหรับการค้นหา
Optional<String> firstLongWord = words.stream()
.filter(word -> word.length() > 5)
.findFirst();
// Note that findFirst() and findAny() methods return Optional<T> objects.
7. การเรียงลำดับ
-
เรียงลำดับองค์ประกอบของคอลเลกชัน
-
sorted()ใช้สำหรับการเรียงลำดับ
List<Integer> topK = numbers.stream()
.sorted()
.limit(k)
.collect(Collectors.toList());
8. การแบ่งพาร์ติชัน
-
แยกองค์ประกอบของคอลเลกชันตามเงื่อนไขที่กำหนด
-
เมธอด Collectors.partitioningBy()ใช้เพื่อแยกองค์ประกอบ
Map<Boolean, List<Student>> passingFailing = students
.stream()
.collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
9. การนับ
-
นับจำนวนองค์ประกอบที่ตรงกับเงื่อนไข
-
count()วิธีการใช้ในการนับจำนวนองค์ประกอบที่ตรงกับเงื่อนไข
long count = words.stream()
.filter(word -> word.length() > 5)
.count();
10. พิสัย
-
สร้างช่วงของค่า
-
หากต้องการสร้างช่วงของค่า ให้ใช้เมธอดrange()
int[] numbers = IntStream.range(0, 10).toArray();
11. การจับคู่
-
จับคู่องค์ประกอบของคอลเลกชันที่มีภาคแสดง (เงื่อนไข)
-
เมธอดเช่นanyMatch() , allMatch()และnoneMatch () ใช้เพื่อจับคู่องค์ประกอบคอลเลกชันกับเพรดิเคตและส่งกลับค่าบูลีน
// true when all elements match the predicate
boolean allMatch = products.stream()
.allMatch(product -> product.getPrice() > 10);
// true when any element matches the predicate
boolean anyMatch = products.stream()
.anyMatch(product -> product.getPrice() > 10);
// true when no elements match the predicate
boolean noneMatch = products.stream()
.noneMatch(product -> product.getPrice() > 10);
12. การเข้าร่วม
-
เชื่อมต่อองค์ประกอบของคอลเลกชันเข้ากับสตริง
-
หากต้องการรวมองค์ประกอบคอลเลกชันเข้ากับสตริง ให้ใช้เมธอดCollectors.joining()
String joinedWords = words.stream()
.collect(Collectors.joining(" "));
เพียงเท่านี้สำหรับสถานการณ์ทั่วไป มีสถานการณ์อื่นๆ ที่ไม่ธรรมดาอื่นๆ ที่คุณสามารถสำรวจได้ด้วยตัวเอง:
- ลำธารขนาน;
- สถิติ;
- นักสะสมแบบกำหนดเอง
ประโยชน์ของเธรด
-
รหัสที่กะทัดรัดยิ่งขึ้น—ลดจำนวนรหัสที่ต้องใช้ในการประมวลผลคอลเลกชัน
-
ตัวแปรกลางน้อยลง ตัวแปรแทรกแซงอาจทำให้เกิดข้อผิดพลาดเกิดขึ้นได้ ยิ่งมีน้อยเท่าไรก็ยิ่งหลีกเลี่ยงข้อผิดพลาดที่ไม่คาดคิดได้ง่ายขึ้นเท่านั้น
-
รหัสที่ใช้งานง่าย นักพัฒนาบางคนอาจไม่เห็นด้วยว่าเธรดนั้นใช้งานง่ายกว่าวิธีอื่น อย่างไรก็ตาม เมื่อเราคุ้นเคยกับมันแล้ว มันก็จะกลายมาเป็นสัญชาตญาณมากกว่าวิธีอื่นๆ
วิธีประเมินการจัดสรรหน่วยความจำของวัตถุใน Java
ที่มา: DZone บทความนี้แสดงสามวิธีที่รู้จักกันดีที่สุดในการประเมินการจัดสรรหน่วยความจำของอ็อบเจ็กต์ใน Javaการประเมินหน่วยความจำโดยใช้ Profiler
วิธีที่ง่ายที่สุดในการประมาณหน่วยความจำของอ็อบเจ็กต์บางตัวคือการมองเข้าไปในหน่วย ความ จำ JVM โดยตรงโดยใช้ตัวสร้างโปรไฟล์ เช่นVisual VM
การประเมินความจำโดยใช้เครื่องมือ
อีกวิธีในการประมาณหน่วยความจำที่จัดสรรสำหรับวัตถุที่กำหนดคือการใช้เครื่องมือ พูดง่ายๆ ก็คือ เราจำเป็นต้องสร้างคลาสและคอมไพล์มันลงใน JAR หลังจากสร้าง JAR แล้ว เราจะต้องดำเนินการ JVM ของเราพร้อมกับ JAR นั้น คุณสามารถหาข้อมูลเพิ่มเติมเกี่ยวกับวิธีการนี้ได้ที่นี่ ข้อเสียคือจำเป็นต้องเพิ่มไฟล์ jar เฉพาะลงใน JVM ซึ่งอาจไม่เป็นที่ยอมรับสำหรับการผลิตเนื่องจากปัญหาด้านความปลอดภัยหรือที่เกี่ยวข้องการประเมินหน่วยความจำโดยใช้ JOL Library
อีกทางเลือกหนึ่ง เราสามารถใช้JOL Libraryได้ นี่เป็นไลบรารีที่ทรงพลังมากซึ่งสามารถให้การประมาณน้ำหนักของวัตถุและหน่วยความจำที่จัดสรรโดยอินสแตนซ์ของวัตถุโดยละเอียดได้ ในการใช้ไลบรารี่ เราต้องเพิ่มการพึ่งพา:<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.16</version>
</dependency>
หลังจากนั้นเราสามารถใช้มันได้ดังนี้:
out.println(GraphLayout.parseInstance(myObject).totalSize() / 1024000d + " MB")
ObjectSizeCalculator จากไฟล์เก็บถาวร Twitter
พื้นที่เก็บ ข้อมูล GitHubสาธารณะ ของ Twitter มีคลาสเครื่องมือที่เรียกว่า ObjectSizeCalculatorซึ่งสามารถประมาณหน่วยความจำที่จัดสรรสำหรับอินสแตนซ์วัตถุที่กำหนดได้ มันไม่ต้องใช้หน่วยความจำหรือเวลามากนักในการใช้งาน กระบวนการประเมินใช้เวลาไม่กี่วินาที แม้แต่กับวัตถุขนาดใหญ่ก็ตาม การใช้คลาสนี้ค่อนข้างง่าย:ObjectSizeCalculator.getObjectSize(address)
ฉันแนะนำวิธีนี้ แต่โปรดจำไว้ว่า Java Hotspot, OpenJDK และ TwitterJDK รองรับเท่านั้น
GO TO FULL VERSION