İleri Programlama Dersi 3. Ünite Özet

Java’da Temel Programlama Deyimleri

Giriş

Bu ünitede Java programlama dilinin temelleri üzerinde durulmuştur. Nesnelerin durumlarının saklandığı alanlar ya da başka bir ifade ile değişkenler kavramı irdelenmiştir. Java programlama diliyle birlikte yerleşik olarak gelen ilkel veri tiplerinin yanı sıra, String ve dizi gibi değişken çeşitleri de bu ünite kapsamında işlenmiştir. Türüne göre değer atanabilen bu değişkenler üzerinde aritmetik, atama, karşılaştırma gibi çeşitli işlemler gerçekleştirmek için var olan operatörler anlatılmıştır.

Değişkenler

Java nesneye yönelik bir programlama dilidir. Bir Java programında tüm unsurlar birer nesnedir. Genel olarak nesnelerin durumu ve davranışı vardır. Nesnenin davranışını ifade etmek için metotlar kullanılır. Öte yandan bir nesnenin durumu o nesnenin alanlarında saklanır. Örneğin, Kişi nesnesinin alanları ad, soyad, yaş, cinsiyet olabilir. Bu alanların değerleri değişkenlerde saklanır. Bir kişi nesnesinin ad değişkeninin değeri “İlayda” iken başka bir kişi nesnesinin adının değeri “Melike” olabilir.

Değişkenlere bir isim verirken uyulması geren kurallar vardır ve kurallar kullanılan programlama diline göre değişiklik gösterebilir. Java programlama dilinde değişkene isim verirken aşağıdaki kurallara uymamız gerekir:

  • Değişken isimleri küçük büyük harfe duyarlıdır.
  • Değişken isimleri rakam ile başlayamaz, harf ile başlamalıdır. Alt çizgi (_) veya dolar işareti ($) ile de başlayabilir ama bunların kullanılması okunurluk açısından tavsiye edilmez.
  • İlk karakterden sonra gelecek olan karakterler harf, sayı, dolar işareti veya alt çizgi olabilir.
  • Java programlama dilinde ayrılmış özel kelimelerden (class, abstract, default, super, vb) birisi olamaz.
  • Eğer değişken ismi bir kelimeden oluşuyorsa hepsini küçük harf ile yazmak tavsiye edilir. Örneğin cinsiyet. Eğer birden fazla kelimeden oluşuyor ise, ilk kelimeden sonraki kelimelerin baş harfinin büyük yazılması tavsiye edilir.
  • Eğer değişken sabit bir değeri saklayacak ise tamamen büyük harf kullanılması ve kelimelerin alt çizgi ile ayrılması tavsiye edilir. Örneğin java.lang. Math sınıfı içinde π sabit sayısı saklamak için değişken ismi olarak PI seçilmiştir.

Java programlama dilinde bir değişkeni kullanabilmemiz için öncesinde onu tanımlamamız gerekmektedir. Örneğin; int yas = 25;

Bu tanımlama ile programa ismi yaş olan bir değişken olduğu, bu değişkenin tam sayı (int) cinsinden değerler alabileceği ve bu değişkenin ilk değerinin 25 olduğu belirtilmiş olur. Bir değişkenin veri tipi, o değişkenin ne türden veri saklayabileceğini belirtir. Bu örneğimizde tam sayı için kullanılan int veri tipini kullandık. Java programla dilinde int veri tipi de dahil olmak üzere toplam sekiz tane ilkel veri tipi vardır. Bu veri tiplerinin isimleri ayrılmış özel kelimelerdir ve değişken ismi olarak kullanılamazlar. İlkel veri tiplerini inceleyebilirsiniz:

  • (byte 0) 8 bit; -128 ile 127 arasındaki tamsayı değerini tutmak için kullanılır.
  • (short 0) 16 bit; -32768 ile 32767 arasındaki tamsayıları tutmak için kullanılır.
  • (int 0) 32 bit; -231 ile 231-1 arasındaki tamsayıları tutmak için kullanılır.
  • (long 0L) 64 bit; -263 ile 263-1 arasındaki tamsayıları tutmak için kullanılır.
  • (float 0.0f) 32 bit; Gezer noktalı (floating point) sayıları tutmak için kullanılır.
  • (double 0.0d) 64 bit; Gezer noktalı (floating point) sayıları tutmak için kullanılır.
  • (char ‘\u0000’) 16 bit; 16-bitlik tek bir Unicode karakter değerini tutmak için kullanılır.
  • (boolean false) 1 bit; Sadece doğru (true) yanlış (false) değerlerini alabilir.

Listelenmiş ilkel veri tiplerinin yanı sıra, karakterlerden oluşmuş metin verisi için java. lang.String sınıfını vardır. Çift tırnak içine alınmış bir metin için otomatik olarak yeni bir String nesnesi yaratılır. Örneğin, String ad = “Zeynep” değişkeni teknik olarak String sınıfı ilkel veri tipi değildir; ancak Java programlama dili tarafından özel olarak desteklenen bu sınıfı temel veri tipleri arasında düşünebiliriz. Bir değişkeni tanımlarken her zaman ona bir değer atamak zorunda değiliz. Eğer açıkça bir değer atanmadan bir değişkeni tanımlarsak, derleyici o değişkene tipine göre bir varsayılan (default) değer atar.

İlkel veri tiplerinden birisiyle tanımlanmış bir değişkene değer atarken new anahtar sözcüğünü kullanmayız. Bunun sebebi, ilkel tipler sınıflardan yaratılmış nesneler değildir. Sabitler kodun içinde değişkenlere atadığımız değerlerdir

Tam sayılar için kullanılan ilkel veri tipleri: byte, short, int ve long’dur. Bunlara sayılardan oluşmuş değerler atanabilir. Burada long tipinde bir değişkene atama yaparken atama yaptığımız sayının long cinsinden olduğunu belirtmek için rakamların sonuna L ya da l harfini koyulur. long tipi int tipinin yetmediği büyüklükteki tam sayıları tutmak için kullanılır. Örneğin: long l = 15000L;

Tam sayı değerlerini ikilik, onluk veya on altılık sistemde yazabiliriz. Onluk sistem günlük hayatta kullandığımız 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 rakamları ile sayıların yazıldığı sistemdir. On altılık sistemde ise sayıları ifade etmek için 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F sembolleri kullanılır. İkilik sistemde ise sadece 0 ve 1 kullanılır. On altılık sistemde bir sayı yazacağımız zaman sayının başına 0x, ikilik sistemde yazacak isek 0b koymamız gerekir.

Gezer noktalı sayıları ifade etmek için double ya da float tipleri kullanılır. Double tipinin duyarlılığı daha fazladır. Eğer ondalıklı sayı F ya da f harfi ile biterse float olarak değerlendirilir. D ya da d harfi ile bitiyorsa double olarak değerlendirilir. Gezer noktalı sayıları bilimsel gösterimde de yazabiliriz. Bu gösterimde E ya da e harfi kullanılır. Bu harflerden sonra gelen sayı ise 10’un katını ifade eder. Örneğin, ışığın hızını 3 x 108 bilimsel gösterimde yazmak istersek 3.0e8 olarak yazarız. Bilimsel gösterim, bilim insanlarının çok büyük ya da çok küçük sayıları daha anlaşılır ve okunur olarak ifade etmesidir. Örneğin, 0.0000000056 yerine 5.6 x 10-9 yazılır. Bu sayı Java dilinde float ve double tipleri için 5.6e-9 ya da 5.6E-9 olarak yazılabilir.

Okunurluğu artırmak için sayısal değişken değerleri için rakamlı gruplamak ya da ayırmak için alt çizgi “_” kullanabiliriz. Örneğin, bir telefon numarasını alan kodundan sonra “_” koyarak yazabiliriz. Bu yazım biçimi sadece kozmetik amaçlıdır. Sayının değerinde bir değişim olmaz.

String ve char sabitleri Unicode (UTF-16) karakterlerinden oluşurlar. Eğer metin editörü ve dosya sistemi izin veriyorsa ASCII dışında kalan karakterleri (ğ, ü, ş, ı, ö, ç, Ğ, Ü, Ş, İ, Ö, Ç, gibi) direk olarak kodun içinde kullanabiliriz. Örneğin: String ad = “Çiğdem”;

Bu tür karakterleri sadece ASCII karakterleri kullanarak yazmanın yolu vardır. Her karakterin Unicode değerinin 16’lık tabanda gösteriminin başına \u koyarak yazarsak o karakterin kendini yazmış gibi oluruz. String ad = “\u00c7i\u011fdem”;

Bu örnekte Ç yerine \u00c7, ğ yerine ise \u011f kullanılmıştır. Bu değişkeni ekrana yazdırdığımızda ise çıktı olarak Çiğdem görülecektir.

Burada bahsedilen ASCII, harflerin bilgisayar ortamında saklanması ve taşınması ile ilgili geliştirilen ilk sistemdir ve Türkçe’de Bilgi Değişimi İçin Amerikan Standart Kodlama Sistemi anlamına gelir. Unicode ise Unicode Consortium organizasyonu tarafından geliştirilen ve her karaktere bir sayı değeri karşılığı atayan bir endüstri standardıdır.

Diziler, tek bir türde sabit sayıdaki değerleri muhafaza ederler. Bir dizini boyutu ilk yaratıldığında belirlenir, sonradan değişmez. Bir diziyi oluşturan öğelere eleman denir. Her bir elemana ait sayısal bir indeks değeri vardır ve elemanlara bu indekslerle erişilir. İndeks dizini sıfırdan başlar. Bir tipin dizisini tanımlamak için köşeli parantezler [ ] kullanılır. Aynı şekilde indeks değerleri de köşeli parantezler içine yazılır. Bir diziyi tanımlamada iki parça vardır: köşeli parantezlerden önce yazılan dizinin tipi ve köşeli parantezlerden sonra yazılan dizinin adı. Dizinin tipi olarak ilkel veri tiplerini (int, byte, long, vb) kullanabileceğimiz gibi sınıflardan yaratılmış nesnelerde kullanabiliriz. Bir kaynak diziyi, başka bir hedef diziye kopyalamak işini en hızlı şekilde gerçekleştirmenin yolu java.lang.System#arraycopy metodunu kullanmaktır. Bu metot Java programlama dilinde doğuştan var olduğu (native) için çok hızlı çalışır. Diziler üzerinde hayatı kolaylaştıran işlemleri gerçekleştiren bir takım metotlar java.util.Arrays sınıfı içinde mevcuttur. Örneğin, dizileri sıralamak veya dizileri String tipine çevirme işlemi. Java 8 sürümü ile gelen bir yenilik olan java.util.Arrays#parallelSort metodu programın çalıştırıldığı bilgisayarın işlemcilerini veya çekirdeklerini kullanarak dizileri paralel bir şekilde sıralar. Çok işlemcili bilgisayarlarda bu işlem java.util.Arrays#sort işleminden daha hızlı olacaktır.

Operatörler

Değişkenler üzerinde çeşitli işlemleri gerçekleştirmeye yarayan özel sembollere operatör denir. Operatörler çeşidine göre bir, iki ya da üç adet işlenen üzerinde çalışırlar ve en sonda bir değer döndürürler. En sık kullanılan operatör değişkenlere değer atamaya yarayan eşittir “=” operatörüdür. Bununla birlikte, Java programlama dilinde toplama, çıkarma, bölme ve çarpma gibi aritmetik işlemler için de operatörler bulunmaktadır.

Java programlama dilindeki 5 temel aritmetik işlem için operatörler aşağıdaki tabloda listelenmiştir. Bu operatörler temel matematik derslerinde aşina olduğumuz dört işlemi gerçekleştirmek için kullanılan;

+ Toplama işlemini

− Çıkarma işlemini

∗ Çarpma işlemini

/ Bölme işlemini

% Modulo işlemini

ifade eden operatörlerdir.

Yukarıda görülen Modulo işlemi, hesaplamada bir sayının diğer bir sayıya bölümünden arta kalan sayıyı verir. Yukarıda listelenen operatörler basit atama operatörü olan “=” operatörü ile birleştirilerek bileşik atama işlemi gerçekleştirilebilir. Örneğin, bir x değişkeninin değerini 3 artırmak istediğimizde ‘x += 3;’ ifadesini kullanabiliriz. Bu ifade ‘x = x + 3;’ ifadesi ile aynı anlama gelmektedir

Tek bir işleneni olan operatörlere birli operatör denir. Bu tür operatörler; bir artırma, bir azaltma, negatifleme veya tersleme işlemleri için kullanılır. Aşağıda bu tip operatörleri görebilirsiniz:

+ Birli toplama operatörü değerin pozitif olduğunu belirtir.

− Birli çıkarma operatörü (değeri negatifler)

++ Artırma operatörü, değişkenin değerini 1 artırır.

-- Azaltma operatörü, değişkenin değerini 1 azaltır.

! Mantıksal tersleme operatörü boolean tipindeki bir değişkenin değerini ters çevirir.

Artırma ve azaltma operatörlerini sonek (x++) ya da önek (++x) olarak kullanmak mümkündür. Değişkenin soluna operatörü yazdığımızda (++x), önce artırma işlemi yapılır daha sonra diğer işlemlere geçilir. Sağına yazdığımızda ise (x++), önce diğer işlemler yapılır sonra artırım işlemi yapılır.

Değişkenlerin değerlerini birbirleriyle karşılaştırmak için kullanılan operatörler aşağıdaki tabloda listelenmiştir. Eşitlik ve ilişki operatörleri boolean tipinde değer döndürürler. Birden fazla boolean döndüren ifadeyi VE ile VEYA operatörleri olan && ile || kombine etmek mümkündür;

== Eşittir

!= Eşit değildir

> Büyüktür

>= Büyük ya da eşittir

< Küçüktür

<= Küçük ya da eşittir

Kontrol Akış Deyimleri

Java kodları genelde satır satır yukarıdan aşağıya doğru sırayla çalıştırılır. Öte yandan, kontrol akış deyimleri bu akışı üç şekilde değiştirilebilir:

  • karar verme (if-then, if-then-else, switch)
  • döngü (for, while, do-while)
  • dallanma (break, continue, return)

Günlük hayatta birçok iş bir koşula bağlı olarak karar verme ile gerçekleştirilir. Eğer dönemlik not ortalamamız 3.0’ın üstünde ise onur sertifikası alabiliriz; 15 yaşını tamamlamış olanların kimlik başvurusunu şahsen başvurması gerekmektedir. Bilgisayar programlarında da benzer şekilde sınamaya bağlı olarak karar vermemiz gereken yerler vardır ve farklı koşullara göre farklı kod blokları çalıştırmamız gerekir.

If-then ifadesi tüm kontrol akış deyimlerinin en temelidir. Belirli bir sınama doğru olarak değerlendirildiğinde programınıza belirli bir kod bölümünü çalıştırmasını söyler. Kontrol akış deyimleri arasında en basit ve en temel olanıdır. Sadece eğer belli bir sınama doğru olarak değerlendirildiğinde programın belirli bir kısmının çalışmasını sağlar. Açılış ve kapanış kaşlı ayraçlarını { } kullanmak “then” ifadesinin yalnızca bir satır içermesi koşuluyla isteğe bağlıdır. Ancak, kaşlı ayraçların { } kullanılmaması kodu daha kırılgan hâle getirebilir. Eğer “then” maddesine ikinci bir satır sonradan eklenirse yeni gerekli kaşlı ayraçları eklemeyi unutmak sık yapılan bir hatadır. Derleyici bu tür hataları yakalayamaz ve yanlış sonuçlar üretir.

If-then-else deyimi, bir “if ” sınaması yanlış (false) olarak değerlendirildiğinde, ikincil bir yürütme yolu sağlar. İş başvurusu örneğinde bir if-then-else ifadesi kullanabiliriz. Örneğin, kişinin yaşının 18’den küçük olması durumunda, işe başvuru yapamayacağını belirten bir hata mesajı gösterecek eylemin çalışmasını sağlayabiliriz.

if-then ve if-then-else ifadelerinden farklı olarak switch ifadesi bir dizi yürütme yollarına sahip olabilir. Bir switch ifadesi, byte, short, char ve int gibi ilkel veri türleriyle çalışır. Ayrıca switch ifadesi numaralandırılmış sıralı tiplerle (Enum), dizgi (String) sınıfında ve bazı ilkel türleri saran Character, Byte, Short ve Integer gibi birkaç özel sınıfla birlikte çalışır. Bir switch deyiminin gövdesi switch bloğu olarak bilinir. Switch bloğundaki bir ifade ya case ya da default etiketleriyle etiketlenebilir. Örnekte görüldüğü gibi bir switch bloğu içinde case etiketi birden fazla olabilir. Switch deyimi ifadesini değerlendirir ve akabinde ifadenin eşleştiği case etiketinden sonra gelen tüm ifadeleri çalıştırır. If-thenelse deyimlerini veya switch deyimini kullanılıp kullanılmayacağına karar vermek okunabilirlik ve test edilen ifadeye dayanır. If-then-else deyimi, değerleri veya koşulların aralıklarına dayalı ifadeleri sınarken switch ifadesi ifadeleri yalnızca tek bir tam sayı, numaralandırılmış değer veya String nesnesine dayalı olarak test eder. Diğer bir ilgi çekici nokta da break ifadesidir. Her break ifadesi, switch deyimini sonlandırır. Kontrol akışı, switch bloğundaki ilk ifadeyle çalışmaya başlar. Switch bloğunun doğru çalışması için break ifadeleri gereklidir. Eğer break ifadeleri kullanılmazsa eşleşen case etiketinden sonraki tüm ifadeler, sonraki case etiketinin eşleşip eşleşmediğine bakılmaksızın, bir break ifadesi bulunana kadar çalışmaya devam eder. Switch deyimi kullanılırken break ifadeleri unutulmamalıdır.

Bazı durumlarda bir kod bloğunu defalarca çalıştırmamız gerekebilir ya da kod bloğunu belirli bir sınama doğru olana kadar çalıştırmak isteyebiliriz. Hatta bazı programlar sonsuz döngü içerisinde çalışmaktadır.

While deyimi, belirli bir koşul geçerli olduğu sürece bir kod bloğunu sürekli çalıştırır. Söz dizimi şu şekilde ifade edilebilir:

while (ifade)

{

// bir şeyler yap

}

While deyimi, bir boolean değeri döndürmesi gereken sınama ifade değerini değerlendirir. Sınama ifadesi doğru (true) olarak değerlendirilirse while deyimi while bloğundaki ifadeleri sırasıyla çalıştırır. While ifadesi, sınama ifadesinin test edilmesine ve içindeki ifadeleri sırayla çalıştırmaya, sınama ifadesinin yanlış (false) olarak değerlendirilene kadar devam eder.

Java programla dili do-while deyimini de sağlamaktadır ve şu kullanımı şu şekildedir:

do {

// bir şeyler yap

} while (ifade);

Bu iki döngü deyimi arasındaki tek fark sınamanın başta veya sonda yapılmasıdır. Bu nedenle do-while deyimi içindeki kod bloğu en az bir kere çalıştırılır çünkü sınama sonda yapılmaktadır.

for (hazırlık; bitiş; artırım)

{

// bir şeyler yap

}

For deyimi, bir değer aralığı üzerinde yürümenin kompakt bir yoludur. Programcılar genellikle bunu “for döngüsü” olarak adlandırırlar çünkü belirli bir koşul sağlanana kadar döngü tekrar eder. For deyiminin genel biçimi şu şekilde ifade edilebilir:

  • Hazırlık: Döngüyü ilk kullanıma hazırlar, bir defaya mahsus döngünün en başında çalıştırılır.
  • Bitiş: Sonlandırma ifadesi yanlış (false) olarak değerlendirildiğinde döngü biter.
  • Artırım: Artırım ifadesi döngünün her bir yinelemesinde çalıştırılır. Genelde bu kısımda bir değişkenin değeri artırılır ya da azaltılır.

Örneğin, aşağıdaki program 1’den 9’a kadar olan rakamları yazdırır. Bu programın çıktısı: 1 2 3 4 5 6 7 8 9 10

for (int i = 1; i < 10; i++) {

System.out.print(i + “ ”);

}

Bu örnekte, hazırlık ifadesi içinde i isimli bir değişken tanımlanmıştır. Bu değişkenin kapsamı tanımlanmasından itibaren başlar ve for döngüsü bloğunun sonuna kadar devam eder; bu nedenle de bitiş ve artırım ifadelerinde de kullanılabilir. Bir for deyimini kontrol eden değişken, döngü dışında gerekli değilse değişkeni hazırlık kısmında tanımlamak en iyisidir. For döngüsü kontrol değişkenleri genellik i, j ve k isimleri ile adlandırılır. Bu değişkenleri hazırlık ifadesi içinde tanımlamak değişkenlerin kapsamını sınırlar ve olası hataları azaltır. For döngüsü için bahsettiğimiz hazırlık, bitiş ve artırım ifadeleri opsiyoneldir. Bu üç ifadeyi kullanmaksak sonsuz bir döngü yaratmış oluruz.

For döngüsünün, diziler ve kolleksiyonlar (listeler, kümeler vs) üzerinde yürümeyi daha kolaylaştıran ve kodu daha okunabilir kılan özel bir hâli vardır. Bu döngüye for-each döngüsü adı verilir. Bu for çeşidinde kontrol değişkeni tanımlandıktan sonra iki nokta (:) işareti kullanılır ve ardından üzerinde yürümek istediğimiz değişkeni yazarız. Mümkün olduğu durumlarda for döngüsünün bu çeşidini kullanmak tavsiye edilir. Çünkü bu hâli daha kısa ve anlaşılırdır. Ancak, for-each döngüsü sadece listenin elemanlarını sırasıyla gezmek içindir. Sadece okuma (read-only) yapmak için kullanılır. Eğer for-each döngüsü içinde liste üzerinde bir değişiklik yapmaya çalışırsanız hata alırsınız.

Program içerisinde sıçrama ya da dallanma yapmak istediğimiz durumlar meydana gelebilir. Örneğin, bir döngü içerisindeyken döngüyü sonlandırmak isteyebiliriz ya da programın etiketlediğimiz bir satırına atlamak isteyebiliriz. Bu tür işlemleri gerçekleştirmek için Java programlama dilinde bize sunulan ifadeler çeşitli ifadeler vardır.

Break ifadesini ilk olarak switch deyimini işlerken görmüştük. Break ifadesi for, while veya do-while döngülerini sonlandırmak için de kullanabiliriz. Bir break ifadesi en içteki switch, for, while veya do-while döngüsünü sonlandırır. Örneğin, verilen bir dizinin küçükten büyüğe sıralı olup olmadığını test etmek istediğimizi düşünelim. Bu işlem için dizinin bütün elemanlarını for döngüsüyle tek tek gezip, bir elamanın bir sonraki elamandan küçük olması durumuyla ilk karşılaşmamızda dizinin sıralı olmadığını tespit olmuş oluruz. Bu durumda dizinin geri kalan diğer elemanlarını kontrol etmemize gerek yoktur. Sıralı olma kuralını ilk ihlal eden durumla karşılaşır karşılaşmaz break ifadesini kullanarak döngüyü sonlandırabiliriz.

Continue ifadesi for, while veya do-while döngülerinin o anki yinelemesini atlamayı sağlar. En içteki döngünün gövdesinin en sonuna giderek en iç döngünün sınama ifadesinin yeniden değerlendirilmesini edilmesini sağlar.

Dallanma deyimlerinin en sonuncusu return ifadesidir. Return ifadesi o anki metottan çıkar böylece kontrol akışı metodun çağrıldığı yere geri döner. Return ifadesinin iki çeşidi vardır: İlki değer döndüren ve diğeri ise değer döndürmeyendir.