12-bo‘lim
Kolleksiyalar
List, Set, Map va Deque interfeyslari, ArrayList va LinkedList, HashMap tartibi tuzog'i, o'zgarmas kolleksiyalar va qaysi birini tanlash.
Ushbu bo‘lim mundarijasi
Kolleksiya - obyektlar to'plami. Java'ning kolleksiyalar kutubxonasi katta va yaxshi o'ylangan; uni bilish kundalik ishning yarmini tashkil qiladi.
Uchta asosiy oila #
List #
import java.util.ArrayList;
import java.util.List;
public class Royxat {
public static void main(String[] args) {
List<String> talabalar = new ArrayList<>();
talabalar.add("Husanboy");
talabalar.add("Malika");
talabalar.add("Nodira");
talabalar.add(0, "Kamola");
talabalar.remove("Malika");
System.out.println("Soni: " + talabalar.size());
System.out.println(talabalar);
System.out.println("Nodira bormi: " + talabalar.contains("Nodira"));
System.out.println("Birinchi: " + talabalar.get(0));
System.out.println("Nodira o'rni: " + talabalar.indexOf("Nodira"));
}
}
Soni: 3
[Kamola, Husanboy, Nodira]
Nodira bormi: true
Birinchi: Kamola
Nodira o'rni: 2
| Metod | Vazifasi |
|---|---|
add(x) | Oxiriga qo'shadi |
add(i, x) | Berilgan o'ringa qo'yadi |
get(i) | Indeks bo'yicha oladi |
set(i, x) | Almashtiradi |
remove(x) / remove(i) | O'chiradi |
removeIf(shart) | Shartga mos hammasini o'chiradi |
size() | Nechta element |
contains(x) | Bormi |
isEmpty() | Bo'shmi |
remove(int) va remove(Object)List<Integer> bilan ishlaganda bu juda chalkash:
import java.util.ArrayList;
import java.util.List;
public class Ogoh {
public static void main(String[] args) {
List<Integer> a = new ArrayList<>(List.of(10, 20, 30));
a.remove(1); // INDEKS bo'yicha
System.out.println("remove(1): " + a);
List<Integer> b = new ArrayList<>(List.of(10, 20, 30));
b.remove(Integer.valueOf(10)); // QIYMAT bo'yicha
System.out.println("remove(valueOf(10)): " + b);
}
}
remove(1): [10, 30]
remove(valueOf(10)): [20, 30]
Birinchisi indeks 1 ni o'chirdi (ya'ni 20), ikkinchisi esa
qiymat 10 ni.
Sabab: List da ikkita remove bor - remove(int index) va
remove(Object o). int berilganda birinchisi tanlanadi.
Qiymat bo'yicha o'chirish uchun Integer.valueOf(x) yoki
(Integer) x yozing.
ArrayList va LinkedList #
import java.util.*;
public class Ikki {
public static void main(String[] args) {
List<String> a = new ArrayList<>(List.of("bir", "ikki"));
List<String> b = new LinkedList<>(List.of("bir", "ikki"));
a.add("uch");
b.add(0, "nol");
System.out.println("ArrayList: " + a);
System.out.println("LinkedList: " + b);
System.out.println("Teng-mi: " + a.equals(new ArrayList<>(a)));
}
}
ArrayList: [bir, ikki, uch]
LinkedList: [nol, bir, ikki]
Teng-mi: true
ArrayList | LinkedList | |
|---|---|---|
| Ichki tuzilma | Massiv | Bog'langan ro'yxat |
get(i) | Juda tez | Sekin - boshidan sanaydi |
| Oxiriga qo'shish | Tez | Tez |
| O'rtaga qo'shish | Sekin - siljitadi | Tez |
| Xotira | Kamroq | Har element uchun qo'shimcha |
LinkedList nazariy jihatdan o'rtaga qo'shishda tezroq, lekin
amalda u kamdan-kam foydali.
Sababi: zamonaviy protsessorlar ketma-ket joylashgan xotira bilan
ancha tez ishlaydi. ArrayList elementlari yonma-yon turadi,
LinkedList niki esa xotira bo'ylab sochilgan.
Natijada ArrayList ko'p hollarda hatto o'rtaga qo'shishda ham
tezroq chiqadi.
Qoida: ArrayList dan boshlang. LinkedList ni faqat o'lchab,
haqiqatan foyda berishini ko'rsangiz ishlating.
Map #
import java.util.LinkedHashMap;
import java.util.Map;
public class Lugat {
public static void main(String[] args) {
Map<String, Integer> aholi = new LinkedHashMap<>();
aholi.put("Namangan", 626000);
aholi.put("Andijon", 441000);
aholi.put("Chust", 68000);
aholi.put("Namangan", 630000); // eskisini almashtiradi
System.out.println("Shaharlar soni: " + aholi.size());
System.out.println("Namangan: " + aholi.get("Namangan"));
System.out.println("Buxoro: " + aholi.get("Buxoro"));
System.out.println("Buxoro (sukut): "
+ aholi.getOrDefault("Buxoro", 0));
System.out.println("Chust bormi: " + aholi.containsKey("Chust"));
for (Map.Entry<String, Integer> yozuv : aholi.entrySet()) {
System.out.printf(" %-10s %8d%n",
yozuv.getKey(), yozuv.getValue());
}
}
}
Shaharlar soni: 3
Namangan: 630000
Buxoro: null
Buxoro (sukut): 0
Chust bormi: true
Namangan 630000
Andijon 441000
Chust 68000
Yuqorida ataylab LinkedHashMap ishlatildi. Oddiy HashMap
bo'lganida chiqish tartibi boshqacha bo'lardi:
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
public class Tartib {
public static void main(String[] args) {
String[] shaharlar =
{"Namangan", "Andijon", "Samarqand", "Toshkent"};
Map<String, Integer> xesh = new HashMap<>();
Map<String, Integer> bogliq = new LinkedHashMap<>();
for (int i = 0; i < shaharlar.length; i++) {
xesh.put(shaharlar[i], i);
bogliq.put(shaharlar[i], i);
}
String kiritilgan = String.join(", ", shaharlar);
System.out.println("Kiritilgan tartib: " + kiritilgan);
System.out.println("LinkedHashMap mos: "
+ String.join(", ", bogliq.keySet()).equals(kiritilgan));
System.out.println("HashMap mos: "
+ String.join(", ", xesh.keySet()).equals(kiritilgan));
}
}
Kiritilgan tartib: Namangan, Andijon, Samarqand, Toshkent
LinkedHashMap mos: true
HashMap mos: false
HashMap elementlarni xesh kodiga qarab joylashtiradi. Tartib
tasodifiy emas, lekin u kiritish tartibiga ham, alifboga ham bog'liq
emas - va Java versiyasi o'zgarganda o'zgarishi mumkin.
Diqqat qiling: yuqoridagi misol HashMap ning aniq tartibini
chop etmaydi, faqat "kiritish tartibiga mos keladimi" degan savolga
javob beradi. Aniq tartibni da'vo qilib bo'lmaydi - u sizning
mashinangizda boshqacha bo'lishi mumkin.
Qoida: tartib muhim bo'lsa - LinkedHashMap (kiritish
tartibi) yoki TreeMap (kalit bo'yicha saralangan).
TreeMap - saralangan #
import java.util.Map;
import java.util.TreeMap;
public class Saralangan {
public static void main(String[] args) {
Map<String, Integer> aholi = new TreeMap<>();
aholi.put("Namangan", 626000);
aholi.put("Andijon", 441000);
aholi.put("Samarqand", 551000);
System.out.println(aholi.keySet());
TreeMap<String, Integer> daraxt = new TreeMap<>(aholi);
System.out.println("Birinchi kalit: " + daraxt.firstKey());
System.out.println("Oxirgi kalit: " + daraxt.lastKey());
}
}
[Andijon, Namangan, Samarqand]
Birinchi kalit: Andijon
Oxirgi kalit: Samarqand
Foydali Map metodlari #
import java.util.LinkedHashMap;
import java.util.Map;
public class MapMetodlar {
public static void main(String[] args) {
Map<String, Integer> hisob = new LinkedHashMap<>();
String[] sozlar = {"olma", "behi", "olma", "uzum", "olma"};
for (String soz : sozlar) {
hisob.merge(soz, 1, Integer::sum);
}
System.out.println("merge bilan: " + hisob);
Map<String, Integer> boshqa = new LinkedHashMap<>();
for (String soz : sozlar) {
boshqa.put(soz, boshqa.getOrDefault(soz, 0) + 1);
}
System.out.println("getOrDefault: " + boshqa);
hisob.putIfAbsent("anor", 1);
hisob.computeIfPresent("olma", (k, v) -> v * 10);
System.out.println("Yakuniy: " + hisob);
}
}
merge bilan: {olma=3, behi=1, uzum=1}
getOrDefault: {olma=3, behi=1, uzum=1}
Yakuniy: {olma=30, behi=1, uzum=1, anor=1}
merge - sanash uchun eng qisqa usul: kalit yo'q bo'lsa 1 qo'yadi,
bor bo'lsa funksiya bilan birlashtiradi.
Set #
import java.util.*;
public class Toplam {
public static void main(String[] args) {
Set<String> a = new LinkedHashSet<>(
List.of("Namangan", "Andijon", "Samarqand"));
boolean qoshildi = a.add("Andijon");
System.out.println("Qayta qo'shildimi: " + qoshildi);
System.out.println("Soni: " + a.size());
Set<String> b = new LinkedHashSet<>(List.of("Andijon", "Buxoro"));
Set<String> umumiy = new LinkedHashSet<>(a);
umumiy.retainAll(b);
System.out.println("Umumiy: " + umumiy);
Set<String> farq = new LinkedHashSet<>(a);
farq.removeAll(b);
System.out.println("Faqat a da: " + farq);
}
}
Qayta qo'shildimi: false
Soni: 3
Umumiy: [Andijon]
Faqat a da: [Namangan, Samarqand]
Deque - navbat va taxlam #
import java.util.ArrayDeque;
import java.util.Deque;
public class Navbat {
public static void main(String[] args) {
Deque<String> navbat = new ArrayDeque<>();
navbat.addLast("Husanboy");
navbat.addLast("Malika");
navbat.addLast("Nodira");
System.out.println("Navbatdan: " + navbat.pollFirst());
System.out.println("Keyingisi: " + navbat.peekFirst());
Deque<String> taxlam = new ArrayDeque<>();
taxlam.push("birinchi");
taxlam.push("ikkinchi");
taxlam.push("uchinchi");
System.out.println("Taxlamdan: " + taxlam.pop());
}
}
Navbatdan: Husanboy
Keyingisi: Malika
Taxlamdan: uchinchi
Stack sinfini ishlatmangJava'da eski Stack sinfi bor, lekin u eskirgan hisoblanadi: u
Vector dan meros olgan va har bir amalda keraksiz sinxronizatsiya
qiladi.
Rasmiy hujjatda ham ArrayDeque tavsiya etiladi. Taxlam kerak
bo'lsa - Deque, Stack emas.
O'zgarmas kolleksiyalar #
import java.util.List;
import java.util.Map;
public class Ozgarmas {
public static void main(String[] args) {
List<String> royxat = List.of("bir", "ikki", "uch");
Map<String, Integer> lugat = Map.of("bir", 1, "ikki", 2);
System.out.println(royxat);
System.out.println("Lug'atda 'bir': " + lugat.get("bir"));
try {
royxat.add("to'rt");
} catch (UnsupportedOperationException x) {
System.out.println("Istisno: " + x.getClass().getSimpleName());
}
}
}
[bir, ikki, uch]
Lug'atda 'bir': 1
Istisno: UnsupportedOperationException
List.of o'zgartirib bo'lmaydigan ro'yxat qaytaradiList.of(...), Map.of(...) va Set.of(...) - o'zgarmas
kolleksiya yaratadi. Unga element qo'shishga urinish istisno beradi.
Bu ataylab shunday: o'zgarmas kolleksiyalar xavfsizroq va tezroq.
O'zgartirish kerak bo'lsa, nusxa oling:
List<String> ozgaruvchan = new ArrayList<>(List.of("bir", "ikki"));
Yana bir tafsilot: Map.of va Set.of null qabul qilmaydi va
takroriy kalit berilsa istisno tashlaydi.
Qaysi birini tanlash #
| Ehtiyoj | Tanlov |
|---|---|
| Odatiy ro'yxat | ArrayList |
| Takrorlanmasin | HashSet |
| Takrorlanmasin + tartib | LinkedHashSet |
| Kalit bo'yicha qidirish | HashMap |
| Kalit bo'yicha + kiritish tartibi | LinkedHashMap |
| Kalit bo'yicha saralangan | TreeMap |
| Navbat yoki taxlam | ArrayDeque |
| O'zgarmas, kichik | List.of, Map.of |
ArrayListga element qo'shing, o'chiring va sanang.List<Integer>daremove(1)varemove(Integer.valueOf(1))farqini ko'ring.ArrayListvaLinkedListni bir xil amallar bilan solishtiring.HashMapvaLinkedHashMaptartibini tekshiring.TreeMapbilan kalitlarni saralab chiqaring.mergebilan so'zlarni sanang.getOrDefaultvaputIfAbsentni sinang.Setbilan kesishma va ayirmani hisoblang.ArrayDequeni navbat va taxlam sifatida ishlating.List.ofga element qo'shishga urinib, istisnoni ko'ring.
Xulosa #
- Uchta asosiy oila:
List(tartibli),Set(takrorsiz),Map(kalit-qiymat). List<Integer>daremove(int)indeks,remove(Object)qiymat bo'yicha o'chiradi.- Amalda deyarli har doim
ArrayList;LinkedListkamdan-kam foydali. HashMaptartibni saqlamaydi va uning tartibiga tayanmang -LinkedHashMapyokiTreeMapishlating.mergevagetOrDefaultsanash uchun eng qulay.- Taxlam uchun
ArrayDeque, eskirganStackemas. List.ofo'zgarmas ro'yxat qaytaradi - o'zgartirish uchun nusxa oling.
Keyingi bo'limda istisnolarni o'rganamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.