JavaRush /Blog Java /Random-MS /Coffee break #108. 12 Kegunaan Biasa Java Stream, Cara Me...

Coffee break #108. 12 Kegunaan Biasa Java Stream, Cara Menilai Peruntukan Memori Objek dalam Java

Diterbitkan dalam kumpulan

12 Cara Biasa Menggunakan Java Stream

Sumber: Dev.to Java Streams API pertama kali muncul di Java 8. Tujuannya adalah untuk menyediakan cara yang lebih padat untuk melaksanakan operasi biasa pada koleksi objek. Selain itu, Java Streams API boleh digunakan untuk melaksanakan algoritma yang kompleks. Dalam artikel ini, kita akan bercakap tentang kes penggunaan biasa Java Streams. Coffee break #108.  12 Penggunaan Biasa Aliran Java, Cara Menilai Peruntukan Memori Objek dalam Java - 1Mula-mula, mari kita jelaskan beberapa asas:
  • stream() - mencipta aliran daripada koleksi.

  • collect() - mengumpul aliran ke dalam objek. Objek boleh menjadi koleksi, primitif atau kelas tersuai.

  • Pengumpul ialah kelas yang menyediakan (banyak) kaedah statik untuk mengumpul strim.

Sekarang mari kita lihat beberapa kes penggunaan untuk Strim:

1. Penapisan

  • Digunakan untuk mengalih keluar nilai daripada Koleksi berdasarkan syarat.

  • Untuk menapis elemen pengumpulan berdasarkan syarat, gunakan kaedah penapis() . Hanya elemen yang sepadan disimpan.

Contoh: keluarkan semua nombor ganjil daripada senarai.
List<Integer> evenNumbers = originalList.stream()
        .filter(n -> n % 2 == 0)
        .collect(Collectors.toList());

2. Prapemprosesan

  • Berguna apabila setiap nilai dalam koleksi perlu diubah pada tempatnya.

  • Kaedah map() digunakan untuk menggunakan fungsi pada setiap elemen koleksi dan mengembalikan koleksi nilai baru yang dikira.

Sebagai contoh, mari tukar setiap nilai kepada kuasa duanya.
List<Integer> squares = originalList.stream()
        .map(n -> n * n)
        .collect(Collectors.toList());

3. Penukaran

  • Berguna apabila kita ingin menukar koleksi kepada koleksi lain.

  • Terdapat beberapa cara untuk mencapai ini.

Seperti yang dinyatakan di atas, kita boleh menggunakan kaedah map() dan collect() untuk mengubah koleksi menjadi koleksi lain.

Contoh 1: Buat Peta daripada Senarai.

Tukar senarai rentetan kepada peta rentetan dan panjang.
Map<String, Integer> wordLengths = words.stream()
        .collect(Collectors.toMap(
                word -> word,
                word -> word.length()));

Contoh 2. Menukar senarai kepada set.

Ini ialah kes penggunaan biasa untuk mengalih keluar pendua. Selain itu, jika kita ingin memasukkan semula elemen ke dalam senarai, kita boleh menggunakan kaedah stream() dan collect() dua kali . Sebagai contoh, mari tukar senarai rentetan kepada senarai rentetan unik:
// 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());

Contoh 3. Menukar senarai produk kepada senarai nama mereka. (Meratakan - Penjajaran)

List<String> productNames = products.stream()
        .map(product -> product.getName())
        .collect(Collectors.toList());

4. Pengurangan

  • Mengurangkan Koleksi kepada satu nilai.

  • Kaedah reduce() digunakan untuk menggunakan fungsi pada setiap elemen koleksi dan mengembalikan nilai tunggal.

Ambil perhatian bahawa kerana kaedah reduce() mengembalikan nilai tunggal, ia tidak boleh digunakan untuk mengembalikan Koleksi. Sebagai contoh, kami meringkaskan semua nilai dalam senarai:
int sum = numbers.stream()
        .reduce(0, (a, b) -> a + b);

5. Pengelompokan

  • Himpunkan elemen Koleksi berdasarkan syarat yang diberikan.

  • Untuk mengumpulkan elemen Koleksi mengikut syarat, gunakan kaedah Collectors.groupingBy() .

Sebagai contoh, mari kumpulkan semua produk ke dalam senarai produk mengikut kategorinya.
Map<String, List<Product>> productsByCategory = products.stream()
        .collect(Collectors.groupingBy(product -> product.getCategory()));

6. Mencari

  • Mencari unsur Koleksi pertama atau mana-mana yang sepadan dengan syarat.

  • Kaedah findFirst() dan findAny() digunakan untuk mencari .

Ini biasanya serupa dengan carian linear. Sebagai contoh, kami sedang mencari perkataan pertama dalam senarai, yang panjangnya melebihi 5 aksara.
Optional<String> firstLongWord = words.stream()
        .filter(word -> word.length() > 5)
        .findFirst();
// Note that findFirst() and findAny() methods return Optional<T> objects.

7. Menyusun

  • Isih unsur Koleksi.

  • Kaedah sorted() digunakan untuk sorting .

Umumnya, Collections.sort() sudah memadai untuk mengisih koleksi. Kita boleh menggunakan sorted() secara khusus jika kita ingin menjalankan operasi lain. Sebagai contoh, mari kita mengisih senarai nombor dalam tertib menaik dan kemudian kembalikan elemen k pertama.
List<Integer> topK = numbers.stream()
        .sorted()
        .limit(k)
        .collect(Collectors.toList());

8. Pembahagian

  • Mengasingkan elemen Koleksi berdasarkan syarat tertentu.

  • Kaedah Collectors.partitioningBy() digunakan untuk memisahkan elemen .

Pemisahan adalah serupa dengan kumpulan, kecuali ia mengembalikan dua koleksi—satu untuk elemen yang sepadan dengan syarat dan satu untuk elemen yang tidak sepadan dengan syarat. Sebagai contoh, mari kita bahagikan pelajar kepada mereka yang lulus peperiksaan dan mereka yang gagal.
Map<Boolean, List<Student>> passingFailing = students
        .stream()
        .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));

9. Mengira

  • Mengira bilangan elemen yang sepadan dengan keadaan.

  • Kaedah count() digunakan untuk mengira bilangan elemen yang sepadan dengan keadaan .

Sebagai contoh, mari kita mengira bilangan perkataan dalam senarai yang panjangnya melebihi 5 aksara.
long count = words.stream()
        .filter(word -> word.length() > 5)
        .count();

10. Julat

  • Mencipta julat nilai.

  • Untuk mencipta julat nilai, gunakan kaedah julat() .

Terdapat kelas khas untuk mencipta strim jenis tertentu - IntStream , LongStream , DoubleStream dan Stream . Kelas ini berguna apabila bekerja dengan jenis angka primitif. Untuk menukar tatasusunan kepada aliran, gunakan Arrays.stream() . Sebagai contoh, mari kita buat susunan nombor dari 0 hingga 10.
int[] numbers = IntStream.range(0, 10).toArray();

11. Padanan

  • Memadankan unsur koleksi dengan predikat (keadaan).

  • Kaedah seperti anyMatch() , allMatch() , dan noneMatch() digunakan untuk memadankan elemen koleksi dengan predikat dan mengembalikan nilai boolean .

Sebagai contoh, mari semak produk dengan harga lebih tinggi daripada 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. Menyertai

  • Menggabungkan elemen koleksi ke dalam rentetan.

  • Untuk menggabungkan elemen koleksi ke dalam rentetan, gunakan kaedah Collectors.joining() .

Sebagai contoh, mari kita gabungkan semua perkataan dalam senarai menjadi satu rentetan.
String joinedWords = words.stream()
        .collect(Collectors.joining(" "));
Itu sahaja untuk senario umum. Terdapat senario lain yang kurang biasa yang boleh anda terokai sendiri:
  • Aliran Selari;
  • Statistik;
  • Pengumpul Tersuai.

Faedah Benang

  • Kod yang lebih padat—mengurangkan jumlah kod yang diperlukan untuk memproses koleksi.

  • Lebih sedikit pembolehubah perantaraan. Pembolehubah campur tangan boleh menyebabkan ralat berlaku. Semakin sedikit, semakin mudah untuk mengelakkan kesilapan yang tidak dijangka.

  • Kod intuitif. Sesetengah pembangun akan tidak bersetuju bahawa urutan lebih intuitif daripada kaedah lain. Walau bagaimanapun, apabila kita membiasakannya, ia menjadi lebih intuitif daripada kaedah lain.

Terima kasih kerana membaca. Saya harap anda menikmati artikel ini. Terdapat banyak lagi kes di mana benang boleh digunakan yang tidak diliputi dalam topik ini. Jangan ragu untuk menambah sebarang senario biasa yang saya terlepas.

Bagaimana untuk menilai peruntukan memori objek dalam Java

Sumber: DZone Artikel ini menunjukkan tiga cara paling terkenal untuk menilai peruntukan memori objek dalam Java.

Penilaian ingatan menggunakan Profiler

Cara paling mudah untuk menganggarkan memori sesetengah objek ialah melihat terus ke dalam memori JVM menggunakan profiler seperti Visual VM . Coffee break #108.  12 Penggunaan Biasa Aliran Java, Cara Menilai Peruntukan Memori Objek dalam Java - 2Masalah dengan pendekatan ini ialah anda perlu menyambung ke JVM yang sedang berjalan, yang mungkin tidak boleh dilakukan untuk persekitaran pengeluaran atas sebab keselamatan.

Penilaian ingatan menggunakan Instrumen

Satu lagi cara untuk menganggarkan memori yang diperuntukkan untuk objek tertentu ialah menggunakan Instrumen. Secara ringkas, kita perlu mencipta kelas dan menyusunnya ke dalam JAR. Selepas mencipta JAR, kami mesti melaksanakan JVM kami bersama-sama dengan JAR itu. Anda boleh mengetahui lebih lanjut mengenai kaedah ini di sini . Kelemahan di sini ialah keperluan untuk menambah fail balang tertentu pada JVM, yang mungkin tidak boleh diterima untuk pengeluaran disebabkan oleh keselamatan atau isu berkaitan.

Penilaian ingatan menggunakan Perpustakaan JOL

Sebagai pilihan lain, kita boleh menggunakan Perpustakaan JOL . Ini ialah perpustakaan yang sangat berkuasa yang boleh memberikan anggaran terperinci tentang berat objek dan memori yang diperuntukkan oleh contoh objek. Untuk menggunakan perpustakaan, kita perlu menambah kebergantungan:
<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.16</version>
</dependency>
Selepas itu kita boleh menggunakannya seperti ini:
out.println(GraphLayout.parseInstance(myObject).totalSize() / 1024000d + " MB")

ObjectSizeCalculator daripada arkib Twitter

Repositori GitHub awam Twitter mempunyai kelas alat yang dipanggil ObjectSizeCalculator yang boleh menganggarkan memori yang diperuntukkan untuk contoh objek tertentu. Ia tidak mengambil banyak memori atau masa untuk digunakan. Proses penilaian mengambil masa beberapa saat, walaupun untuk objek besar. Menggunakan kelas ini agak mudah:
ObjectSizeCalculator.getObjectSize(address)
Saya mengesyorkan kaedah ini, tetapi perlu diingat bahawa ia hanya disokong oleh Java Hotspot, OpenJDK dan TwitterJDK.
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION