Rumah  >  Artikel  >  Java  >  Perkara Beri keutamaan kepada fungsi tanpa kesan sampingan dalam aliran

Perkara Beri keutamaan kepada fungsi tanpa kesan sampingan dalam aliran

WBOY
WBOYasal
2024-08-08 16:46:52663semak imbas

Item  Dê preferência às funções sem efeitos colaterais nas streams

Pengenalan menggunakan strim:

  • Pengguna baharu mungkin mendapati sukar untuk menyatakan pengiraan dalam saluran paip aliran.
  • Strim adalah berdasarkan pengaturcaraan berfungsi, menawarkan ekspresif, kelajuan dan kesejajaran.

Penstrukturan pengiraan:

  • Pengiraan struktur sebagai jujukan penjelmaan menggunakan fungsi tulen.
  • Fungsi tulen hanya bergantung pada inputnya dan tidak menukar keadaan.

Kesan sampingan:

  • Elakkan kesan sampingan dalam fungsi yang dihantar ke strim operasi.
  • Penggunaan forEach yang tidak betul yang mengubah keadaan luaran ialah "bau busuk".

Contoh 1: Kod dengan kesan sampingan

Map<String, Long> freq = new HashMap<>();
try (Stream<String> words = new Scanner(file).tokens()) {
    words.forEach(word -> {
        freq.merge(word.toLowerCase(), 1L, Long::sum);
    });
}

Masalah: Kod ini menggunakan forEach untuk mengubah suai keadaan luaran (freq). Ia berulang dan tidak mengambil kesempatan daripada strim.

Contoh 2: Kod tanpa kesan sampingan

Map<String, Long> freq;
try (Stream<String> words = new Scanner(file).tokens()) {
    freq = words.collect(Collectors.groupingBy(String::toLowerCase, Collectors.counting()));
}

Penyelesaian: Menggunakan Collectors.groupingBy collector untuk mencipta jadual kekerapan tanpa mengubah keadaan luaran. Lebih pendek, lebih jelas dan lebih cekap.

Peruntukan API strim:

  • Kod yang meniru gelung berulang tidak mengambil kesempatan daripada strim.
  • Gunakan pengumpul untuk operasi yang lebih cekap dan boleh dibaca.

Pengumpul:

  • Permudahkan pengumpulan hasil ke dalam koleksi seperti senarai dan set.
  • Collectors.toList(), Collectors.toSet(), Collectors.toCollection(collectionFactory).

Contoh 3: Mengekstrak senarai sepuluh perkataan yang paling kerap

List<String> topTen = freq.entrySet().stream()
    .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
    .limit(10)
    .map(Map.Entry::getKey)
    .collect(Collectors.toList());

Penjelasan:

  • Memesan entri peta kekerapan dalam tertib nilai menurun.
  • Menghadkan strim kepada 10 patah perkataan.
  • Mengumpul perkataan yang paling kerap dalam senarai.

Kerumitan API Pengumpul:

  • API mempunyai 39 kaedah, tetapi kebanyakannya adalah untuk kegunaan lanjutan.
  • Pengumpul boleh digunakan untuk membuat peta (toMap, groupingBy).

Peta dan strategi pengumpulan:

  • ke Peta(keyMapper, valueMapper) untuk nilai kunci unik.
  • Strategi untuk menangani konflik utama menggunakan fungsi gabungan.
  • mengumpulkan Mengikut untuk mengumpulkan elemen ke dalam kategori berdasarkan fungsi pengelas.

Contoh 4: Menggunakan toMap dengan fungsi gabungan

Map<String, Long> freq;
try (Stream<String> words = new Scanner(file).tokens()) {
    freq = words.collect(Collectors.toMap(
        String::toLowerCase, 
        word -> 1L, 
        Long::sum
    ));
}

Penjelasan:

  • untuk memetakan perkataan kepada frekuensinya.
  • Fungsi gabungan (Long::sum) menangani konflik utama dengan menjumlahkan frekuensi.

Contoh 5: Mengumpulkan album mengikut artis dan mencari album terlaris

Map<Artist, Album> topAlbums = albums.stream()
    .collect(Collectors.toMap(
        Album::getArtist,
        Function.identity(),
        BinaryOperator.maxBy(Comparator.comparing(Album::sales))
    ));

Penjelasan:

  • untuk memetakan artis ke album terlaris mereka.
  • BinaryOperator.maxBy menentukan album terlaris untuk setiap artis.

Koleksi rentetan:
Pengumpul.menyertai untuk menggabungkan rentetan dengan pembatas pilihan.

Contoh 6: Menggabungkan rentetan dengan pembatas

String result = Stream.of("came", "saw", "conquered")
    .collect(Collectors.joining(", ", "[", "]"));

Penjelasan:

  • Collectors.joining menggabungkan rentetan dengan koma sebagai pembatas, awalan dan akhiran.
  • Keputusan: [datang, melihat, ditakluki].

Kesimpulan:

  • Intipati aliran ada dalam fungsi tanpa kesan sampingan.
  • forEach hanya boleh digunakan untuk melaporkan keputusan.
  • Pengetahuan tentang pengumpul adalah penting untuk penggunaan strim yang berkesan.

Atas ialah kandungan terperinci Perkara Beri keutamaan kepada fungsi tanpa kesan sampingan dalam aliran. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn