Java Academy · Ders

Özel Bir Toplayıcı Oluşturma

Alana özgü bir kullanım durumu için yeniden kullanılabilir bir toplama işlemi oluşturmak üzere Collector arayüzünü uygulayın.

4. ders / 413 adım

Özel Bir Toplayıcı Oluşturma, CoddyKit'te ücretsiz bir Java Academy dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Java Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Java Academy kursu toplamda 4 dersten oluşur.

Özel Bir Toplayıcı Neden Oluşturulur?

Yerleşik toplayıcılar alanınıza uygun olmadığında, yeniden kullanılabilir ve birleştirilebilir toplama mantığı oluşturmak için Collector<T, A, R> arayüzünü uygulayın. T=girdi, A=değiştirilebilir biriktirici, R=sonuç.

Collector Arayüzü

Bir Collector beş bileşene sahiptir:

  • supplier() — başlangıç biriktiricisini oluşturur
  • accumulator() — bir öğeyi biriktiriciye ekler
  • combiner() — iki biriktiriciyi birleştirir (paralel stream'ler için)
  • finisher() — biriktiriciyi nihai sonuca dönüştürür
  • characteristics() — optimizasyon ipuçları sağlar

Collector.of() Fabrikası

Özel bir toplayıcı oluşturmanın en kolay yolu, arayüzü doğrudan uygulamadan Collector.of() kullanmaktır:

import java.util.stream.*;

// Collector that builds a comma-separated String
Collector<String, StringBuilder, String> csvCollector = Collector.of(
    StringBuilder::new,                     // supplier
    (sb, s) -> {
        if (sb.length() > 0) sb.append(',');
        sb.append(s);
    },                                       // accumulator
    (a, b) -> {
        if (a.length() > 0 && b.length() > 0) a.append(',');
        a.append(b); return a;
    },                                       // combiner
    StringBuilder::toString                  // finisher
);

String csv = Stream.of("Alice","Bob","Carol").collect(csvCollector);
System.out.println(csv); // Alice,Bob,Carol

Özel Toplayıcı: TopN

Bir karşılaştırıcıya göre yalnızca en iyi N öğeyi tutan bir toplayıcı oluşturun:

import java.util.*;
import java.util.stream.*;

static <T> Collector<T, ?, List<T>> topN(int n, Comparator<T> comp) {
    return Collector.of(
        () -> new ArrayList<T>(),
        (list, e) -> {
            list.add(e);
            list.sort(comp.reversed());
            if (list.size() > n) list.remove(list.size() - 1);
        },
        (a, b) -> {
            a.addAll(b);
            a.sort(comp.reversed());
            while (a.size() > n) a.remove(a.size() - 1);
            return a;
        },
        Collector.Characteristics.UNORDERED
    );
}

TopN Toplayıcısını Kullanma

Özel TopN toplayıcısını bir stream üzerinde uygulayın:

List<Integer> top3 = Stream.of(5,2,9,1,7,3,8)
    .collect(topN(3, Comparator.naturalOrder()));
System.out.println(top3); // [9, 8, 7]

Özellik Bayrakları

Üç isteğe bağlı özellik, stream optimizasyonunu ayarlar:

  • IDENTITY_FINISH — finisher özdeşlik dönüşümüdür; atlanabilir
  • UNORDERED — sonuç sırasının önemi yoktur
  • CONCURRENT — biriktirici eşzamanlı olarak çağrılabilir

Yanlış bayrağın ayarlanması (ör. iş parçacığı güvenliği olmadan CONCURRENT kullanılması) hatalara yol açar.

Özel Toplayıcı: Çalışan Ortalama

İkinci bir geçiş yapmadan çalışan bir ortalama tutun:

record RunningAvg(long count, double sum) {
    RunningAvg add(double v) { return new RunningAvg(count+1, sum+v); }
    RunningAvg merge(RunningAvg o) { return new RunningAvg(count+o.count, sum+o.sum); }
    double avg() { return count == 0 ? 0 : sum / count; }
}

Collector<Double, RunningAvg[], Double> avgCollector = Collector.of(
    () -> new RunningAvg[]{new RunningAvg(0, 0)},
    (a, v) -> a[0] = a[0].add(v),
    (a, b) -> { a[0] = a[0].merge(b[0]); return a; },
    a -> a[0].avg()
);

double avg = Stream.of(10.0, 20.0, 30.0).collect(avgCollector);
System.out.println(avg); // 20.0

Collector Arayüzünü Doğrudan Uygulama

Daha fazla denetim için Collector<T,A,R> arayüzünü bir sınıf olarak uygulayın:

import java.util.function.*;
import java.util.stream.*;

class StringJoiningCollector implements Collector<String, List<String>, String> {
    private final String delimiter;
    StringJoiningCollector(String delimiter) { this.delimiter = delimiter; }
    public Supplier<List<String>> supplier() { return ArrayList::new; }
    public BiConsumer<List<String>, String> accumulator() { return List::add; }
    public BinaryOperator<List<String>> combiner() {
        return (a,b) -> { a.addAll(b); return a; };
    }
    public Function<List<String>, String> finisher() {
        return list -> String.join(delimiter, list);
    }
    public Set<Characteristics> characteristics() { return Set.of(); }
}

Özel ve Yerleşik Toplayıcıların Karşılaştırılması

Özel bir toplayıcı yazmadan önce, yerleşik toplayıcıları birleştirerek aynı sonucu elde edip edemeyeceğinizi kontrol edin; bunlar zaten test edilmiş ve optimize edilmiştir:

// Instead of custom, compose:
Map<String, IntSummaryStatistics> stats = orders.stream().collect(
    Collectors.groupingBy(Order::status,
        Collectors.summarizingInt(Order::amount))
);
// This replaces many custom collector implementations

Özel Toplayıcılarda İş Parçacığı Güvenliği

CONCURRENT özelliği ayarlanırsa biriktirici aynı anda birden çok iş parçacığından çağrılır. Bu durumda biriktirici iş parçacığı güvenli olmalıdır (ör. ConcurrentHashMap veya AtomicLong kullanın). CONCURRENT kullanılmadığında birleştirici paralelliği güvenli biçimde yönetir.

Gerçek Kullanım Örneği: Histogram Toplayıcısı

Sayısal değerleri bir histogram eşleminde aralıklara ayırın:

Collector<Integer, Map<Integer, Long>, Map<Integer, Long>> histogram =
    Collector.of(
        LinkedHashMap::new,
        (map, val) -> map.merge(val / 10 * 10, 1L, Long::sum),
        (a, b) -> { b.forEach((k,v) -> a.merge(k,v,Long::sum)); return a; },
        Collector.Characteristics.IDENTITY_FINISH
    );

Map<Integer,Long> hist = Stream.of(5,15,25,12,8,22,18,3)
    .collect(histogram);
hist.forEach((bucket, cnt) -> System.out.println(bucket+"-"+(bucket+9)+": "+cnt));

Hızlı Kontrol

Hangi Collector.Characteristics bayrağı, finisher işlevinin özdeşlik dönüşümü olduğunu ve atlanabileceğini belirtir?

Özet: Özel Toplayıcılar

Temel çıkarımlar:

  • Collector<T,A,R>: T=girdi, A=biriktirici, R=sonuç
  • Bir sınıf kullanmadan hızlı bir uygulama için Collector.of() kullanın
  • supplier/accumulator/combiner/finisher/characteristics beş bileşendir
  • IDENTITY_FINISH, UNORDERED, CONCURRENT optimizasyon bayraklarıdır
  • Yerleşik toplayıcıları birleştirmeyi tercih edin; yalnızca gerektiğinde özel toplayıcı kullanın
Başlamak ücretsiz

Yapay zeka eğitmeniyle Java öğren — ücretsiz

Tarayıcında gerçek kod yaz ve çalıştır, 7/24 yapay zeka eğitmeninden anında yardım al; web'de ya da uygulamada kaldığın yerden devam et.

Kurslar
104
Dersler
374

Sıkça Sorulan Sorular

“Özel Bir Toplayıcı Oluşturma” dersi ücretsiz mi?

Evet — “Özel Bir Toplayıcı Oluşturma” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Java Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Java Academy kursu toplamda 4 dersten oluşur.

“Özel Bir Toplayıcı Oluşturma” dersinde ne öğreneceğim?

Alana özgü bir kullanım durumu için yeniden kullanılabilir bir toplama işlemi oluşturmak üzere Collector arayüzünü uygulayın. Java Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

Java Academy öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te Java Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.

“Özel Bir Toplayıcı Oluşturma” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu Java Academy dersinde kod yazıp çalıştırabilir miyim?

Evet. Her Java Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. groupingBy: Öğeleri Sınıflandırma
  2. partitioningBy ve counting
  3. toMap, joining ve summarizing
  4. Özel Bir Toplayıcı Oluşturma
← Java Academy Sayfasına Dön