JavaRush /จาวาบล็อก /Random-TH /คอฟฟี่เบรค #108. 12 การใช้งานทั่วไปของ Java Streams, วิธี...

คอฟฟี่เบรค #108. 12 การใช้งานทั่วไปของ Java Streams, วิธีประเมินการจัดสรรหน่วยความจำของวัตถุใน Java

เผยแพร่ในกลุ่ม

12 วิธีทั่วไปในการใช้ Java Streams

ที่มา: Dev.to Java Streams API ปรากฏตัวครั้งแรกใน Java 8 โดยมีวัตถุประสงค์คือเพื่อให้มีวิธีที่กะทัดรัดยิ่งขึ้นในการดำเนินการทั่วไปกับคอลเลกชันของอ็อบเจ็กต์ นอกจากนี้ Java Streams API ยังสามารถใช้เพื่อนำอัลกอริธึมที่ซับซ้อนไปใช้ได้อีกด้วย ในบทความนี้ เราจะพูดถึงกรณีการใช้งานทั่วไปของ Java Streams คอฟฟี่เบรค #108.  12 การใช้งานทั่วไปของ Java Streams, วิธีประเมินการจัดสรรหน่วยความจำของวัตถุใน Java - 1ก่อนอื่น เรามาทำความเข้าใจข้อมูลเบื้องต้นกันก่อน:
  • stream() - สร้างกระแสจากคอลเลกชัน

  • collect() - รวบรวมกระแสเข้าสู่วัตถุ อ็อบเจ็กต์อาจเป็นคอลเล็กชัน คลาสดั้งเดิม หรือคลาสแบบกำหนดเอง

  • Collectorsเป็นคลาสที่ให้วิธีการคงที่ (มากมาย) สำหรับการรวบรวมสตรีม

ตอนนี้เรามาดูกรณีการใช้งานบางส่วนสำหรับ Streams:

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. การกลับใจใหม่

  • มีประโยชน์เมื่อเราต้องการแปลงคอลเลกชันเป็นคอลเลกชันอื่น

  • มีหลายวิธีในการบรรลุเป้าหมายนี้

ตามที่กล่าวไว้ข้างต้น เราสามารถใช้เมธอด map()และcollect()เพื่อแปลงคอลเลกชันหนึ่งเป็นคอลเลกชันอื่นได้

ตัวอย่างที่ 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()ใช้สำหรับการค้นหา

ซึ่งมักจะคล้ายกับการค้นหาเชิงเส้น ตัวอย่างเช่น เรากำลังมองหาคำแรกในรายการซึ่งมีความยาวเกิน 5 ตัวอักษร
Optional<String> firstLongWord = words.stream()
        .filter(word -> word.length() > 5)
        .findFirst();
// Note that findFirst() and findAny() methods return Optional<T> objects.

7. การเรียงลำดับ

  • เรียงลำดับองค์ประกอบของคอลเลกชัน

  • sorted()ใช้สำหรับการเรียงลำดับ

โดยทั่วไปCollections.sort()ก็เพียงพอแล้วในการจัดเรียงคอลเลกชัน เราสามารถใช้sorted()โดยเฉพาะหากเราต้องการดำเนินการอื่น ตัวอย่างเช่น ลองเรียงลำดับรายการตัวเลขจากน้อยไปหามากแล้วส่งคืนองค์ประกอบ k แรก
List<Integer> topK = numbers.stream()
        .sorted()
        .limit(k)
        .collect(Collectors.toList());

8. การแบ่งพาร์ติชัน

  • แยกองค์ประกอบของคอลเลกชันตามเงื่อนไขที่กำหนด

  • เมธอด Collectors.partitioningBy()ใช้เพื่อแยกองค์ประกอบ

การแยกจะคล้ายกับกลุ่ม ยกเว้นว่าจะส่งกลับคอลเลกชัน 2 รายการ โดยรายการหนึ่งสำหรับองค์ประกอบที่ตรงกับเงื่อนไข และอีกรายการหนึ่งสำหรับองค์ประกอบที่ไม่ตรงกับเงื่อนไข ตัวอย่างเช่น แบ่งนักเรียนออกเป็นผู้ที่สอบผ่านและผู้ที่สอบไม่ผ่าน
Map<Boolean, List<Student>> passingFailing = students
        .stream()
        .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));

9. การนับ

  • นับจำนวนองค์ประกอบที่ตรงกับเงื่อนไข

  • count()วิธีการใช้ในการนับจำนวนองค์ประกอบที่ตรงกับเงื่อนไข

ตัวอย่างเช่น ลองนับจำนวนคำในรายการที่มีความยาวเกิน 5 ตัวอักษร
long count = words.stream()
        .filter(word -> word.length() > 5)
        .count();

10. พิสัย

  • สร้างช่วงของค่า

  • หากต้องการสร้างช่วงของค่า ให้ใช้เมธอดrange()

มีคลาสพิเศษสำหรับการสร้างสตรีมบางประเภท- IntStream , LongStream , DoubleStreamและStream คลาสเหล่านี้มีประโยชน์เมื่อทำงานกับประเภทตัวเลขพื้นฐาน หากต้องการแปลงอาร์เรย์เป็นสตรีม ให้ใช้Arrays.stream( ) ตัวอย่างเช่น ลองสร้างอาร์เรย์ของตัวเลขตั้งแต่ 0 ถึง 10
int[] numbers = IntStream.range(0, 10).toArray();

11. การจับคู่

  • จับคู่องค์ประกอบของคอลเลกชันที่มีภาคแสดง (เงื่อนไข)

  • เมธอดเช่นanyMatch() , allMatch()และnoneMatch () ใช้เพื่อจับคู่องค์ประกอบคอลเลกชันกับเพรดิเคตและส่งกลับค่าบูลีน

เช่น ลองตรวจสอบสินค้าที่มีราคาสูงกว่า 10
// 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 คอฟฟี่เบรค #108.  12 การใช้งานทั่วไปของ Java Streams, วิธีประเมินการจัดสรรหน่วยความจำของวัตถุใน Java - 2ปัญหาของแนวทางนี้คือคุณต้องเชื่อมต่อกับ JVM ที่กำลังรันอยู่ ซึ่งอาจเป็นไปไม่ได้สำหรับสภาพแวดล้อมการใช้งานจริงเนื่องจากเหตุผลด้านความปลอดภัย

การประเมินความจำโดยใช้เครื่องมือ

อีกวิธีในการประมาณหน่วยความจำที่จัดสรรสำหรับวัตถุที่กำหนดคือการใช้เครื่องมือ พูดง่ายๆ ก็คือ เราจำเป็นต้องสร้างคลาสและคอมไพล์มันลงใน 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 รองรับเท่านั้น
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION