Java Generics Get ve Put Prensibi

Java Generics and Collections kitabında Get and Put isminde bir prensipden bahsediliyor. Java Generics wildcard kullanımı bu prensip takip edildiğinde daha kolaylaşıyor. Prensip şöyle:

Eğer bir yapıdan (liste, map vs.) nesne ediniyorsanız (get) extends wildcard, bir yapıya nesne ekliyorsanız (put) super wildcard kullanın. Bir yapı üzerinde bu iki işlemi birden yapıyorsanız, o zaman wildcard kullanmayın.

Bunu bir örnek ile açıklayalım. Aşağıdaki metot bir listeden diğer bir listeye nesneleri kopyalamak için kullanılan jenerik bir metot.

public static <T> void copy(List<? super T> dest, List<? extends T> src) {
	for (int i = 0; i < src.size(); i++) {
		dest.set(i, src.get(i));
	}
}

copy metodunun ilk parametresi nesnelerin kopyalanacağı, yani put yapılacak olan liste, ikinci parametresi nesnelerin alındığı, yani get edildiği liste. Şu şekilde bir listeyi diğer bir listeye kopyalayabiliriz:

List<Object> objs = Arrays.<Object>asList("String", 1, 3.14);
List<Integer> ints = Arrays.<Integer>asList(1,2);
copy(objs, ints);

dest isimli parametre put işlemi yapıldığı için super wildcard’ını, src isimli parametre get yapıldığı için extends wildcard’ını kullanıyor.

Bir iterator kullanıldığında bir yapıdan get işlemi ile değerler edinilir. Bu durumda extends wildcard kullanılmalı. Aşağıdaki örnekte sum metodu bir listede yer alan Number sınıfı ve altsınıflarından oluşan nesnelerin değerlerini topluyor. Buna göre bu metodu sum(Arrays. asList(1, 2)) ya da sum(Arrays. asList(1.1, 2.2)) şeklinde koşturmak mümkün. Eğer extends wildcard kullanılmasaydı Integer ya da Double nesneler ihtiva eden bir listeyi sum metoduna parametre olarak vermek mümkün olmazdı.

public static double sum(Collection<? extends Number> nums) {
	double s = 0.0;
	for (Number num : nums)
		s += num.doubleValue();
	return s;
}

EOF (End Of Fun)
Özcan Acar

Share Button
0.00 avg. rating (0% score) - 0 votes

2 Comments

  • Tarık

    01 Şubat 2013

    Hocam .NET’e gelin rahat edin :) 400 küsür JVM dili arasında boğulmayın :)

    Yukarıdaki bi dolu kodun C# daki çözümünü vermek isterim ;

    public static class Foo
    {
    public static decimal? Sum(IEnumerable items)
    {
    return items.Sum(x => x as decimal?);
    }
    }

  • Özcan Acar

    01 Şubat 2013

    Java 8 ile Java diline lambda, diger adi ile Closure yapilari eklenecek. Tasarimcilari örnek olarak C# dilini almislar. Java 8 ile ayni seyi Java dilinde de yapmak mümkün olacak.

Bir cevap yazın