Java - Wrapper (Sarmalayıcı) Class - Set,Map,Queue ve Math Apı

Java - Wrapper (Sarmalayıcı) Class - Set,Map,Queue ve Math Apı

Arkadaşlar merhaba,

Bu yazımızda java'da Wrapper (Sarmalayıcı) Class - Set ve Map - Math Apı konularına kısaca göz atacağız.

Wrapper Class

Java'da her primitive türün nesne türünde karşılığı olan bir sarmalayıcı sınıfı vardır.

Her sarmalayıcı sınıfın bir constructor'ı vardır.

Bir string'i wrapper veya primitive tipe döndürmek içinde metotlar vardır.

parseInt() gibi bir metot primitive'e döndürür.

valueOf() methodu bir sarmalayıcı sınıfa döndürür.

primitive tipler null tanımlanamaz fakat wrapper sınıflar object oldukları için tanımlanabilir.

Sarmalayıcı sınıfının primitive değere ters çevrilmesine unboxing denir.

Primitive bir değerin sarmalayıcı bir sınıfa çevrilmesine autoboxing denir. Java bunu otomatik olarak yapar.

List<Integer> weights = new ArrayList<>();
Integer w = 50; // int primitive tipini Integer nesnesine autoboxing(otomatik çevirir) yerleştirir.
weights.add(w);   // [50] ve listeye ekler.
weights.add(Integer.valueOf(60)); 

// [50, 60] hala uzun yoldan yazılarak wrapper objeye iletebiliriz.
weights.remove(new Integer(50)); // [60]
double first = weights.get(0); 

// 60.0'ı yani listedeki ilk Integer'ı alır primitive olarak unboxing yapar ve double'a cast eder.
List<Integer> heights = new ArrayList<>();

heights.add(null);
//  Listeye null ekledik. Bu geçerlidir çünkü herhangi bir referansa değişkenine boş bir referans değişkeni atanabilir.

int h = heights.get(0); // NullPointerException

// int değeri null olarak unboxingn etmeye çalışır bu bir problemdir.Java int değere null geçmeye çalışır.
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);

numbers.remove(1); // index 1'i siler. 
// [1]

numbers.remove(new Integer(1)); // listedeki 1'i siler.
[2]

Değerleri ekledikten sonra liste 1,2'dir.Daha sonra index 1'e sahip elemanın kaldırılmasını isteriz.

Bir int parametresi alan remove() methodu zaten varolduğundan java otomatik olarak bunu çağırır.

Array ve List Dönüştürme

Bir arrayList'i bir Array'e dönüştürelim.

List<String> list = new ArrayList<>();
list.add("umut");
list.add("Ali");

Object[] object = list.toArray();

// ArrayList'in kendisini bir diziye nasıl dönüştüreceğini bildiğini gösterir. 

// Tek sorun, varsayılan olarak bir Object sınıfı array'ine sahip olmasıdır.

Aşağıdaki örnek ise dizinin türünü belirtir ve gerçekten istediğimizi yapar.

Parametre için 0 boyutu belirlemenin avantajı, Java'nın dönüş değeri için uygun boyutta yeni bir dizi oluşturmasıdır.

İsterseniz, bunun yerine kullanılmak üzere daha büyük bir dizi geçebilirsiniz.

ArrayList bu diziye sığarsa döndürülür, aksi takdirde yenisi oluşturulacaktır.

String[] stringArray = list.toArray(new String[0]);

clear orijinal listeyi temizlemez.Bu, her iki diziyi de etkilemez. Dizi, orijinal listeyle hiçbir ilişkisi olmayan yeni oluşturulmuş bir nesnedir. Bu sadece bir kopyadır.

list.clear();

System.out.println(objectArray.length); // 2
System.out.println(stringArray.length); // 2

Diziden Listeye Dönüştürme

Seçeneklerden biri, orijinal diziye bağlı bir Liste oluşturmaktır. Birinde değişiklik yapıldığında, diğerinde kullanılabilir. Bu, sabit boyutlu bir listedir ve diziyle birlikte değiştiği için yedekli Liste olarak da bilinir.

String[] array = { "umut" , "gökhan"} // [umut, gökhan]

List<String> list = Arrays.asList(array);  // sabit boyut listesini döndürür

// diziyi bir Listeye dönüştürür. Bunun alıştığımız java.util.ArrayList olmadığını unutmayın
// Bir Listenin sabit boyutlu halidir.

System.out.println(list.size()); 
// 2
list.set(1,"test");

//[umut,test] set yalnızca mevcut değeri değiştirir.

array[0] = "new"; 

//[new, test] hem diziyi hemde listeyi değiştirir.

System.out.println(Arrays.toString(array)); // [new, test]

list1.remove(1); 
// throws UnsupportedOperationException => listenin boyutunu değiştirme iznimiz  yok.

Başka bir seçenek de immutable bir liste oluşturmaktır.

Bu, Listenin değerlerini veya boyutunu değiştiremeyeceğiniz anlamına gelir. Orijinal diziyi değiştirebilirsiniz, ancak değişiklikler immutable listeye yansıtılmaz.

String[] array2 = {"umut","gökhan"};

List<String> list2 = List.of(array2); // immutable list oluştur.

System.out.println("list2: " + list2.size()); // 2

array[0] = "new";

System.out.println(Arrays.toString(array2));

// [new, gökhan]

System.out.println("list 2 :" + list2);

// [umut, gökhan]

list2.set(1, "test"); // throws UnsupportedOperationException

Değişmez bir listede bir liste değerinin değiştirilmesine izin verilmediğini gösterir.

varargs Kullanarak Liste Oluşturma

List<String> list1 = Arrays.asList("one", "two");
List<String> list2 = List.of("one", "two");

Bu methodların her ikisi de bir array geçmenize veya sadece String değerlerini yazmanıza izin veren varargs alır.

Bu, bir satırda kolayca bir iste oluşturup doldurabileceğiniz için test ederken kullanışlıdır.

Her iki method da sabit boyutlu diziler oluşturur. Daha sonra öğe eklemeniz veya kaldırmanız gerekirse, yine de constructor kullanarak bir ArrayList oluşturmanız gerekir.

Seçeneklerden hiçbirinin öğe sayısını değiştirmenize izin vermediğine dikkat edin.

Sıralama

Bir ArrayList'i sıralamak, bir diziyi sıralamaya benzer. Sadece farklı bir yardımcı sınıf kullanıyoruz.

List<Integer> numbers1 = new ArrayList<>();
numbers1.add(99);
numbers1.add(5);
numbers1.add(81);
Collections.sort(numbers1);

// [5, 81, 99]

Set

2560px-Java.util.Collection_hierarchy.svg.png

Java'da collection frameworklerinin alt tiplerinden biridir.

Set: Kümedir, tuttuğu nesneler tekildir, aynı nesneden birden fazla tutmaz.

Dizilim-sıra (order) kavramı yoktur.

Set'i implement eden iki ortak sınıf vardır. HashSet en yaygın olanıdır. Sıralama önemli olduğunda TreeSet kullanılır.

Set,tüm Collection nesneleri gibi Iterable’dır ve devraldığı iterator()metoduna sahiptir.

Dolayısıyla elemanlarına ancak Iterator ile ulaşılabilir.

Set<Integer> set = new HashSet<>();
System.out.println(set.add(66)); // true
System.out.println(set.add(66)); // false
System.out.println(set.size()); // 1

set.remove(66);
System.out.println(set.isEmpty()); // true

Set<String> set1 = new HashSet<>();
System.out.println(set1.add("Umut"));
System.out.println(set1.add("Çakmak"));

Iterator value = set1.iterator();
    while (value.hasNext()){
                System.out.println("iterator : " + value.next());
}

// iterator : Çakmak
// iterator : Umut

Liste gibi, tek satırda immutable bir Set oluşturabilir veya var olanın bir kopyasını oluşturabilirsiniz.

Set<Character> letters = Set.of('z', 'o', 'g');
Set<Character> copy = Set.copyOf(letters);
Set<Integer> set = new HashSet<>();
boolean b1 = set.add(66); // true
boolean b2 = set.add(10); // true
boolean b3 = set.add(66); // false
boolean b4 = set.add(8); // true

set.forEach(System.out::println);

// kümenin öğelerini rastgele bir sırayla yazdırır. Bu durumda, sıralama düzeni veya öğeleri eklediğimiz sıra olmaz.
    Set<Integer> set1 = new TreeSet<>();
        boolean b5 = set.add(66); // true
        boolean b6 = set.add(10); // true
        boolean b7 = set.add(66); // false
        boolean b8 = set.add(8); // true
        set1.forEach(System.out::println); 
// öğeler doğal sıralı düzende yazdırılır. Sayılar, Java'da sıralama  için kullanılan Comparable arabirimi uygular.

TreeSet

TreeSet, elemanlarını sıralı (sorted) tutan bir başka Set gerçekleştirmesidir.

TreeSet, hem NavigableSet hem de SortedSet’tir.

TreeSet, eklenen elemanları sıralamak için şu iki yöntemi kullanır:

Eğer elemanların dizilişi (natural ordering) varsa yani gerçekleştiriyorlarsa Comparable arayüzünü,

Elemanların doğal dizilişinin olmadığı dolayısıyla Comparable arayüzünün gerçekleştirmediği durumlarda kendisine geçilen Comparator arayüzünü.

Bir HashSet, öğelerini bir hash table'da saklar; bu, key'lerin bir hash olduğu ve value'lerin bir Nesne olduğu anlamına gelir. Bu, nesneleri daha verimli bir şekilde almak için hashCode() methodunu kullandığı anlamına gelir.

equals()’un true döndürdüğü nesnelerin hashCode() da aynı int değeri döndürmeli,

equals()’un true döndürdüğü nesnelerin gerçekleştirdiği Comparable arayüzün compareTo() (ya da Comparator arayüzündeki compare()) metotları da 0 döndürmelidir.

equals()’un true döndürdüğü nesnelerin hashCode() metotlarının da aynı int değeri döndürmesi, nesnelerin aynılık kontrolüyle ilgilidir.

Map

Elemalanlarını key value olarak eşleştirerek tutan torbaların ana arayüzüdür.

Saklanan eleman value'dur ve bir anahtar (key) ile eşleştirilerek torbada tutulur.Bundan dolayı da genelde elemanlara anahtarlarıyla (key) ulaşılır.

map-interface.png

Map<String, String> map = new HashMap<>();

map.put("umut", "çakmak");
String name = map.get("umut"); // umut değerini key ile alır

String other = map.getOrDefault("ant", "leaf");
 // leaf olmayan bir key arar.Bu nedenle leaf default value olarak 

System.out.println("name :"  + name);
System.out.println("other :" + other);

for (String key : map.keySet())
    System.out.println("keySet :" + key + " " + map.get(key));
}

// name :çakmak
// other :leaf
// keySet :umut çakmak

Artık bir value iletmeyi unutamayız. Bir parametreyi dışarıda bırakırsak entry() methodu derlenmez. Uygun şekilde, Map.copyOf(map), List ve Set interface copyOf() yöntemleri gibi çalışır.

Map.ofEntries(Map.entry("key", "value"), Map.entry("key1", "value1"));
  1. V get(Object key) => Key ile eşlenen değeri döndürür veya hiçbiri eşlenmemişse null döndürür.
  2. V getOrDefault(Object key, V other) => Hiçbiri eşlenmemişse, key veya diğeriyle eşlenen değeri döndürür.
  3. V put(K key, V value) => key/value çiftini ekler veya değiştirir. Önceki değeri veya boş değeri döndürür.
  4. V remove(Object key) => key ile eşlenen value'yi kaldırır ve döndürür. Hiçbiri yoksa null döndürür.
  5. boolean containsKey(Object key) => Key'in map'de olup olmadığını döndürür.
  6. boolean containsValue(Object value) => Value'nun map'de olup olmadığını döndürür.
  7. Set keySet() => Tüm Key ve setleri döndürür.
  8. Collection values() => Tüm collection value'lerini döndürür.

Bir key verilen value elde etmek için get() methodunu kullanabiliriz.

Tüm key'leri almak için ise keySet() methodunu kullanırız.Java, sırayı belirlemek için key'lerin hashCode()'unu kullanır.Buradaki sıra, sıralama düzeni veya değerleri yazdığımız sıra değildir.

Map<String, String> stringMap = new HashMap<>();
stringMap.put("Umut" , "Çakmak");
stringMap.put("Gökhan" , "Çakmak");

String person = stringMap.get("umut");
        for (String key : stringMap.keySet())
            System.out.print("Person :" + key + " ,");

containsKey() , size() , isEmpty()

System.out.println("Person : " + stringMap.containsKey("Umut"));
System.out.println("Person :" + stringMap.containsKey("gökhan"));
System.out.println(stringMap.size());
System.out.println(stringMap.isEmpty()); 

// Person : true
// Person :false
// 2
// false

forEach()

Map'de kullanılan forEach() methodun da lambda'nın iki parametresi vardır; key ve value.

Lambda, parametre olarak hem key'e hem de value'e sahiptir.

Map<Integer,Character> characterMap = new HashMap<>();
characterMap.put(1,'a');
characterMap.put(2,'b');
characterMap.put(3, 'c');

characterMap.forEach((k,v) -> System.out.println(v));

key'i önemsemiyorsanız , bunun yerine values() methodu ve bir method referansı ile yazılabilir.

characterMap.values().forEach(System.out::println);

Bir Map'daki tüm verileri gözden geçirmenin başka bir yolu, bir Set'deki key/value çiftlerini elde etmektir. Java,Map içinde Entry adlı statik bir interface'ye sahiptir. Her bir çiftin key ve value'sini almak için methodlar sağlar.

characterMap.entrySet().forEach(e -> System.out.println(e.getKey() + e.getValue()));

get() ve getOrDefault()

İstenen key map'de değilse, get() methodu null değerini döndürür. Bazen farklı bir değer döndürülmesini tercih edebilirsiniz.getOrDefault() methodu bunu kolaylaştırır.

Map<Character,String> maps = new HashMap<>();
maps.put('a', "Gala");
System.out.println("a " + maps.get('a'));
System.out.println(maps.getOrDefault('a' , ""));
System.out.println("b :" + maps.get('b'));

System.out.println("b getOrDefault : " + maps.getOrDefault('b'  , "saray"));

System.out.println(maps.get('b'));

a :Galata
Galata
b :null
b-getOrDefault : saray
null

replace() ve replaceAll()

replace methodu key değerini değiştirir ve orijinal değeri döndürür.

replaceAll satırı bir fonksiyon çağırır ve map'in her bir öğesinin değerini o fonksiyonun sonucuna göre ayarlar.

Map<Integer, Integer> integerMap = new HashMap<>();
integerMap.put(2,4);
integerMap.put(6,8);
Integer integer = integerMap.replace(6,12);
System.out.println("replace :" + integerMap);


int j = 5;
integerMap.replaceAll((k,v) -> j + v);
System.out.println("replaceAll : " + integerMap);

replace :  {2=4, 6=12}
replaceAll : {2=9, 6=17}

putIfAbsent()

Map'de bir key ayarlar ancak key zaten boş olmayan bir value ayarlanmışsa onu atlar.

Map<String, String> names = new HashMap<>();
names.put("Umut" , "Çakmak");
names.put("Ahmet" , null);
names.putIfAbsent("Gökhan" , "Çakmak");

System.out.println("names : " + names);
names.putIfAbsent("Ahmet","Çakmak");
names.putIfAbsent("Umut","Kibrit");

System.out.println("names : " + names);

names : {Ahmet=null, Gökhan=Çakmak, Umut=Çakmak}
names : {Ahmet=Çakmak, Gökhan=Çakmak, Umut=Çakmak}

Gördüğünüz gibi key'i Ahmet olan değeri değiştirdi fakat key'i Umut olan değerin value'su boş olmadığı için onu atladı.

merge()

Java HashMap merge() yöntemi, belirtilen anahtar zaten mevcut değilse, belirtilen anahtar/değer eşlemesini hashmap'e ekler.

Belirtilen anahtar zaten bir değerle ilişkilendirilmişse, method eski değeri belirtilen fonksiyonun sonucuyla değiştirir.

BiFunction<String , String , String>  merge = (v1,v2) -> v1.length() > v2.length() ? v1 : v2;
String umut = names.merge("Umut" , "Çakmaktaş" , merge); // çakmaktaş çakmaktan uzundur.
String gokhan = names.merge("Gökhan" , "Çakıl" , merge); // çakmak çakıldan uzundur.

System.out.println("merge umut" + umut);
System.out.println("merge gokhan : " + gokhan);

// merge umut : Çakmaktaş
// merge gokhan : Çakmak

merge() methodu ayrıca null value'ler veya eksik key'ler söz konusu olduğunda ne olacağı konusunda bir mantığa sahiptir. Bu durumda BiFunction'ı hiç çağırmaz ve sadece yeni değeri kullanır.

names.put("Ahmet", null);
names.merge("Ahmet" , "Çakmak", merge);
System.out.println(names);

Mapping fonksiyonunun çağrılmadığına dikkat edin. Öyle olsaydı, bir NullPointerException'ımız olurdu. merge işlevi, yalnızca aralarında karar verilecek iki gerçek value olduğunda kullanılır.

merge() hakkında bilinmesi gereken son şey, mapping fonksiyonu çağrıldığında ve null döndürdüğünde ne olduğudur. Bu gerçekleştiğinde key map'den kaldırılır.

BiFunction<String, String, String> mapper = (v1, v2) -> null;
Map<String, String> names = new HashMap<>();
names.put("Umut", "Çakmak");
names.put("Gökhan", "Çakmak");
names.merge("Umut", "can", mapper);
names.merge("Ahmet", "can", mapper);
System.out.println(names);

// {Ahmet=can, Gökhan=Çakmak}

TreeMap

key’leri sıralayan bir Map gerçekleştirmesidir.

TreeMap , hem SortedMap hemde NavigableMap’tir.

TreeMap key olarak null’a izin vermez ama value olarak null’a izin verir.

Map<String, String> treeMap = new TreeMap<>();
treeMap.put("Umut" , "Çakmak");
treeMap.put("Gökhan" , "Çakmak");

String persons = treeMap.get("umut");
    for (String key : treeMap.keySet())
        System.out.println("TreeMap :" + key + " ,");

// TreeMap :Gökhan ,
// TreeMap :Umut ,

Queue

Öğeler belirli bir sırayla eklendiğinde ve kaldırıldığında bir kuyruk kullanabilirsiniz.

Kuyruklar genellikle öğeleri işlemeden önce sıralamak için kullanılır.

Aksi belirtilmedikçe, bir kuyruğun FIFO (ilk giren ilk çıkar) olduğu varsayılır.

Queue<Integer> integerQueue = new LinkedList<>();
System.out.println(integerQueue.offer(1)); // Kuyruğun arkasına bir öğe ekler ve başarılı olup olmadığını döndürür

System.out.println(integerQueue.offer(10));
System.out.println(integerQueue.peek()); // Bir sonraki öğeyi döndürür veya boş sıra varsa null değerini döndürür

System.out.println("QUEUE " + integerQueue);

System.out.println("then pool " + integerQueue.poll()); // Bir sonraki öğeyi kaldırır ve döndürür veya sıra boşsa null değerini döndürür
System.out.println("peek : " + integerQueue.peek()); // bir kuyruğun ilk öğesine bakmaya çalışır
System.out.println("remove : " + integerQueue.remove()); // Bir sonraki öğeyi kaldırır ve döndürür veya sıra boşsa bir istisna atar
System.out.println("QUEUE " + integerQueue);
System.out.println("add :" + integerQueue.add(4)); // Kuyruğun arkasına bir öğe ekler ve true değerini döndürür veya bir istisna atar
System.out.println("element : " + integerQueue.element());  //Sıra boşsa bir sonraki öğeyi döndürür veya bir istisna atar.

true
true
1
QUEUE [1, 10]
then pool 1
peek : 10
remove : 10
QUEUE []
add :true
element : 4

Math APIs

Matematik hesaplamalarının yapıldığı apidir.

min() ve max() metotları iki değeri karşılaştırır ve bunlardan birini döndürür.

int first = Math.max(3, 7); // 7
int second = Math.min(7, -9); // -9

round()

Round() yöntemi, bir sonraki uygun sayıyı seçerek değerin ondalık kısmından kurtulur. Kesirli kısım .5 veya daha yüksekse,yukarıya yuvarlar.

long low = Math.round(123.45); // 123
long high = Math.round(123.50); // 124
int fromFloat = Math.round(123.45f); // 123

pow()

pow() methodu üsleri işler.

double squared = Math.pow(5, 2); // 25.0

random()

random() methodu, 0'dan büyük, 0'a eşit ve 1'den küçük rastgele bir değer döndürür.

double num = Math.random();

Umarım faydalı olmuştur.