Get rid of the cost of boxing/unboxing: Specialized Forms of Supplier<T> Functional Interface

Özge Odabaş
2 min readFeb 13, 2024

Java programlama dili, geniş bir kullanıcı kitlesi tarafından tercih edilen güçlü bir dildir. Ancak, performans endişeleri bazen geliştiricileri etkileyebilir. Bu endişelerden biri, sıklıkla kullanılan ancak performans maliyeti olan boxing ve unboxing işlemleridir. Boxing, ilkel veri türlerini (primitive types) sarmalayarak referans türlerine dönüştürürken, unboxing ise tam tersini yapar. Bu işlemler, özellikle yüksek hacimli veri manipülasyonunda performans kaybına neden olabilir. Java 8 ile birlikte tanıtılan Supplier<T> fonksiyonel arayüzü, bu maliyeti azaltmak veya tamamen ortadan kaldırmak için bir çözüm sunuyor. Bu yazıda, Supplier<T> interfaceinin nasıl kullanılabileceği ve boxing/unboxing maliyetlerinden nasıl kaçınılabileceğimizi inceleyeceğiz.

JDK 8 ile gelen java.util.function paketinde kullanıma sunulan fonksiyonel interfacelerden Supplier interfaceinin özelleştirilmiş türlerini kullancağız.

Bildiğimiz gibi bir supplier arguman alamaz ve dönüş tipi T’dir. Kullanması oldukça kolay bir interfacedir. Default ve static metodları bulunmaz, sadece get() metodu vardır.

//Supplier Interface Implementation
@FunctionalInterface
public interface Supplier<T> {

T get();
}

JDK’da bir lambda ifadesinin ne kadar hızlı yürütülebileceği kritik öneme sahiptir. Bu yüzden JDK API ayrıca Supplier<T> interfaceinin özelleştirilmiş ve optimize edilmiş sürümlerini de kullanıma sunuyor; IntSupplier, LongSupplier, BooleanSupplier ve DoubleSupplier.

IntSupplier

//auto-boxing
int i= 12;
Integer integer = i;

//auto-unboxing
Integer integer2= Integer.valueOf(12);
int i2= integer2;

Yukarıda görülen boxing/unboxing işlemlerinin uygulamarımız için bir maliyeti vardır. Çoğu zaman diğer işlemler kadar pahalı olmasa da bazen bu maliyetten kaçınmak isteyebiliriz.

Bu noktada kullanıma sunulan IntSupplier interfacei işimize yarayacaktır;

@FunctionalInterface
public interface IntSupplier {

int getAsInt();
}
//usage
Random random = new Random(314L);
IntSupplier newRandom = () -> random.nextInt();

for(int i=0; i<5;i++){
int nextRandom = newRandom.getAsInt();
System.out.println("new random integer is: " + nextRandom);
}

Görüldüğü gibi herhangi bir boxing/unboxing işlemi yapmamıza gerek kalmadı.

--

--

Özge Odabaş

Merhaba! Ben Özge. Junior Java Developerım. Kendimi geliştirirken edindiğim bilgileri yazıyorum. Keyifli okumalar.