1. Yineleyicilerin nasıl ortaya çıktığına dair arka plan
zaten aşinasınız HashSet
. Sadece bir ders okumanın ötesinde gerçekten araştırdıysanız, şu soruyu sormanız gerekirdi:
Ekranda tüm HashSet öğelerinin listesini nasıl görüntülerim? get()
Sonuçta, arayüz ve set()
yöntemler yok !
Ve HashSet
bu sınırlamada yalnız değil. Ek olarak HashSet
, öğelerin tanımlı bir sırası olmadığı için öğelerin dizine göre alınmasına izin vermeyen birçok başka koleksiyon vardır.
Yıllar geçtikçe, programcılar grafikler ve ağaçlar gibi birçok karmaşık veri yapısı icat ettiler. Veya liste listeleri.
Birçok konteyner, yeni öğeler eklendiğinde veya mevcut öğeler kaldırıldığında öğelerinin sırasını değiştirir. Örneğin, bir liste, öğeleri belirli bir sırada saklar ve yeni bir öğe eklendiğinde, hemen hemen her zaman listenin ortasına eklenir.
Ayrıca öğeleri depolayan ancak herhangi bir sabit sırada olmayan bir kapsayıcının olduğu durumlar da elde ederiz.
Şimdi böyle bir koleksiyondaki tüm öğeleri bir diziye veya listeye kopyalamak istediğimizi varsayalım. Tüm unsurları almamız gerekiyor. Öğeler üzerinde yineleme sırasını umursamıyoruz - önemli olan aynı öğeler üzerinde birden fazla yineleme yapmamaktır. Bunu nasıl yaparız?
2. Bir koleksiyon için yineleyici
Yineleyiciler, yukarıdaki soruna bir çözüm olarak önerildi.
Bir yineleyici, bir koleksiyonla ilişkili özel bir nesnedir ve koleksiyonun tüm öğelerini hiçbirini tekrar etmeden dolaşmaya yardımcı olur.
Herhangi bir koleksiyon için bir yineleyici almak üzere aşağıdaki kodu kullanabilirsiniz:
Iterator<Type> it = name.iterator();
name
Koleksiyon değişkeninin adı, koleksiyonun Type
öğelerinin türü, iterator()
koleksiyonun yöntemlerinden biri ve it
yineleyici değişkenin adıdır.
Bir yineleyici nesnenin 3 yöntemi vardır:
Yöntem | Tanım |
---|---|
|
Koleksiyondaki bir sonraki öğeyi döndürür |
|
Henüz geçilmemiş herhangi bir öğe olup olmadığını kontrol eder |
|
Koleksiyonun geçerli öğesini kaldırır |
Bu yöntemler, Scanner sınıfının nextInt)
ve hasNextInt()
yöntemlerine biraz benzer.
Yöntem next()
, yineleyiciyi aldığımız koleksiyonun bir sonraki öğesini döndürür.
Yöntem hasNext()
, koleksiyonun yineleyicinin henüz döndürmediği ek öğelere sahip olup olmadığını kontrol eder.
a öğesinin tüm öğelerini nasıl görüntüleyeceğiniz aşağıda açıklanmıştır HashSet
:
kod | notlar |
---|---|
|
HashSet Öğeleri depolayan bir nesne oluşturun String . Değişkene çeşitli dillerdeki selamları ekliyoruz set . Küme için bir yineleyici nesnesi alın set . Hala öğeler olduğu sürece Sonraki öğeyi al Öğeyi ekranda göster |
3. For-each
döngü
Bir yineleyicinin ana dezavantajı, kodunuzun bir for
döngü kullanmaktan daha hantal hale gelmesidir.
for
Karşılaştırmak için, bir döngü ve yineleyici kullanarak bir liste görüntüleyelim :
Yineleyici | döngü için |
---|---|
|
|
Evet, bir döngü kullanarak öğelerini geçmek çok daha iyidir ArrayList
— her şeyin daha kısa olduğu ortaya çıkar.
Ancak Java'nın yaratıcıları yine üzerimize biraz şeker dökmeye karar verdi. Neyse ki bizim için sözdizimsel şekerdi .
Java'ya yeni bir tür döngü verdiler ve buna for-each
döngü adını verdiler. Genel olarak böyle görünüyor:
for(Type name:collection)
collection
Koleksiyon değişkeninin adı nerede , Type
koleksiyondaki öğelerin türü ve name
döngünün her yinelemesinde koleksiyondan bir sonraki değeri alan değişkenin adı.
Bu tür bir döngü, örtük bir yineleyici kullanarak bir koleksiyonun tüm öğelerini yineler. Gerçekte şöyle çalışır:
Her döngü için | Derleyici ne görür: Bir yineleyici ile döngü |
---|---|
|
|
Derleyici for-each
kodunuzda bir döngüyle karşılaştığında, onu sağdaki kodla değiştirir: diğer eksik yöntem çağrılarıyla birlikte bir yineleyici almak için bir çağrı ekler.
Programcılar döngüyü severler for-each
ve bir koleksiyonun tüm öğelerini yinelemeleri gerektiğinde neredeyse her zaman onu kullanırlar.
ArrayList
Bir döngü kullanarak bir listeyi yinelemek bile for-each
daha kısa görünür:
Her döngü için | döngü için |
---|---|
|
|
4. Döngüdeki bir öğeyi for-each
çıkarma
Döngünün for-each
bir dezavantajı vardır: öğeleri doğru şekilde kaldıramaz. Böyle bir kod yazarsanız, bir hata alırsınız.
kod | Not |
---|---|
|
Kaldırma işlemi bir hata üretecek! |
Bu çok güzel ve anlaşılır bir kod ama işe yaramayacak.
Bir yineleyici ile üzerinde gezinirken bir koleksiyonu değiştiremezsiniz.
Bu sınırlamayı aşmanın üç yolu vardır.
1. Farklı türde bir döngü kullanın
When traversing an ArrayList collection
, bir sayaç değişkeni ile sıradan bir döngü kullanabilirsiniz i
.
kod |
---|
|
HashSet
Ancak bu seçenek koleksiyonlar için uygun değildir HashMap
.
2. Açık bir yineleyici kullanın
Açıkça bir yineleyici kullanabilir ve yöntemini çağırabilirsiniz remove()
.
Çalışan sürüm | Çalışmayan sürüm |
---|---|
|
|
remove()
Yöntemi yineleyici nesnesinde çağırdığımıza dikkat edin ! Yineleyici, öğenin kaldırıldığının farkındadır ve durumu doğru bir şekilde halledebilir.
3. Koleksiyonun bir kopyasını kullanın
Ayrıca koleksiyonun bir kopyasını oluşturabilir ve ardından bu kopyayı bir döngüde kullanabilir for-each
ve orijinal koleksiyondaki öğeleri silebilirsiniz.
kod | Not |
---|---|
|
Bir koleksiyonun kopyasını oluşturmak çok kolaydır Döngü, koleksiyonun kopyası için yineleyiciyi kullanır. Öğeler koleksiyondan kaldırılır list . |
Öğelerin kendileri çoğaltılmadığı için koleksiyon oldukça hızlı bir şekilde kopyalanır. Bunun yerine, yeni koleksiyon, eski koleksiyonda zaten var olan öğelere yapılan başvuruları depolar.
GO TO FULL VERSION