19. Generics¶
Oldingi bobda Collections bilan tanishdik.
Masalan:
ArrayList<String> ismlar = new ArrayList<>();
Bu yerda String oddiy ma'lumot turi emas, balki ArrayList ichida qanday turdagi ma'lumot saqlanishini bildiradi.
Bu tushuncha Generics deb ataladi.
Generics nima?¶
Generics — class, interface va methodlarni ma'lum bir data type bilan xavfsiz ishlashga imkon beradigan Java mexanizmi.
Masalan:
ArrayList<String> ismlar = new ArrayList<>();
Bu ArrayList faqat String saqlashini bildiradi.
Quyidagi kod ishlamaydi:
ismlar.add(100);
Chunki 100 — Integer, ismlar esa String uchun yaratilgan.
Nima uchun Generics kerak?¶
Genericsning asosiy afzalligi — type safety.
Masalan, genericsiz:
ArrayList list = new ArrayList();
list.add("Ali");
list.add(100);
list.add(true);
Bitta list ichida turli xil ma'lumotlar paydo bo‘ldi.
Keyinchalik qaysi element qanday type ekanini tekshirishga to‘g‘ri keladi.
Generics bilan:
ArrayList<String> list = new ArrayList<>();
list.add("Ali");
list.add("Vali");
list.add("Hasan");
Endi Java list faqat String saqlashini biladi.
Generic type belgisi¶
Ko‘pincha generic type uchun T harfi ishlatiladi.
Masalan:
class Box<T> {
T qiymat;
}
Bu yerda T keyinchalik qanday type bo‘lishini bildiradi.
Generic class¶
O‘zimiz generic class yaratishimiz mumkin.
class Box<T> {
private T qiymat;
public void set(T qiymat) {
this.qiymat = qiymat;
}
public T get() {
return qiymat;
}
}
Endi Box bilan String ishlatamiz:
Box<String> box = new Box<>();
box.set("Salom");
System.out.println(box.get());
Natija:
Salom
Integer bilan ham ishlatish mumkin:
Box<Integer> box = new Box<>();
box.set(100);
System.out.println(box.get());
Natija:
100
Bitta class turli type bilan ishlayapti.
Generic classning to‘liq misoli¶
class Box<T> {
private T qiymat;
public Box(T qiymat) {
this.qiymat = qiymat;
}
public T get() {
return qiymat;
}
}
Keyin:
public class Main {
public static void main(String[] args) {
Box<String> matn = new Box<>("Salom");
Box<Integer> son = new Box<>(100);
System.out.println(matn.get());
System.out.println(son.get());
}
}
Natija:
Salom
100
Bir nechta generic type¶
Generic class bir nechta type qabul qilishi mumkin.
Masalan:
class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}
Endi:
Pair<String, Integer> odam = new Pair<>("Ali", 25);
Bu yerda:
K → String
V → Integer
Key:
Ali
Value:
25
Generic method¶
Method ham generic bo‘lishi mumkin.
Masalan:
public static <T> void print(T qiymat) {
System.out.println(qiymat);
}
Endi:
print("Salom");
print(100);
print(3.14);
Natija:
Salom
100
3.14
Method turli type bilan ishlayapti.
Generic methodning to‘liq misoli¶
public class Main {
public static <T> void print(T qiymat) {
System.out.println(qiymat);
}
public static void main(String[] args) {
print("Salom");
print(100);
print(true);
}
}
Generic type nomlari¶
Java'da generic type uchun odatda quyidagi harflar ishlatiladi:
T → Type
E → Element
K → Key
V → Value
N → Number
Masalan:
class Box<T> {
}
yoki:
class Pair<K, V> {
}
Bu nomlar majburiy emas.
Masalan, T o‘rniga X yozish ham mumkin:
class Box<X> {
X qiymat;
}
Lekin Java dasturchilari odatda standart nomlardan foydalanadilar.
Generics va primitive type¶
Generics bilan primitive type ishlatib bo‘lmaydi.
Masalan, bu noto‘g‘ri:
ArrayList<int> sonlar = new ArrayList<>();
Buning o‘rniga wrapper class ishlatiladi:
ArrayList<Integer> sonlar = new ArrayList<>();
Xuddi shunday:
int → Integer
double → Double
float → Float
boolean → Boolean
char → Character
long → Long
Masalan:
ArrayList<Integer> sonlar = new ArrayList<>();
sonlar.add(10);
sonlar.add(20);
sonlar.add(30);
Generic va type safety¶
Generics koddagi xatolarni oldindan aniqlashga yordam beradi.
Masalan:
ArrayList<String> ismlar = new ArrayList<>();
ismlar.add("Ali");
ismlar.add("Vali");
Keyin:
String ism = ismlar.get(0);
Bu xavfsiz, chunki Java ismlar ichida faqat String borligini biladi.
Generics Collections bilan¶
Generics eng ko‘p Collections bilan ishlatiladi.
Masalan:
ArrayList<String> ismlar = new ArrayList<>();
HashSet<Integer> sonlar = new HashSet<>();
HashMap<String, Integer> yoshlar = new HashMap<>();
Bu yerda:
ArrayList<String>
faqat String saqlaydi.
HashSet<Integer>
faqat Integer saqlaydi.
HashMap<String, Integer>
esa String key va Integer value saqlaydi.
Real hayotdagi misol¶
Tasavvur qiling, sizda mahsulotlar bilan ishlaydigan dastur bor.
class Product {
String name;
double price;
Product(String name, double price) {
this.name = name;
this.price = price;
}
}
Mahsulotlar ro‘yxatini yaratamiz:
ArrayList<Product> products = new ArrayList<>();
Endi:
products.add(new Product("Laptop", 1000));
products.add(new Product("Phone", 700));
products.add(new Product("Mouse", 30));
Bu yerda Java products faqat Product obyektlarini saqlashini biladi.
Genericsning asosiy foydalari¶
Generics:
- Type safety beradi.
- Kodni qayta ishlatishga yordam beradi.
- Type castingni kamaytiradi.
- Collections bilan xavfsiz ishlash imkonini beradi.
- Generic class va methodlar yaratish imkonini beradi.
Amaliy mashqlar¶
1-mashq¶
Quyidagi generic classni yarating:
class Box<T> {
T qiymat;
}
String va Integer bilan ishlatib ko‘ring.
2-mashq¶
Pair<K, V> generic class yarating.
Unda key va value bo‘lsin.
Masalan:
Pair<String, Integer>
ko‘rinishida foydalaning.
3-mashq¶
Generic method yarating:
public static <T> void print(T qiymat)
Uni String, Integer va Double bilan chaqiring.
4-mashq¶
Quyidagi Collectionslarni yarating:
ArrayList<String>
HashSet<Integer>
HashMap<String, Double>
Har biriga mos ma'lumotlar qo‘shing.
Muhim narsalarni eslab qoling¶
Generics — type bilan xavfsiz va qayta ishlatiladigan kod yozish imkonini beradi.
Generic class:
class Box<T> {
}
Generic object:
Box<String> box = new Box<>();
Bir nechta type:
class Pair<K, V> {
}
Generic method:
public static <T> void print(T qiymat) {
}
Collections bilan:
ArrayList<String>
HashSet<Integer>
HashMap<String, Integer>
Generics Java'da katta dasturlar yozishda juda muhim tushuncha hisoblanadi.