JavaRush /Java Blog /Random-ID /Rehat kopi #108. 12 Kegunaan Umum Java Stream, Cara Menge...

Rehat kopi #108. 12 Kegunaan Umum Java Stream, Cara Mengevaluasi Alokasi Memori Objek di Java

Dipublikasikan di grup Random-ID

12 Cara Umum Menggunakan Java Stream

Sumber: Dev.to Java Streams API pertama kali muncul di Java 8. Tujuannya adalah untuk menyediakan cara yang lebih ringkas untuk melakukan operasi umum pada kumpulan objek. Selain itu, Java Streams API dapat digunakan untuk mengimplementasikan algoritma yang kompleks. Pada artikel ini, kita akan membahas tentang kasus penggunaan umum Java Streams. Rehat kopi #108.  12 Kegunaan Umum Java Stream, Cara Mengevaluasi Alokasi Memori Objek di Java - 1Pertama, mari kita perjelas beberapa hal mendasar:
  • stream() - membuat aliran dari koleksi.

  • collect() - mengumpulkan aliran ke dalam suatu objek. Sebuah objek dapat berupa koleksi, kelas primitif, atau kelas khusus.

  • Kolektor adalah kelas yang menyediakan (banyak) metode statis untuk mengumpulkan aliran.

Sekarang mari kita lihat beberapa kasus penggunaan Streams:

1. Penyaringan

  • Digunakan untuk menghapus nilai dari suatu Koleksi berdasarkan suatu kondisi.

  • Untuk memfilter elemen koleksi berdasarkan suatu kondisi, gunakan metode filter() . Hanya elemen yang cocok yang disimpan.

Contoh: hapus semua bilangan ganjil dari daftar.
List<Integer> evenNumbers = originalList.stream()
        .filter(n -> n % 2 == 0)
        .collect(Collectors.toList());

2. Pemrosesan awal

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

  • Metode map() digunakan untuk menerapkan fungsi ke setiap elemen koleksi dan mengembalikan kumpulan nilai terhitung yang baru.

Misalnya, mari kita ubah setiap nilai menjadi kuadratnya.
List<Integer> squares = originalList.stream()
        .map(n -> n * n)
        .collect(Collectors.toList());

3. Konversi

  • Berguna ketika kita ingin mengubah suatu koleksi menjadi koleksi lain.

  • Ada beberapa cara untuk mencapai hal ini.

Seperti disebutkan di atas, kita dapat menggunakan metode map() dancollect () untuk mengubah suatu koleksi menjadi koleksi lain.

Contoh 1: Membuat Peta dari Daftar.

Ubah daftar string menjadi peta string dan panjangnya.
Map<String, Integer> wordLengths = words.stream()
        .collect(Collectors.toMap(
                word -> word,
                word -> word.length()));

Contoh 2. Mengubah daftar menjadi kumpulan.

Ini adalah kasus penggunaan umum untuk menghapus duplikat. Selain itu, jika kita ingin memasukkan kembali elemen ke dalam daftar, kita dapat menggunakan metode stream() dancollect () dua kali . Misalnya, mari kita ubah daftar string menjadi daftar string 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. Mengubah daftar produk menjadi daftar namanya. (Perataan - Penyelarasan)

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

4. Pengurangan

  • Mengurangi Koleksi menjadi satu nilai.

  • Metode pengurangan() digunakan untuk menerapkan fungsi ke setiap elemen koleksi dan mengembalikan satu nilai.

Perhatikan bahwa karena metode pengurangan() mengembalikan nilai tunggal, maka metode tersebut tidak dapat digunakan untuk mengembalikan Koleksi. Contoh, kami menjumlahkan semua nilai dalam daftar:
int sum = numbers.stream()
        .reduce(0, (a, b) -> a + b);

5. Pengelompokan

  • Mengelompokkan elemen Koleksi berdasarkan kondisi tertentu.

  • Untuk mengelompokkan elemen Koleksi berdasarkan kondisi, gunakan metode Collectors.groupingBy() .

Misalnya, mari kelompokkan semua produk ke dalam daftar produk berdasarkan kategorinya.
Map<String, List<Product>> productsByCategory = products.stream()
        .collect(Collectors.groupingBy(product -> product.getCategory()));

6. Menemukan

  • Mencari elemen Koleksi pertama atau apa pun yang cocok dengan suatu kondisi.

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

Ini biasanya mirip dengan pencarian linier. Misalnya kita mencari kata pertama dalam daftar yang panjangnya melebihi 5 karakter.
Optional<String> firstLongWord = words.stream()
        .filter(word -> word.length() > 5)
        .findFirst();
// Note that findFirst() and findAny() methods return Optional<T> objects.

7. Penyortiran

  • Mengurutkan elemen Koleksi.

  • Metode sortir() digunakan untuk menyortir .

Secara umum, Collections.sort() cukup untuk mengurutkan koleksi. Kita dapat menggunakan disortir() secara khusus jika kita ingin menjalankan operasi lain. Misalnya, mari kita urutkan daftar angka dalam urutan menaik lalu kembalikan k elemen pertama.
List<Integer> topK = numbers.stream()
        .sorted()
        .limit(k)
        .collect(Collectors.toList());

8. Partisi

  • Memisahkan elemen Koleksi berdasarkan kondisi tertentu.

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

Pemisahan mirip dengan grup, hanya saja ia mengembalikan dua koleksi—satu untuk elemen yang cocok dengan kondisi dan satu lagi untuk elemen yang tidak cocok dengan kondisi. Misalnya, mari kita bagi siswa menjadi mereka yang lulus ujian dan mereka yang gagal.
Map<Boolean, List<Student>> passingFailing = students
        .stream()
        .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));

9. Menghitung

  • Menghitung jumlah elemen yang cocok dengan suatu kondisi.

  • Metode count() digunakan untuk menghitung jumlah elemen yang cocok dengan suatu kondisi .

Misalnya, hitung jumlah kata dalam daftar yang panjangnya melebihi 5 karakter.
long count = words.stream()
        .filter(word -> word.length() > 5)
        .count();

10. Jangkauan

  • Menciptakan serangkaian nilai.

  • Untuk membuat rentang nilai, gunakan metode range() .

Ada kelas khusus untuk membuat aliran jenis tertentu - IntStream , LongStream , DoubleStream dan Stream . Kelas-kelas ini berguna ketika bekerja dengan tipe numerik primitif. Untuk mengubah array menjadi aliran, gunakan Arrays.stream() . Misalnya, mari kita buat array angka dari 0 sampai 10.
int[] numbers = IntStream.range(0, 10).toArray();

11. Mencocokkan

  • Mencocokkan unsur suatu koleksi dengan predikat (kondisi).

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

Misalnya, mari kita periksa produk dengan harga lebih tinggi dari 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. Bergabung

  • Menggabungkan elemen koleksi menjadi string.

  • Untuk menggabungkan elemen koleksi menjadi string, gunakan metode Collectors.joining() .

Misalnya, mari kita gabungkan semua kata dalam daftar menjadi satu string.
String joinedWords = words.stream()
        .collect(Collectors.joining(" "));
Itu saja untuk skenario umum. Ada skenario lain yang kurang umum yang dapat Anda jelajahi sendiri:
  • Aliran Paralel;
  • Statistik;
  • Kolektor Kustom.

Manfaat Benang

  • Kode yang lebih ringkas—mengurangi jumlah kode yang diperlukan untuk memproses pengumpulan.

  • Lebih sedikit variabel perantara. Variabel intervening dapat menyebabkan terjadinya kesalahan. Semakin sedikit jumlahnya, semakin mudah untuk menghindari kesalahan yang tidak terduga.

  • Kode intuitif. Beberapa pengembang tidak akan setuju bahwa thread lebih intuitif dibandingkan metode lainnya. Namun, setelah kita terbiasa, metode ini menjadi jauh lebih intuitif dibandingkan metode lainnya.

Terima kasih telah membaca. Saya harap Anda menikmati artikel ini. Masih banyak lagi kasus di mana thread dapat digunakan yang tidak tercakup dalam topik ini. Jangan ragu untuk menambahkan skenario umum apa pun yang saya lewatkan.

Cara mengevaluasi alokasi memori suatu objek di Java

Sumber: DZone Artikel ini menunjukkan tiga cara paling terkenal untuk mengevaluasi alokasi memori suatu objek di Java.

Penilaian memori menggunakan Profiler

Cara termudah untuk memperkirakan memori beberapa objek adalah dengan melihat langsung ke memori JVM menggunakan profiler seperti Visual VM . Rehat kopi #108.  12 Kegunaan Umum Java Stream, Cara Mengevaluasi Alokasi Memori Objek di Java - 2Masalah dengan pendekatan ini adalah Anda perlu terhubung ke JVM yang sedang berjalan, yang mungkin tidak dapat dilakukan untuk lingkungan produksi karena alasan keamanan.

Penilaian memori menggunakan Instrumen

Cara lain untuk memperkirakan alokasi memori untuk objek tertentu adalah dengan menggunakan Instrumen. Secara sederhana, kita perlu membuat kelas dan mengkompilasinya menjadi JAR. Setelah membuat JAR, kita harus menjalankan JVM bersama dengan JAR tersebut. Anda dapat mengetahui lebih lanjut tentang metode ini di sini . Kelemahannya di sini adalah kebutuhan untuk menambahkan file jar tertentu ke JVM, yang mungkin tidak dapat diterima untuk produksi karena masalah keamanan atau terkait.

Penilaian memori menggunakan JOL Library

Sebagai pilihan lain, kita bisa menggunakan JOL Library . Ini adalah perpustakaan yang sangat kuat yang dapat memberikan perkiraan rinci tentang bobot suatu objek dan memori yang dialokasikan oleh sebuah instance objek. Untuk menggunakan perpustakaan, kita perlu menambahkan ketergantungan:
<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.16</version>
</dependency>
Setelah itu kita bisa menggunakannya seperti ini:
out.println(GraphLayout.parseInstance(myObject).totalSize() / 1024000d + " MB")

ObjectSizeCalculator dari arsip Twitter

Repositori GitHub publik Twitter memiliki kelas alat yang disebut ObjectSizeCalculator yang dapat memperkirakan alokasi memori untuk instance objek tertentu. Tidak memerlukan banyak memori atau waktu untuk menggunakannya. Proses evaluasi memakan waktu beberapa detik, bahkan untuk objek berukuran besar. Cara menggunakan kelas ini cukup sederhana:
ObjectSizeCalculator.getObjectSize(address)
Saya merekomendasikan metode ini, namun perlu diingat bahwa ini hanya didukung oleh Java Hotspot, OpenJDK, dan TwitterJDK.
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION