generics etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
generics etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

11 Ocak 2021 Pazartesi

Generics ve Bounded Type

Giriş 
Eğer liste hem dolaşılacak hem de eklenecekse wildcard kullanılmaması gerekir. 

Örnek
Şöyle yaparız. count metodu listeye yeni eleman ekler, sum ise listeyi dolaşır. Dolayısıyla sadece Collection<Number> şeklinde kullanılır.
public static double sumCount(Collection<Number> nums, int n) {
  count(nums, n);
  return sum(nums);
}
Örnek - İçerideki Generic tip
Şöyle yaparız. Burada RandomizerEntry sınıfının kendisi de Generic tip. Dolayısıyla generic tipi de dışarından geçmek gerekiyor.
public class RandomizedWrapper<T>{

  final int upperBound = 100;
  final List<RandomizerEntry<T>> randomizeList;
  Map<Integer, RandomizerEntry<T>> randomizerMap;

    
  public RandomizedWrapper(final List<RandomizerEntry<T>> randomizeList) {

    this.randomizeList = randomizeList;
    this.randomizerMap = new HashMap<>();
  }


  public void create(){
    List<RandomizerEntry<Integer>> randomizerList = new ArrayList<>();
    //stuff here
    RandomizedWrapper wrapper = new RandomizedWrapper(randomizerList);//OK
  }
}

24 Eylül 2020 Perşembe

Generics ve Bounded Wildcard Denkliği

Giriş
1. Aynı şekilde tanımlanmış iki tane Generics + Bounded Wildcard denk değildir
2. Wildcard olmase bile aralarında kalıtım olan iki tane farklı tipin kullanıldığı generic tipler denk değildir. Örneğin Box<Number> ve Box<Integer> denk değildir.

Açıklaması şöyle.
The usage of two bounded wildcards with the same bound doesn't mean they are the same type.
Bir başka açıklama şöyle. Yani her extends vs kullanımı aynı ata tipi kullansa daha farklı şeyler olarak algılanır.
First of all, every single wildcard is captured, everywhere, by javac. In plain english: every time javac "sees" a wildcard it is going to transform that
Örnek
Şu kod derlenmez
void test(List<? extends Number> g1, List<? extends Number> g2) {
    g1 = g2;
}
Bu kod java açısında şunun aynıdır. X1 ve X2 birbirleriyle ilgisiz tiplerdir ve iki liste birbirine atanamazlar.
void test(List<X1>, List<X2>)
Örnek
Elimizde şöyle bir kod olsun
void  persistData(ActivityDao<? extends BaseActivity> activityDao,
                  Collection<? extends BaseActivity> data){
  ...
  activityDao.saveAll(data);
  ...  
}
Bu metod derleyici tarafından şöyle algılanır. Haliyle derlenmez
private void  persistData(ActivityDao<CAP#1-of-? extends BaseActivity> activityDao,
                         Collection<CAP#2-of-? extends BaseActivity> data){
  ...
  activityDao.saveAll(data);
  ...
}
Bunu düzeltmenin tek yolu şöyle. Burada extends kullanımı kaldırılıyor!
private <T extends BaseActivity> void  persistData(ActivityDao<T> activityDao,
                                                   Collection<T> col){
  ...
  activityDao.saveAll(col);
  ...
}
Örnek
İki listeyi birleştirmek için şöyle yaparız. Burda metod imzasında extends var ancak içeride yeni bir liste yaratılıyor.
List<Foo> collect( List<? extends Foo> a1, List<? extends Foo> a2 )
{
  List<Foo> collected = new ArrayList<>();
  collected.addAll( a1 );
  collected.addAll( a2 );
  return collected;
}
Şöyle yapsaydık kod derlenmezdi.
ArrayList<? extends Foo> subFoos = new ArrayList<>();
subFoos.add(new Foo());
subFoos.add(new Bar());
Şuna benzer bir bir hata alırız.
no suitable method found for add(Foo)
method java.util.Collection.add(capture#1 of ? extends Foo) is not applicable
(argument mismatch; Foo cannot be converted to capture#1 of ? extends Foo)

no suitable method found for add(Bar)
method java.util.Collection.add(capture#2 of ? extends Bar) is not applicable
(argument mismatch; Bar cannot be converted to capture#2 of ? extends Bar)