JavaRush /Java блогы /Random-KK /Java тіліндегі карта туралы 9 басты сұрақ
Treefeed
Деңгей

Java тіліндегі карта туралы 9 басты сұрақ

Топта жарияланған
Еске салайық, Карта кілт-мән жұптарының жиынынан тұратын құрылымдық деректер болып табылады және әрбір кілт бір Картада тек бір рет пайдаланылуы мүмкін. Бұл тақырып Java және оның енгізілген сыныптарында Map пайдалану туралы 9 негізгі сұрақты қамтиды . Қарапайымдылық үшін мен мысалдарда жалпылауды қолданамын . Сондықтан мен Map спецификаторын көрсетпей, жай ғана Карта деп жазамын. Бірақ сіз K және V мәндерінің екеуі де салыстырмалы деп болжауға болады, яғни K Comparable кеңейтеді және V да Comparable кеңейтеді .Java тіліндегі карта туралы 9 басты сұрақ - 1

0. Картаны тізімге түрлендіру

Java тілінде Map интерфейсі жинақтардың үш түрін ұсынады: кілттер жинағы, мәндер жиыны және кілттер-мәндер жинағы. Олардың барлығын конструктор немесе әдіс арқылы ТізімгеaddAll() айналдыруға болады . Келесі code үзіндісі картадан ArrayList жасау жолын көрсетеді.
// 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. Картадағы барлық мәндерді айналдырыңыз

Әрбір кілт-мән жұбын аралау Карта арқылы өтудің ең негізгі, негізгі proceduresасы болып табылады. Java тілінде әрбір жұп Map.Entry деп аталатын Карта өрісінде сақталады . Map.entrySet()кілт-мәндер жинағын қайтарады, сондықтан Картаның барлық мәндері арқылы қайталаудың ең тиімді жолы:
for(Entry entry: Map.entrySet()) {
  //get the key
  K key = entry.getKey();
  //get value
  V value = entry.getValue();
}
IteratorБіз сонымен қатар , әсіресе JDK 1.5 нұсқасынан кіші нұсқаларда пайдалана аламыз
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. Картаға пернелер арқылы тапсырыс беру

Карталарды пернелер арқылы ұйымдастыру - тағы бір жиі қолданылатын proceduresа. Бірінші жол - тізімге Map.Entry қосу және мәндер бойынша сұрыптайтын компаратор арқылы сұрыптау.
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());
  }
});
Басқа әдіс: SortedMap пайдаланыңыз , ол сонымен қатар өз кілттерін ретімен реттейді. Бірақ, барлық кілттер Comparable болуы керек немесе компаратормен қабылдануы керек. Іске асырылған сыныптардың бірі TreeMapSortedMap болып табылады . Оның конструкторы компараторды қабылдайды. Келесі code қалыпты codeты реттелгенге қалай айналдыру керектігін көрсетеді. Map
SortedMap sortedMap = new TreeMap(new Comparator() {

  @Override
  public int compare(K k1, K k2) {
    return k1.compareTo(k2);
  }

});
sortedMap.putAll(Map);

3. Мәндер бойынша картаға тапсырыс беріңіз

Картаны тізімге қосу, содан кейін оны сұрыптау бұл жағдайда жұмыс істейді, бірақ бұл жолы пайдалану керек Entry.getValue(). Төмендегі code бұрынғыға ұқсас.
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());
  }

});
Бұл жағдайда біз оны әлі де пайдалана аламыз SortedMap, бірақ мәндер бірегей болса ғана. Бұл жағдайда кілт-мән жұбын кілт-мәнге айналдыруға болады. Бұл шешімнің қатаң шектеулері бар және мен оны ұсынбаймын.

4. Статикалық/өзгермейтін картаны инициализациялау

Картаның өзгермейтін болып қалуын қаласаңыз, оны өзгермейтін Картаға көшіру жақсы әдіс болып табылады. Бұл қорғаныстық бағдарламалау техникасы пайдалану үшін қауіпсіз ғана емес, сонымен қатар ағынмен қауіпсіз Картаны жасауға көмектеседі. Статикалық/өзгермейтін Картаны инициализациялау үшін біз инициализаторды пайдалана аламыз static(төменде қараңыз). Бұл codeтың мәселесі мынада, Map ретінде жарияланғанымен static final, біз онымен инициализациядан кейін де жұмыс істей аламыз, мысалы Test.Map.put(3,"three");. Сондықтан бұл нақты өзгермейтін емес. Статикалық инициализаторды пайдаланып өзгермейтін Картаны жасау үшін бізге соңғы инициализация қадамында өзгермейтін Картаға қосатын супер анонимді класс қажет. Кодтың екінші бөлігін қараңыз. Егер сіз іске қоссаңыз, UnsupportedOperationExceptionTest.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);
  }
}
Гуава кітапханасы сонымен қатар статикалық және өзгермейтін жинақтарды инициализациялаудың әртүрлі жолдарын қолдайды. Гуаваның өзгермейтін жинақтар утorтасының артықшылықтары туралы қосымша ақпарат алу үшін Guava әдісі бөліміндегі Өзгермейтін жинақтар бөлімін қараңыз .

5. HashMap, TreeMap және Hashtable арасындағы айырмашылық

Java тілінде Map интерфейсінің үш негізгі іске асырылуы бар : HashMap , TreeMap және Hashtable . Негізгі айырмашылықтар келесідей:
  • Өту тәртібі . HashMap және HashTable Картаны ретке келтіруге кепілдік бермейді; атап айтқанда, олар уақыт өте келе тәртіп өзгеріссіз қалатынына кепілдік бермейді. Бірақ TreeMapол барлық мәндерді пернелердің «табиғи реті» бойынша немесе компаратор арқылы реттейді.
  • Жарамды кілт-мән жұптары. HashMapнөлдік кілт пен нөлдік мәнге ие болуға мүмкіндік береді. HashTableнөлдік кілтке немесе нөлдік мәнге рұқсат бермейді. Табиғи тәртіп пайдаланылса TreeMapнемесе компаратор нөлдік кілтке рұқсат бермесе, ерекше жағдай шығарылады.
  • Синхрондау . Тек HashTableсинхрондалған, қалғандары жоқ. Бірақ, "егер ағынды қауіпсіз енгізу қажет болмаса, оның HashMapорнына " пайдалану ұсынылады HashTable.
Толығырақ салыстыру
.                       | HashMap | HashTable | TreeMap
-------------------------------------------------------

Упорядочивание          |нет      |нет        | да
null в ключ-meaning    | да-да   | нет-нет   | нет-да
синхронизировано        | нет     | да        | нет
производительность      | O(1)    | O(1)      | O(log n)
воплощение              | корзины | корзины   | красно-чёрное дерево
HashMap қатынасы туралы толығырақ оқыңыз . TreeMap қарсы Хэштабельге қарсы LinkedHashMap .

6. Кері іздеу/көрініс бар карта

Кейде бізге кілт-кілт жұптарының жиынтығы қажет, яғни мәндер кілттер сияқты бірегей (бірден-бір үлгі). Бұл жүйелілік Картада «инверттелген көрініс/іздеу» жасауға мүмкіндік береді. Яғни, оның мәні бойынша кілтті таба аламыз. Бұл деректер құрылымы екі бағытты карта деп аталады , өкінішке орай, JDK оны қолдамайды. Apache Common Collections да, Guava да сәйкесінше BidiMap және BiMap деп аталатын екі бағытты Map іске асыруды ұсынады. Екеуі де кілттер мен мәндер арасында 1:1 салыстыруды қамтамасыз ететін шектеуді енгізеді.

7. Картаның таяз көшірмесі

Java тіліндегі карталардың барлығы болмаса да, барлығы дерлік басқа Карта үшін көшіру конструкторын қамтиды. Бірақ көшіру proceduresасы синхрондалмаған. Яғни, бір ағын Картаны көшірсе, басқа ағын оның құрылымын өзгерте алады. Көшірменің кенеттен десинхронизациясын болдырмау үшін мұндай жағдайда олардың біреуін пайдалану керек Collections.synchronizedMap().
Map copiedMap = Collections.synchronizedMap(Map);
Таяз көшірудің тағы бір қызықты тәсілі - пайдалану clone(). Бірақ оны тіпті Java жинақтарының негізін жасаушы Джошуа Блох ұсынбайды. « Көшіру конструкторы және клондау » пікірталасында ол келесі позицияны ұстанады: Дәйексөз: «Мен көбінесе нақты сыныптарда жалпыға ортақ клондау әдісін ұсынамын, өйткені адамдар олардың сонда болуын күтеді. ... Клондау бұзылғаны ұят, бірақ ол болды... Клондау – әлсіз жер және менің ойымша, адамдарға оның шектеулері туралы ескерту керек». clone()Осы себепті мен сізге Картаны көшіру әдісін қалай пайдалану керектігін көрсетпеймін

8. Бос Картаны жасаңыз

Егер Mapөзгермейтін болса, пайдаланыңыз:
Map = Collections.emptyMap();
Немесе кез келген басқа нұсқаны пайдаланыңыз. Мысалы:
Map = new HashMap();
Соңы
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION