Eslatib o'tamiz, Xarita kalit-qiymat juftliklari to'plamidan iborat tuzilgan ma'lumotlardir va har bir kalit bitta Xaritada faqat bir marta ishlatilishi mumkin. Ushbu mavzu Java va uning amalga oshirilgan sinflarida Mapdan foydalanish bo'yicha 9 ta asosiy savolni o'z ichiga oladi . Oddiylik uchun men misollarda umumlashmalardan foydalanaman . Shuning uchun, men Map spetsifikatsiyasini ko'rsatmasdan, oddiygina Xarita yozaman. Ammo siz K va V ning ikkala qiymatini solishtirish mumkin deb taxmin qilishingiz mumkin, ya'ni K taqqoslanadigan va V ham taqqoslanadigan ni kengaytiradi .
0. Xaritani ro‘yxatga aylantirish
Java-da Map interfeysi uchta turdagi to'plamlarni taklif qiladi: kalitlar to'plami, qiymatlar to'plami va kalit-qiymatlar to'plami. Ularning barchasi konstruktor yoki usul yordamida Ro'yxatga aylantirilishi mumkinaddAll()
. Quyidagi kod parchasi Xaritadan ArrayListni qanday yaratishni ko'rsatadi.
// list of keys
List keyList = new ArrayList(Map.keySet());
//list of values
List valueList = new ArrayList(Map.valueSet());
//list key-value
List entryList = new ArrayList(Map.entrySet());
1. Xaritadagi barcha qiymatlarni aylantiring
Har bir kalit-qiymat juftligi bo'ylab yurish Xarita bo'ylab yurishning eng asosiy, asosiy protsedurasidir. Java-da har bir juftlik Map.Entry deb nomlangan Xarita maydonida saqlanadi .Map.entrySet()
kalit-qiymatlar to'plamini qaytaradi, shuning uchun Xaritaning barcha qiymatlarini takrorlashning eng samarali usuli:
for(Entry entry: Map.entrySet()) {
//get the key
K key = entry.getKey();
//get value
V value = entry.getValue();
}
Iterator
Biz , ayniqsa, JDK 1.5 dan kichikroq versiyalarda ham foydalanishimiz mumkin
Iterator itr = Map.entrySet().iterator();
while(itr.hasNext()) {
Entry entry = itr.next();
//get the key
K key = entry.getKey();
//get value
V value = entry.getValue();
}
2. Xaritani kalitlar bo'yicha buyurtma qilish
Xaritalarni kalitlar bo'yicha tartibga solish yana bir keng tarqalgan protsedura hisoblanadi. Birinchi usul Map.Entry ni roʻyxatga qoʻshish va qiymatlar boʻyicha saralovchi komparator yordamida tartiblashdir.List list = new ArrayList(Map.entrySet());
Collections.sort(list, new Comparator() {
@Override
public int compare(Entry e1, Entry e2) {
return e1.getKey().compareTo(e2.getKey());
}
});
Boshqa yo'l: SortedMap dan foydalaning , u qo'shimcha ravishda uning kalitlarini tartibda tartibga soladi. Biroq, barcha kalitlar Comparable ni o'z ichiga olishi yoki solishtiruvchi tomonidan qabul qilinishi kerak. Amalga oshirilgan sinflardan biri SortedMap
TreeMap . Uning konstruktori komparatorni qabul qiladi. Quyidagi kod oddiyni qanday qilib Map
buyurtma qilinganga aylantirishni ko'rsatadi.
SortedMap sortedMap = new TreeMap(new Comparator() {
@Override
public int compare(K k1, K k2) {
return k1.compareTo(k2);
}
});
sortedMap.putAll(Map);
3. Xaritani qiymatlar bo‘yicha tartiblash
Roʻyxatga Xarita qoʻshish va keyin uni saralash bu holatda ishlaydi, lekin bu safar dan foydalanishingiz kerakEntry.getValue()
. Quyidagi kod avvalgidek deyarli bir xil.
List list = new ArrayList(Map.entrySet());
Collections.sort(list, new Comparator() {
@Override
public int compare(Entry e1, Entry e2) {
return e1.getValue().compareTo(e2.getValue());
}
});
Bu holatda biz undan foydalanishimiz mumkin SortedMap
, ammo qiymatlar noyob bo'lsa. Bunday holda siz kalit-qiymat juftligini kalit-qiymatga aylantirishingiz mumkin. Ushbu yechim jiddiy cheklovlarga ega va men tomonidan tavsiya etilmaydi.
4. Statik/o‘zgarmas xaritani ishga tushirish
Xarita o'zgarmas bo'lishini istasangiz, uni o'zgarmas Xaritaga nusxalash yaxshi usuldir. Ushbu mudofaa dasturlash texnikasi sizga nafaqat foydalanish uchun xavfsiz, balki iplar uchun ham xavfsiz Xarita yaratishga yordam beradi. Statik/o‘zgarmas xaritani ishga tushirish uchun biz initsializatordan foydalanishimiz mumkinstatic
(pastga qarang). Ushbu kod bilan bog'liq muammo shundaki, Map deb e'lon qilingan bo'lsa ham static final
, ishga tushirilgandan so'ng biz u bilan ishlashimiz mumkin, masalan Test.Map.put(3,"three");
. Demak, bu haqiqiy o'zgarmaslik emas. Statik ishga tushirgich yordamida o'zgarmas Xarita yaratish uchun bizga oxirgi ishga tushirish bosqichida o'zgarmas xaritaga qo'shiladigan o'ta anonim sinf kerak bo'ladi. Iltimos, kodning ikkinchi qismiga qarang. Agar ishga tushirsangiz, UnsupportedOperationException tashlanadi qachon Test.Map.put(3,"three");
.
public class Test {
private static final Map Map;
static {
Map = new HashMap();
Map.put(1, "one");
Map.put(2, "two");
}
}
public class Test {
private static final Map Map;
static {
Map aMap = new HashMap();
aMap.put(1, "one");
aMap.put(2, "two");
Map = Collections.unmodifiableMap(aMap);
}
}
Guava kutubxonasi shuningdek, statik va o'zgarmas to'plamlarni ishga tushirishning turli usullarini qo'llab-quvvatlaydi. Guavaning oʻzgarmas toʻplamlar yordam dasturining afzalliklari haqida koʻproq maʼlumot olish uchun Guavaning “Oʻzgarmas toʻplamlar” boʻlimiga qarang .
5. HashMap, TreeMap va Hashtable o'rtasidagi farq
Java-da Map interfeysining uchta asosiy ilovasi mavjud : HashMap , TreeMap va Hashtable . Asosiy farqlar quyidagilardan iborat:- O'tish tartibi . HashMap va HashTable Xarita tartibini kafolatlamaydi; xususan, ular buyurtma vaqt o'tishi bilan bir xil bo'lib qolishiga kafolat bermaydi. Ammo
TreeMap
u barcha qiymatlarni kalitlarning "tabiiy tartibida" yoki taqqoslash vositasida buyurtma qiladi. - Yaroqli kalit-qiymat juftliklari.
HashMap
null kalit va null qiymatga ega bo'lish imkonini beradi.HashTable
null kalit yoki null qiymatga ruxsat bermaydi. AgarTreeMap
tabiiy tartib ishlatilsa yoki taqqoslagich null kalitga ruxsat bermasa, istisno chiqariladi. - Sinxronizatsiya . Faqat
HashTable
sinxronlashtiriladi, qolganlari yo'q. Biroq, "agar ip bilan xavfsiz dastur kerak bo'lmasa, uningHashMap
o'rniga " dan foydalanish tavsiya etiladiHashTable
.
. | HashMap | HashTable | TreeMap
-------------------------------------------------------
Упорядочивание |нет |нет | да
null в ключ-meaning | да-да | нет-нет | нет-да
синхронизировано | нет | да | нет
производительность | O(1) | O(1) | O(log n)
воплощение | корзины | корзины | красно-чёрное дерево
HashMap va boshqalar munosabatlari haqida ko'proq o'qing . TreeMap va boshqalar. Hashtable vs. LinkedHashMap .
6. Teskari qidiruv/ko'rish bilan xarita
Ba'zan bizga kalit-kalit juftliklari to'plami kerak bo'ladi, ya'ni qiymatlar kalitlar kabi noyobdir (birma-bir naqsh). Ushbu izchillik Xaritada "teskari ko'rinish/qidiruv" yaratish imkonini beradi. Ya'ni, biz kalitni uning qiymatiga qarab topishimiz mumkin. Ushbu ma'lumotlar strukturasi ikki tomonlama xarita deb ataladi , afsuski, JDK tomonidan qo'llab-quvvatlanmaydi. Ikkala Apache Common Collections ham, Guava ham mos ravishda BidiMap va BiMap deb nomlangan ikki tomonlama xarita dasturlarini taklif qiladi. Ikkalasi ham kalitlar va qiymatlar o'rtasida 1: 1 xaritalashni amalga oshiradigan cheklovni joriy qiladi.7. Xaritaning sayoz nusxasi
Hammasi bo'lmasa ham, deyarli barchasi Java-dagi Xaritalarda boshqa Xarita uchun nusxa ko'chirish konstruktori mavjud. Ammo nusxa ko'chirish jarayoni sinxronlashtirilmaydi. Bu shuni anglatadiki, bir ip Xaritadan nusxa ko'chirsa, boshqa ip uning tuzilishini o'zgartirishi mumkin. To'satdan nusxa ko'chirish desinxronizatsiyasini oldini olish uchun bunday holatda ulardan birini ishlatish kerakCollections.synchronizedMap()
.
Map copiedMap = Collections.synchronizedMap(Map);
Sayoz nusxa ko'chirishning yana bir qiziqarli usuli dan foydalanishdir clone()
. Ammo buni hatto Java to'plamlari ramkasini yaratuvchisi Joshua Bloch ham tavsiya etmaydi. " Nusxalash konstruktori va klonlash " bahsida u shunday pozitsiyani egallaydi: Iqtibos: "Men ko'pincha aniq sinflarda ommaviy klonlash usulini taqdim etaman, chunki odamlar u erda bo'lishini kutishadi. ... Klonlash buzilganligi sharmandalik, lekin bu sodir bo'ldi. ... Klonlash zaif nuqta va menimcha, odamlar uning cheklovlari haqida ogohlantirilishi kerak." clone()
Shu sababli, men sizga Xaritani nusxalash usulidan qanday foydalanishni ham ko'rsatmayman
8. Bo'sh Xarita yarating
AgarMap
o'zgarmas bo'lsa, foydalaning:
Map = Collections.emptyMap();
Yoki har qanday boshqa variantdan foydalaning. Masalan:
Map = new HashMap();
OXIRI
GO TO FULL VERSION