Bölüm 5: Koleksiyonlar

Bölüm 5: Koleksiyonlar · Çalışma Soruları
Çerçeve ve jeneriklerArrayListStackArrayDequePriorityQueueKümelerEşlemelerIteratorCollectionsSeçim
Sercan KÜLCÜ

Çoktan Seçmeli · Koleksiyon Çerçevesi

Soru 1: Collection Ailesi

Aşağıdaki arayüzlerden hangisi Collection arayüzünü genişletmez?

C: Map anahtar-değer çiftleri tutar; Koleksiyon Çerçevesinin parçasıdır ama Collection'dan türemez ve Iterable değildir. Bu yüzden doğrudan for-each ile gezilemez; keySet(), values() ya da entrySet() kullanılır.

Çoktan Seçmeli · Koleksiyon Çerçevesi

Soru 2: Jenerik Tanım

Aşağıdaki satırlardan hangisi derlenir?

B: Tip argümanı bir referans tipi olmalıdır: int yerine sarmalayıcı Integer (A: unexpected type); int değerler otomatik kutulanır. Elmas <> yalnızca new tarafında yazılır (C). List bir arayüzdür, nesnesi oluşturulamaz (D: List is abstract; cannot be instantiated).

Adım Adım Çalıştırma · Listeler

Soru 3: ArrayList İşlemleri

Her işlemden sonra liste nasıl görünür? Program ne yazdırır? remove(2) ile remove(Integer.valueOf(10)) farkına dikkat edin.

100201302add(e) sona ekler

Üç add öğeleri eklenme sırasıyla sona koyar; int değerler Integer'a kutulanır.

100151202303add(1, 15)

add(1, 15) indis 1'e ekler; 20 ve 30 bir sağa kayar.

100151302remove(2): indis

Argüman int olduğu için remove(int index) çalışır: indis 2'deki 20 silinir, 30 sola kayar.

150301remove(Object): değer

Integer.valueOf(10) bir nesnedir: remove(Object) değeri 10 olan öğeyi siler.

990301set(0, 99)

set boyutu değiştirmez, indis 0'daki değeri değiştirir.

990301indexOf(30) = 1

30 indis 1'de; boyut 2.

List<Integer> l = new ArrayList<>();
l.add(10);
l.add(20);
l.add(30);
l.add(1, 15);
l.remove(2);
l.remove(Integer.valueOf(10));
l.set(0, 99);
System.out.println(l + " " + l.indexOf(30)
    + " " + l.size());

Çoktan Seçmeli · Listeler

Soru 4: Başa Ekleme

Bir listenin başına 100 000 öğe tek tek eklenecek: liste.add(0, x). Hangisi doğrudur?

D: ArrayList içte bir dizi kullanır: başa her ekleme tüm öğeleri bir sağa kaydırır, O(n); toplam O(n²). LinkedList'te yalnızca yeni düğüm baştaki düğüme bağlanır, O(1); kaydırma yoktur (C). Aynı arayüz aynı metotları sunar, aynı maliyeti değil (B). Uçlarda işlem için ArrayDeque da uygundur.

Çıktı Sorusu · Listeler

Soru 5: Stack

Program ne yazdırır?

Stack<Integer> y = new Stack<>();
y.push(4);
y.push(7);
y.push(1);
System.out.println(y.peek() + " " + y.search(4));
y.push(y.pop() + y.pop());
System.out.println(y + " " + y.size());
Cevabı göster
1 3
[4, 8] 2

peek() en üsttekini (1) çıkarmadan verir. search konumu üstten 1'den sayar: 1 → 1, 7 → 2, 4 → 3.

İlk pop() 1'i, ikincisi 7'yi çıkarır; Integer'lar toplanır (8) ve geri itilir. println yığını alttan üste yazar: [4, 8].

Adım Adım Çalıştırma · Kuyruklar

Soru 6: ArrayDeque İki Uç

Çift uçlu kuyruk iki uçtan da kullanılıyor. Her işlemden sonra baştan sona öğeler nedir, program ne yazdırır?

50başson

Boş deque'e 5 eklenir; tek öğe hem baş hem sondur.

8051başson

addFirst başa ekler.

208152başsonpush = addFirst

Yığın işlemleri baş uçta çalışır: push başa ekler.

20815273başsonoffer = offerLast

Kuyruk işlemi offer sona ekler.

208152başsonpollLast → 7

pollLast sondakini çıkarıp döndürür: a = 7.

8051başsonpop → 2

pop baştakini çıkarır: b = 2.

508152başsonpeekLast = 5

peekLast sondaki 5'i çıkarmadan okur; offerFirst onu başa ekler. Deque tekrarlı öğeye izin verir.

508152başson

Deque baştan sona yazılır; boyut 3.

Deque<Integer> d = new ArrayDeque<>();
d.addLast(5);
d.addFirst(8);
d.push(2);
d.offer(7);
int a = d.pollLast();
int b = d.pop();
d.offerFirst(d.peekLast());
System.out.println(d + " " + a + " " + b
    + " " + d.size());

Çoktan Seçmeli · Kuyruklar

Soru 7: Boş Kuyruk

Boş bir Queue<String> k = new LinkedList<>(); için hangisi doğrudur?

A: Queue her işlemi iki biçimde sunar: add/remove/element başarısızlıkta istisna fırlatır, offer/poll/peek özel değer (false/null) döndürür. Boş kuyrukta remove() ve element() NoSuchElementException fırlatır.

Çıktı Sorusu · Kuyruklar

Soru 8: PriorityQueue

Program ne yazdırır?

PriorityQueue<Integer> pq =
    new PriorityQueue<>();
for (int x : new int[]{5, 1, 4, 1, 3}) {
  pq.add(x);
}
System.out.println(pq.poll() + " " + pq.peek()
    + " " + pq.size());
pq.add(2);
StringBuilder sb = new StringBuilder();
while (!pq.isEmpty()) {
  sb.append(pq.poll()).append(' ');
}
System.out.println(sb);
Cevabı göster
1 1 4
1 2 3 4 5 

Öncelikli kuyruk eklenme sırasına değil değere bakar: poll her zaman en küçüğü çıkarır. Kuyruk küme değildir; iki 1 de durur. İlk poll bir 1'i çıkarır, peek diğer 1'i görür, boyut 4.

Sonradan eklenen 2 de doğru yere girer; boşaltma sırası küçükten büyüğe olur. println(pq) ise sıralı olmayan iç yığın düzenini yazardı.

Çıktı Sorusu · Kümeler

Soru 9: LinkedHashSet ve TreeSet

Program ne yazdırır?

String[] k = {"kiraz", "Elma", "armut",
              "elma", "Kiraz", "armut"};
List<String> liste = Arrays.asList(k);
Set<String> l = new LinkedHashSet<>(liste);
Set<String> t = new TreeSet<>(liste);
System.out.println(l.size() + " " + l);
System.out.println(t);
Cevabı göster
5 [kiraz, Elma, armut, elma, Kiraz]
[Elma, Kiraz, armut, elma, kiraz]

Yalnız ikinci "armut" tekrardır; "Elma" ile "elma" farklı dizgilerdir. LinkedHashSet ilk eklenme sırasını korur.

TreeSet dizgileri doğal sırayla (karakter kodu) dizer: büyük harfler (E = 69, K = 75) küçük harflerden (a = 97) önce gelir. Alfabetik sıra için String.CASE_INSENSITIVE_ORDER ya da Türkçe için Collator verilir.

Çıktı Sorusu · Kümeler

Soru 10: TreeSet Aralıkları

Program ne yazdırır?

TreeSet<Integer> t = new TreeSet<>(
    Arrays.asList(40, 10, 30, 20, 50, 30));
System.out.println(t.size() + " " + t.first()
    + " " + t.last());
System.out.println(t.headSet(30) + " "
    + t.tailSet(30) + " " + t.subSet(15, 45));
Set<Integer> k = new TreeSet<>(t);
k.retainAll(Arrays.asList(20, 30, 60));
System.out.println(k + " " + t.add(60)
    + " " + t.add(60));
Cevabı göster
5 10 50
[10, 20] [30, 40, 50] [20, 30, 40]
[20, 30] true false
  • İkinci 30 eklenmez: 5 öğe, sıralı.
  • headSet(30) 30 hariç küçükler; tailSet(30) 30 dahil büyükler; subSet(15, 45) [15, 45) aralığı.
  • retainAll kesişimi bırakır (60 kümede yok). Kopya üzerinde çalışıldığı için t değişmez.
  • add eklediyse true, öğe zaten varsa false döndürür.

Adım Adım Çalıştırma · Eşlemeler

Soru 11: Kelime Sayma

Her kelimeden sonra eşlemenin içeriği nedir? Program ne yazdırır?

anahtardeğerboş eşleme {}TreeMap: anahtarsırası (Unicode)

Boş bir TreeMap: anahtarlar her zaman sıralı tutulur.

anahtardeğersu1TreeMap: anahtarsırası (Unicode)

"su" yok: getOrDefault 0 verir, 1 yazılır.

anahtardeğersu1çay1TreeMap: anahtarsırası (Unicode)

"çay" yok: 1 yazılır. "ç" (231) "s"den (115) büyük olduğu için "su"dan sonra sıralanır.

anahtardeğersu2çay1TreeMap: anahtarsırası (Unicode)

"su" var: 1 + 1 = 2.

anahtardeğerkahve1su2çay1TreeMap: anahtarsırası (Unicode)

"kahve" yok: getOrDefault 0 verir, 1 yazılır.

anahtardeğerkahve1su2çay2TreeMap: anahtarsırası (Unicode)

"çay" var: 1 + 1 = 2.

anahtardeğerkahve1su3çay2TreeMap: anahtarsırası (Unicode)

"su" var: 2 + 1 = 3.

anahtardeğerkahve1su3çay2TreeMap: anahtarsırası (Unicode)

Çıktı Türkçe alfabe sırasında değil: String karşılaştırması karakter kodlarına bakar.

String metin = "su çay su kahve çay su";
Map<String, Integer> sayac = new TreeMap<>();
for (String k : metin.split(" ")) {
  sayac.put(k, sayac.getOrDefault(k, 0) + 1);
}
System.out.println(sayac);

Çoktan Seçmeli · Eşlemeler

Soru 12: put'un Dönüş Değeri

Program ne yazdırır?

Map<String, Integer> m = new HashMap<>();
System.out.println(m.put("a", 1) + " "
    + m.put("a", 2) + " "
    + m.get("b") + " " + m.size());

D: İlk put yeni anahtar ekler, önceki değer olmadığı için null döndürür. İkinci put aynı anahtarın değerini 2 yapar ve eski değeri (1) döndürür. Olmayan anahtar için get null verir (0 değil). Anahtarlar tekil: boyut 1.

Hata Bulma · Yineleyici

Soru 13: Gezinirken Silme

Kod listeden çift sayıları silmek için yazıldı. Çalışınca ne olur? Iterator ile düzeltin.

List<Integer> sayilar = new ArrayList<>(
    Arrays.asList(4, 7, 10, 13, 16));
for (Integer s : sayilar) {
  if (s % 2 == 0) {
    sayilar.remove(s);
  }
}
System.out.println(sayilar);
Cevabı göster
Exception in thread "main"
  java.util.ConcurrentModificationException

4 silinir; for-each'in arkasındaki yineleyici sonraki next()'te listenin kendisi dışında değiştirildiğini fark eder ve istisna fırlatır. println'e hiç ulaşılmaz.

Iterator<Integer> it = sayilar.iterator();
while (it.hasNext()) {
  if (it.next() % 2 == 0) {
    it.remove();
  }
}
System.out.println(sayilar);   // [7, 13]

it.remove() son next() ile alınan öğeyi güvenle siler. Java 8+: sayilar.removeIf(s -> s % 2 == 0);

Çoktan Seçmeli · Yineleyici

Soru 14: Iterator.remove

Yeni alınmış bir yineleyicide it.next() hiç çağrılmadan it.remove() çağrılırsa ne olur?

C: remove() son next()'in döndürdüğü öğeyi siler; böyle bir öğe yoksa (hiç next çağrılmadı ya da aynı öğe için ikinci kez remove çağrıldı) IllegalStateException fırlatır. NoSuchElementException, öğe kalmamışken next() çağrılınca oluşur.

Çıktı Sorusu · Algoritmalar

Soru 15: Collections Algoritmaları

Program ne yazdırır?

List<Integer> l = new ArrayList<>(
    Arrays.asList(8, 3, 11, 5, 3));
Collections.sort(l);
System.out.println(l + " "
    + Collections.binarySearch(l, 8) + " "
    + Collections.binarySearch(l, 6));
Collections.reverse(l);
Collections.swap(l, 0, 4);
System.out.println(l + " "
    + Collections.frequency(l, 3) + " "
    + Collections.max(l));
Cevabı göster
[3, 3, 5, 8, 11] 3 -4
[3, 8, 5, 3, 11] 2 11

binarySearch sıralı listede çalışır: 8 indis 3'te. 6 yoktur; eklenmesi gereken yer indis 3'tür, dönüş −(3) − 1 = −4. Negatif sonuç "yok" demektir ve ekleme noktasını da taşır.

reverse → [11, 8, 5, 3, 3]; swap(l, 0, 4) uçları değiştirir → [3, 8, 5, 3, 11]. 3 iki kez geçer; en büyük 11.

Çoktan Seçmeli · Algoritmalar

Soru 16: compareTo ile Sıra

Collections.sort(sinif) sonrası ne yazdırılır?

class Ogrenci implements Comparable<Ogrenci> {
  String isim; int puan;
  Ogrenci(String isim, int puan) {
    this.isim = isim; this.puan = puan;
  }
  public int compareTo(Ogrenci diger) {
    return Integer.compare(diger.puan,
                           puan);
  }
  public String toString() {
    return isim + ":" + puan;
  }
}
// eklenen: Cem:72, Ayşe:95, Banu:60

B: Integer.compare(diger.puan, puan) karşılaştırmayı ters çevirir: puanı yüksek olan için negatif döner, yani o önce gelir. Doğal sıra azalan puan olur. A artan sıradır (Integer.compare(puan, diger.puan)); C isme göre sıradır.

Çoktan Seçmeli · Seçim

Soru 17: Doğru Yapıyı Seçmek

Acil serviste hastalar geliş sırasına göre değil aciliyet derecesine göre çağrılacak; en acil hasta her an hızlıca alınabilmeli ve aynı derecede birden çok hasta olabilir. Hangisi uygundur?

A: PriorityQueue'da poll her zaman en öncelikli öğeyi verir; ekleme ve çıkarma O(log n). B her çağrıda O(n log n) sıralama yapar. C geliş sırasıdır (FIFO). D'de karşılaştırıcıya göre eşit iki hasta aynı öğe sayılır ve ikincisi kümeye eklenmez.

Son

Bölüm 5: Koleksiyonlar: Çalışma Soruları
Konu anlatımı: Koleksiyonlar sunumu · Terim sözlüğü
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.