Statistik Ringkasan Streaming – beragampengetahuan

 – Beragampengetahuan
8 mins read

Statistik Ringkasan Streaming – beragampengetahuan – Beragampengetahuan

Agar dapat memanfaatkan berbagai kemampuan Java Streams, pertama-tama Anda harus memahami dua konsep umum — aliran dan aliran pipa. Aliran di Jawa adalah aliran data berurutan. Di sisi lain, pipa streaming mewakili urutan langkah-langkah yang diterapkan pada data, urutan langkah-langkah yang pada akhirnya menghasilkan suatu hasil.

Saya dan keluarga saya baru-baru ini mengunjungi Legoland Resort di Jerman – omong-omong, tempat yang bagus – di mana, di antara atraksi lainnya, kami memiliki kesempatan untuk mengamati sampel proses peletakan batu bata secara mendetail. Singkatnya, semuanya dimulai dengan plastik pelet, yang dilebur, dimodelkan sesuai, dirakit, dicat, distensil (jika perlu), dan dikemas dalam tas dan kotak. Semua langkah adalah bagian dari pipa pabrik perakitan.

Perlu disebutkan bahwa langkah selanjutnya hanya dapat dilakukan setelah langkah sebelumnya selesai, dan jumlah langkah dibatasi. Selain itu, di setiap langkah, setiap elemen LEGO disentuh untuk melakukan tindakan yang sesuai, lalu hanya bergerak maju, bukan mundur, untuk menyelesaikan langkah berikutnya. Hal yang sama berlaku untuk aliran Java.

Dalam pemrograman fungsional, langkah-langkah ini disebut operasi aliran, dan terbagi dalam tiga kategori: yang memulai pekerjaan (sumber), yang mengakhiri pekerjaan dan menghasilkan hasil (terminal), dan beberapa pekerjaan perantara di antaranya.

Sebagai pertimbangan terakhir, perlu disebutkan bahwa operasi perantara mampu mengubah aliran menjadi aliran lain, tetapi tidak akan berjalan hingga operasi terminal berjalan (dievaluasi dengan malas). Akhirnya, setelah hasil dihasilkan dan rentang awal tercapai, aliran tidak valid lagi.

Contents

Abstrak

Mengambil Java Streams sebagai contoh, setelah operasi aliran terminal selesai, aliran tidak lagi valid, makalah ini bertujuan untuk mengusulkan metode untuk menghitung beberapa operasi secara bersamaan dengan hanya satu traversal aliran.Ini dicapai dengan memanfaatkan objek statistik ringkasan Java (khususnya IntSummaryStatistics) telah ada sejak versi 1.8.

bukti dari konsep

Proyek kecil ini dibangun khusus untuk mendemonstrasikan perhitungan statistik menggunakan:

  • Jawa 17
  • Maven 3.6.3
  • Mesin JUnit Jupiter v.5.9.3

Sebagai domain, ada satu entitas sederhana – induk.

public record Parent(String name, int age) { }

Itu dimodelkan oleh dua properti – nama dan usia. Sementara nama ada hanya untuk membedakan orang tua, usia adalah yang menarik di sini.

Tujuannya agar dapat menghitung beberapa statistik umur untuk sekumpulan orang tua, yaitu:

  • ukuran sampel keseluruhan
  • Usia orang tua termuda dan tertua.
  • Rentang usia grup.
  • umur rata-rata
  • Jumlah total tahun yang diakumulasikan oleh orang tua.

Hasilnya dikemas sebagai ParentStats Struktur juga direpresentasikan sebagai catatan.

public record ParentStats(long count,
                          int youngest,
                          int oldest,
                          int ageRange,
                          double averageAge,
                          long totalYearsOfAge) { }

Untuk mencapai ini, antarmuka didefinisikan.

public interface Service {
 
    ParentStats getStats(List<Parent> parents);
}

Saat ini, hanya ada satu metode untuk menerima masukan dari daftar Parents dan berikan statistik yang diinginkan sebagai output.

implementasi awal

Karena masalahnya sepele, implementasi awal dan wajib dari suatu layanan mungkin terlihat seperti ini:

public class InitialService implements Service {
 
    @Override
    public ParentStats getStats(List<Parent> parents) {
        int count = parents.size();
        int min = Integer.MAX_VALUE;
        int max = 0;
        int sum = 0;
        for (Parent human : parents) {
            int age = human.age();
            if (age < min) {
                min = age;
            }
            if (age > max) {
                max = age;
            }
            sum += age;
        }
 
        return new ParentStats(count, min, max, max - min, (double) sum/count, sum);
    }
}

Kode terlihat jelas, tetapi tampaknya terlalu fokus pada “bagaimana” daripada “apa”; dengan demikian, masalah tampaknya hilang dalam penerapannya, dan kode sulit dibaca.

Karena gaya dan aliran fungsional sudah menjadi bagian dari praktik setiap pengembang Java, kemungkinan implementasi layanan berikutnya akan dipilih.

public class StreamService implements Service {
 
    @Override
    public ParentStats getStats(List<Parent> parents) {
        int count = parents.size();
 
        int min = parents.stream()
                .mapToInt(Parent::age)
                .min()
                .orElseThrow(RuntimeException::new);
 
        int max = parents.stream()
                .mapToInt(Parent::age)
                .max()
                .orElseThrow(RuntimeException::new);
 
        int sum = parents.stream()
                .mapToInt(Parent::age)
                .sum();
 
        return new ParentStats(count, min, max, max - min, (double) sum/count, sum);
    }
}

Kode sekarang lebih mudah dibaca; tetapi sisi negatifnya adalah traversal aliran untuk menghitung semua statistik yang diperlukan adalah mubazir – tiga kali lipat dalam kasus khusus ini. Seperti disebutkan di awal artikel, setelah operasi terminal selesai – min, maks, jumlah – Aliran tidak lagi valid. Akan sangat berguna untuk dapat menghitung statistik target tanpa harus mengulang daftar orang tua beberapa kali.

Ringkasan Implementasi Statistik

Di Jawa, ada serangkaian objek yang disebut SummaryStatistics yang terdiri dari berbagai jenis – IntSummaryStatistics, LongSummaryStatistics, DoubleSummaryStatistics.

Menurut JavaDoc, IntSummaryStatistics adalah “objek status untuk mengumpulkan statistik seperti jumlah, min, maks, jumlah, dan rata-rata. Kelas ini dimaksudkan untuk digunakan dengan (meskipun tidak diperlukan untuk) aliran”.

Ini adalah kandidat yang baik untuk tujuan awal; oleh karena itu, implementasi layanan berikut tampaknya lebih disukai.

public class StatsService implements Service {
 
    @Override
    public ParentStats getStats(List<Parent> parents) {
        IntSummaryStatistics stats = parents.stream()
                .mapToInt(Parent::age)
                .summaryStatistics();
 
        return new ParentStats(stats.getCount(),
                stats.getMin(),
                stats.getMax(),
                stats.getMax() - stats.getMin(),
                stats.getAverage(),
                stats.getSum());
    }
}

Hanya ada satu aliran induk, statistik dihitung, dan kali ini kodenya dapat dibaca.

Untuk memeriksa ketiga implementasi, pengujian unit dasar abstrak berikut digunakan.

abstract class ServiceTest {
 
    private Service service;
 
    private List<Parent> mothers;
    private List<Parent> fathers;
    private List<Parent> parents;
 
    protected abstract Service setupService();
 
    @BeforeEach
    void setup() {
        service = setupService();
 
        mothers = IntStream.rangeClosed(1, 3)
                .mapToObj(i -> new Parent("Mother" + i, i + 30))
                .collect(Collectors.toList());
 
        fathers = IntStream.rangeClosed(4, 6)
                .mapToObj(i -> new Parent("Father" + i, i + 30))
                .collect(Collectors.toList());
 
        parents = new ArrayList<>(mothers);
        parents.addAll(fathers);
    }
 
    private void assertParentStats(ParentStats stats) {
        Assertions.assertNotNull(stats);
        Assertions.assertEquals(6, stats.count());
        Assertions.assertEquals(31, stats.youngest());
        Assertions.assertEquals(36, stats.oldest());
        Assertions.assertEquals(5, stats.ageRange());
 
        final int sum = 31 + 32 + 33 + 34 + 35 + 36;
 
        Assertions.assertEquals((double) sum/6, stats.averageAge());
        Assertions.assertEquals(sum, stats.totalYearsOfAge());
    }
 
    @Test
    void getStats() {
        final ParentStats stats = service.getStats(parents);
        assertParentStats(stats);
    }
}

Karena statistik dihitung untuk semua orang tua, ibu dan ayah pertama-tama dimasukkan ke dalam daftar orang tua yang sama (nanti kita akan melihat mengapa ada dua daftar).

Tes unit spesifik untuk setiap implementasi sederhana – ini menyiapkan instance layanan.

class StatsServiceTest extends ServiceTest {
 
    @Override
    protected Service setupService() {
        return new StatsService();
    }
}

Gabungkan Statistik

Selain metode yang sudah digunakan – getMin(), getMax(), getCount(), getSum(), getAverage()IntSummaryStatistics Menyediakan cara untuk menggabungkan status objek serupa lainnya ke dalam objek saat ini.

void combine(IntSummaryStatistics other)

Seperti yang dapat kita lihat pada pengujian unit di atas, awalnya ada dua daftar sumber − ibu Dan ayah. Akan sangat berguna untuk dapat menghitung statistik secara langsung tanpa menggabungkannya terlebih dahulu.

Untuk mencapai ini, layanan diperkaya dengan metode berikut.

default ParentStats getCombinedStats(List<Parent> mothers, List<Parent> fathers) {
    final List<Parent> parents = new ArrayList<>(mothers);
    parents.addAll(fathers);
    return getStats(parents);
}

Dua implementasi pertama − InitialService Dan StreamService – tidak menarik di sini; oleh karena itu, implementasi default disediakan untuk kenyamanan.itu hanya ditutupi StatsService.

@Override
public ParentStats getCombinedStats(List<Parent> mothers, List<Parent> fathers) {
    Collector<Parent, ?, IntSummaryStatistics> collector = Collectors.summarizingInt(Parent::age);
 
    IntSummaryStatistics stats = mothers.stream().collect(collector);
    stats.combine(fathers.stream().collect(collector));
 
    return new ParentStats(stats.getCount(),
            stats.getMin(),
            stats.getMax(),
            stats.getMax() - stats.getMin(),
            stats.getAverage(),
            stats.getSum());
}

dengan menggunakan combine() metode, karena daftar sumber yang berbeda dapat digunakan, statistik dapat digabungkan secara langsung.

Tes unit yang sesuai sederhana.

@Test
void getCombinedStats() {
    final ParentStats stats = service.getCombinedStats(mothers, fathers);
    assertParentStats(stats);
}

Setelah membaca materi di atas Collectorawal getStats() Metode dapat ditulis lebih singkat.

@Override
public ParentStats getStats(List<Parent> parents) {
    IntSummaryStatistics stats = parents.stream()
            .collect(Collectors.summarizingInt(Parent::age));
 
    return new ParentStats(stats.getCount(),
            stats.getMin(),
            stats.getMax(),
            stats.getMax() - stats.getMin(),
            stats.getAverage(),
            stats.getSum());
}

Kesimpulannya

Tergantung pada tipe data yang digunakan, IntSummaryStatistics, LongSummaryStatistics atau DoubleSummaryStatistics adalah konstruksi out-of-the-box yang nyaman untuk menghitung statistik sederhana dengan cepat dan berfokus pada penulisan kode yang lebih mudah dibaca dan dipelihara.

rencana pengembangan website



metode pengembangan website

jelaskan beberapa rencana untuk pengembangan website, proses pengembangan website, kekuatan dan kelemahan bisnis pengembangan website
, jasa pengembangan website, tahap pengembangan website, biaya pengembangan website

#Statistik #Ringkasan #Streaming #beragampengetahuan

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *