Java HashMap is een van de meest populaire Collection-klassen in Java. Java HashMap is een implementatie op basis van een hash-tabel. HashMap in Java breidt de AbstractMap-klasse uit die de Map-interface implementeert.
Java HashMap
Enkele belangrijke punten over HashMap in Java zijn:
- Java HashMap staat null-sleutel en null-waarden toe.
- HashMap is geen geordende collectie. U kunt itereren over HashMap-items via de set van sleutels, maar de volgorde waarin ze aan de HashMap zijn toegevoegd, is niet gegarandeerd.
- HashMap lijkt bijna op Hashtable, behalve dat het niet-gesynchroniseerd is en null-sleutels en -waarden toestaat.
- HashMap gebruikt zijn binnenklasse Node<K,V> voor het opslaan van map-items.
- HashMap slaat items op in meerdere enkelvoudig gelinkte lijsten, genaamd buckets of bins. Het standaard aantal bins is 16 en het is altijd een macht van 2.
- HashMap gebruikt hashCode() en equals() methoden op sleutels voor get- en put-operaties. Daarom moet het sleutelobject van HashMap een goede implementatie van deze methoden bieden. Dit is de reden waarom onveranderlijke klassen beter geschikt zijn voor sleutels, bijvoorbeeld String en Integer.
- Java HashMap is niet thread-safe, voor een multithreaded omgeving moet u de ConcurrentHashMap-klasse gebruiken of een gesynchroniseerde map verkrijgen met behulp van de
Collections.synchronizedMap()
-methode.
Java HashMap Constructoren
Java HashMap biedt vier constructoren.
- public HashMap(): Meest gebruikte HashMap-constructor. Deze constructor zal een lege HashMap maken met de standaard initiële capaciteit van 16 en een belastingsfactor van 0.75
- public HashMap(int initialCapacity): Deze HashMap-constructor wordt gebruikt om de initiële capaciteit en belastingsfactor van 0.75 te specificeren. Dit is handig om opnieuw hashen te vermijden als u het aantal toewijzingen aan de HashMap kent.
- public HashMap(int initialCapacity, float loadFactor): Deze HashMap-constructor zal een lege HashMap maken met de gespecificeerde initiële capaciteit en belastingsfactor. U kunt dit gebruiken als u het maximale aantal toewijzingen aan HashMap kent. In gebruikelijke scenario’s moet u dit vermijden omdat een belastingsfactor van 0.75 een goede afweging biedt tussen ruimte- en tijdkosten.
- public HashMap(Map<? extends K, ? extends V> m): Maakt een Map met dezelfde toewijzingen als de gespecificeerde map en met een belastingsfactor van 0.75
Java HashMap Constructoren Voorbeeld
Onderstaande codefragment toont een voorbeeld van het gebruik van alle bovenstaande constructoren.
Map<String, String> map1 = new HashMap<>();
Map<String, String> map2 = new HashMap<>(2^5);
Map<String, String> map3 = new HashMap<>(32,0.80f);
Map<String,String> map4 = new HashMap<>(map1);
Java HashMap-methoden
Laten we eens kijken naar de belangrijke methoden van HashMap in Java.
- public void clear(): Deze HashMap-methode verwijdert alle koppelingen en de HashMap wordt leeg.
- public boolean containsKey(Object key): Deze methode retourneert ’true’ als de sleutel bestaat, anders retourneert het ‘false’.
- public boolean containsValue(Object value): Deze HashMap-methode retourneert true als de waarde bestaat, anders false.
- public Set<Map.Entry<K,V>> entrySet(): Deze methode retourneert een Set-weergave van de HashMap-koppelingen. Deze set wordt ondersteund door de map, dus wijzigingen in de map worden weerspiegeld in de set, en vice versa.
- public V get(Object key): Geeft de waarde terug die is gekoppeld aan de opgegeven sleutel, of null als er geen koppeling is voor de sleutel.
- public boolean isEmpty(): Een hulpmethode die true retourneert als er geen sleutel-waardekoppelingen aanwezig zijn.
- public Set<K> keySet(): Retourneert een Set-weergave van de sleutels die in deze map zijn opgenomen. De set wordt ondersteund door de map, dus wijzigingen in de map worden weerspiegeld in de set, en vice versa.
- public V put(K key, V value): Koppelt de opgegeven waarde aan de opgegeven sleutel in deze map. Als de map eerder een koppeling voor de sleutel bevatte, wordt de oude waarde vervangen.
- public void putAll(Map<? extends K, ? extends V> m): Kopieert alle toewijzingen van de opgegeven map naar deze map. Deze toewijzingen zullen eventuele bestaande toewijzingen voor een van de sleutels in de opgegeven map vervangen.
- public V remove(Object key): Verwijdert de toewijzing voor de opgegeven sleutel uit deze map indien aanwezig.
- public int size(): Geeft het aantal sleutel-waarde toewijzingen in deze map terug.
- public Collection<V> values(): Geeft een Collection-weergave van de waarden in deze map terug. De verzameling wordt ondersteund door de map, dus wijzigingen in de map worden weerspiegeld in de verzameling, en vice versa.
Er zijn veel nieuwe methoden in HashMap geïntroduceerd in Java 8.
- public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction): Als de opgegeven sleutel nog niet is gekoppeld aan een waarde (of is gekoppeld aan null), probeert deze methode de waarde te berekenen met de opgegeven toewijzingsfunctie en voert deze in in de HashMap, tenzij Null.
- public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction): Als de waarde voor de opgegeven sleutel aanwezig is en niet-null, probeert het een nieuwe toewijzing te berekenen met de sleutel en de huidige waarde ervan.
- public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction): Deze HashMap-methode probeert een toewijzing te berekenen voor de opgegeven sleutel en de huidige waarde ervan.
- public void forEach(BiConsumer<? super K, ? super V> action): Deze methode voert de opgegeven actie uit voor elk item in deze map.
- public V getOrDefault(Object key, V defaultValue): Hetzelfde als get, behalve dat defaultValue wordt geretourneerd als er geen mapping is gevonden voor de opgegeven sleutel.
- public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction): Als de opgegeven sleutel nog niet is gekoppeld aan een waarde of is gekoppeld aan null, wordt deze gekoppeld aan de opgegeven niet-null waarde. Vervangt anders de geassocieerde waarde door de resultaten van de opgegeven remapping-functie, of verwijdert deze als het resultaat null is.
- public V putIfAbsent(K key, V value): Als de opgegeven sleutel nog niet is gekoppeld aan een waarde (of is toegewezen aan null), wordt deze gekoppeld aan de opgegeven waarde en wordt null geretourneerd, anders wordt de huidige waarde geretourneerd.
- public boolean remove(Object key, Object value): Verwijdert de invoer voor de opgegeven sleutel alleen als deze momenteel is gekoppeld aan de opgegeven waarde.
- public boolean replace(K key, V oldValue, V newValue): Vervangt de invoer voor de opgegeven sleutel alleen als deze momenteel is gekoppeld aan de opgegeven waarde.
- public V replace(K key, V value): Vervangt de invoer voor de opgegeven sleutel alleen als deze momenteel is gekoppeld aan een waarde.
- public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function): Vervangt de waarde van elk item door het resultaat van het aanroepen van de opgegeven functie voor dat item.
Voorbeeld van Java HashMap
Hier is een eenvoudig Java-programma voor de veelgebruikte methoden van HashMap.
package com.journaldev.examples;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class HashMapExample {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("1", "1"); // put example
map.put("2", "2");
map.put("3", "3");
map.put("4", null); // null value
map.put(null, "100"); // null key
String value = map.get("3"); // get example
System.out.println("Key = 3, Value = " + value);
value = map.getOrDefault("5", "Default Value");
System.out.println("Key = 5, Value=" + value);
boolean keyExists = map.containsKey(null);
boolean valueExists = map.containsValue("100");
System.out.println("keyExists=" + keyExists + ", valueExists=" + valueExists);
Set<Entry<String, String>> entrySet = map.entrySet();
System.out.println(entrySet);
System.out.println("map size=" + map.size());
Map<String, String> map1 = new HashMap<>();
map1.putAll(map);
System.out.println("map1 mappings= " + map1);
String nullKeyValue = map1.remove(null);
System.out.println("map1 null key value = " + nullKeyValue);
System.out.println("map1 after removing null key = " + map1);
Set<String> keySet = map.keySet();
System.out.println("map keys = " + keySet);
Collection<String> values = map.values();
System.out.println("map values = " + values);
map.clear();
System.out.println("map is empty=" + map.isEmpty());
}
}
Onderstaand is de uitvoer van het bovenstaande Java HashMap voorbeeldprogramma.
Key = 3, Value = 3
Key = 5, Value=Default Value
keyExists=true, valueExists=true
[null=100, 1=1, 2=2, 3=3, 4=null]
map size=5
map1 mappings= {null=100, 1=1, 2=2, 3=3, 4=null}
map1 null key value = 100
map1 after removing null key = {1=1, 2=2, 3=3, 4=null}
map keys = [null, 1, 2, 3, 4]
map values = [100, 1, 2, 3, null]
map is empty=true
Hoe werkt HashMap in Java?
HashMap in Java gebruikt zijn innerlijke klasse Node Aanbevolen lezen: Belang van hashCode en equals-methode in Java
Java HashMap Laadfactor
De laadfactor wordt gebruikt om te bepalen wanneer HashMap opnieuw gehasht zal worden en de grootte van de emmer zal worden vergroot. De standaardwaarde van de emmer of capaciteit is 16 en de laadfactor is 0,75. De drempel voor het opnieuw hashen wordt berekend door de capaciteit en de laadfactor te vermenigvuldigen. Dus de standaard drempelwaarde zal 12 zijn. Dus wanneer de HashMap meer dan 12 toewijzingen heeft, zal deze opnieuw worden gehasht en het aantal bakken zal worden verhoogd naar het volgende macht van 2, namelijk 32. Let op dat de capaciteit van HashMap altijd een macht van 2 is. De standaard laadfactor van 0,75 biedt een goede balans tussen ruimte- en tijdscomplexiteit. Maar je kunt het instellen op verschillende waarden op basis van je vereisten. Als je ruimte wilt besparen, kun je de waarde verhogen naar 0,80 of 0,90, maar dan zullen de get-/zet-operaties meer tijd kosten.
Java HashMap keySet
De Java HashMap keySet-methode retourneert de Set-weergave van sleutels in de HashMap. Deze Set-weergave wordt ondersteund door HashMap en alle wijzigingen in HashMap worden weerspiegeld in de Set en vice versa. Hieronder staat een eenvoudig programma dat voorbeelden van HashMap keySet demonstreert en wat de manier is om te gaan als je een keySet wilt die niet wordt ondersteund door de map.
package com.journaldev.examples;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class HashMapKeySetExample {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("1", "1");
map.put("2", "2");
map.put("3", "3");
Set<String> keySet = map.keySet();
System.out.println(keySet);
map.put("4", "4");
System.out.println(keySet); // keySet is backed by Map
keySet.remove("1");
System.out.println(map); // map is also modified
keySet = new HashSet<>(map.keySet()); // copies the key to new Set
map.put("5", "5");
System.out.println(keySet); // keySet is not modified
}
}
De uitvoer van het bovenstaande programma zal duidelijk maken dat keySet wordt ondersteund door de map.
[1, 2, 3]
[1, 2, 3, 4]
{2=2, 3=3, 4=4}
[2, 3, 4]
Java HashMap-waarden
De Java HashMap-waardenmethode retourneert een Collection-weergave van de waarden in de Map. Deze verzameling wordt ondersteund door HashMap, dus alle wijzigingen in HashMap worden weerspiegeld in de waardencollectie en vice versa. Een eenvoudig voorbeeld hieronder bevestigt dit gedrag van de HashMap-waardencollectie.
package com.journaldev.examples;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class HashMapValuesExample {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("1", "1");
map.put("2", "2");
map.put("3", null);
map.put("4", null);
map.put(null, "100");
Collection<String> values = map.values();
System.out.println("map values = " + values);
map.remove(null);
System.out.println("map values after removing null key = " + values);
map.put("5", "5");
System.out.println("map values after put = " + values);
System.out.println(map);
values.remove("1"); // changing values collection
System.out.println(map); // updates in map too
}
}
De uitvoer van het bovenstaande programma is als volgt.
map values = [100, 1, 2, null, null]
map values after removing null key = [1, 2, null, null]
map values after put = [1, 2, null, null, 5]
{1=1, 2=2, 3=null, 4=null, 5=5}
{2=2, 3=null, 4=null, 5=5}
Java HashMap-entrySet
De Java HashMap-entrySet-methode retourneert de Set-weergave van de mappings. Deze entrySet wordt ondersteund door HashMap, dus alle wijzigingen in de map worden weerspiegeld in de entry set en vice versa. Bekijk het onderstaande voorbeeldprogramma voor een voorbeeld van HashMap-entrySet.
package com.journaldev.examples;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class HashMapEntrySetExample {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("1", "1");
map.put("2", null);
map.put(null, "100");
Set<Entry<String,String>> entrySet = map.entrySet();
Iterator<Entry<String, String>> iterator = entrySet.iterator();
Entry<String, String> next = null;
System.out.println("map before processing = "+map);
System.out.println("entrySet before processing = "+entrySet);
while(iterator.hasNext()){
next = iterator.next();
System.out.println("Processing on: "+next.getValue());
if(next.getKey() == null) iterator.remove();
}
System.out.println("map after processing = "+map);
System.out.println("entrySet after processing = "+entrySet);
Entry<String, String> simpleEntry = new AbstractMap.SimpleEntry<String, String>("1","1");
entrySet.remove(simpleEntry);
System.out.println("map after removing Entry = "+map);
System.out.println("entrySet after removing Entry = "+entrySet);
}
}
Hieronder staat de uitvoer die door het bovenstaande programma wordt geproduceerd.
map before processing = {null=100, 1=1, 2=null}
entrySet before processing = [null=100, 1=1, 2=null]
Processing on: 100
Processing on: 1
Processing on: null
map after processing = {1=1, 2=null}
entrySet after processing = [1=1, 2=null]
map after removing Entry = {2=null}
entrySet after removing Entry = [2=null]
Java HashMap-putIfAbsent
A simple example for HashMap putIfAbsent method introduced in Java 8.
package com.journaldev.examples;
import java.util.HashMap;
import java.util.Map;
public class HashMapPutIfAbsentExample {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("1", "1");
map.put("2", null);
map.put(null, "100");
System.out.println("map before putIfAbsent = "+map);
String value = map.putIfAbsent("1", "4");
System.out.println("map after putIfAbsent = "+map);
System.out.println("putIfAbsent returns: "+value);
System.out.println("map before putIfAbsent = "+map);
value = map.putIfAbsent("3", "3");
System.out.println("map after putIfAbsent = "+map);
System.out.println("putIfAbsent returns: "+value);
}
}
De uitvoer van het bovenstaande programma is als volgt;
map before putIfAbsent = {null=100, 1=1, 2=null}
map after putIfAbsent = {null=100, 1=1, 2=null}
putIfAbsent returns: 1
map before putIfAbsent = {null=100, 1=1, 2=null}
map after putIfAbsent = {null=100, 1=1, 2=null, 3=3}
putIfAbsent returns: null
Java HashMap-forEach
HashMap forEach-methode is geïntroduceerd in Java 8. Het is een zeer nuttige methode om de opgegeven actie uit te voeren voor elk item in de map totdat alle items zijn verwerkt of de actie een uitzondering veroorzaakt.
package com.journaldev.examples;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
public class HashMapForEachExample {
public static void main(String[] args) {
Map map = new HashMap<>();
map.put("1", "1");
map.put("2", null);
map.put(null, "100");
BiConsumer action = new MyBiConsumer();
map.forEach(action);
//voorbeeld van lambda-expressie
System.out.println("\nHashMap forEach lambda example\n");
map.forEach((k,v) -> {System.out.println("Key = "+k+", Value = "+v);});
}
}
class MyBiConsumer implements BiConsumer {
@Override
public void accept(String t, String u) {
System.out.println("Key = " + t);
System.out.println("Processing on value = " + u);
}
}
De uitvoer van het bovenstaande voorbeeldprogramma voor HashMap forEach is;
Key = null
Processing on value = 100
Key = 1
Processing on value = 1
Key = 2
Processing on value = null
HashMap forEach lambda example
Key = null, Value = 100
Key = 1, Value = 1
Key = 2, Value = null
Java HashMap replaceAll
De replaceAll-methode van HashMap kan worden gebruikt om de waarde van elk item te vervangen door het resultaat van het aanroepen van de opgegeven functie voor dat item. Deze methode is toegevoegd in Java 8 en we kunnen lambda-expressies gebruiken als argument voor deze methode.
package com.journaldev.examples;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;
public class HashMapReplaceAllExample {
public static void main(String[] args) {
Map map = new HashMap<>();
map.put("1", "1");
map.put("2", "2");
map.put(null, "100");
System.out.println("map before replaceAll = " + map);
BiFunction function = new MyBiFunction();
map.replaceAll(function);
System.out.println("map after replaceAll = " + map);
// replaceAll met lambda-expressies
map.replaceAll((k, v) -> {
if (k != null) return k + v;
else return v;});
System.out.println("map after replaceAll lambda expression = " + map);
}
}
class MyBiFunction implements BiFunction {
@Override
public String apply(String t, String u) {
if (t != null)
return t + u;
else
return u;
}
}
De uitvoer van het bovenstaande programma voor HashMap replaceAll is;
map before replaceAll = {null=100, 1=1, 2=2}
map after replaceAll = {null=100, 1=11, 2=22}
map after replaceAll lambda example = {null=100, 1=111, 2=222}
Java HashMap computeIfAbsent
De computeIfAbsent-methode van HashMap berekent de waarde alleen als de sleutel nog niet aanwezig is in de map. Na het berekenen van de waarde wordt deze in de map geplaatst als deze niet null is.
package com.journaldev.examples;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
public class HashMapComputeIfAbsent {
public static void main(String[] args) {
Map map = new HashMap<>();
map.put("1", "10");
map.put("2", "20");
map.put(null, "100");
Function function = new MyFunction();
map.computeIfAbsent("3", function); //key not present
map.computeIfAbsent("2", function); //key already present
//op de lambda-manier
map.computeIfAbsent("4", v -> {return v;});
map.computeIfAbsent("5", v -> {return null;}); //null value won't get inserted
System.out.println(map);
}
}
class MyFunction implements Function {
@Override
public String apply(String t) {
return t;
}
}
De uitvoer van het bovenstaande programma is;
{null=100, 1=10, 2=20, 3=3, 4=4}
Java HashMap computeIfPresent
De Java HashMap computeIfPresent methode herberekent de waarde als de opgegeven sleutel aanwezig is en de waarde niet-nul is. Als de functie null retourneert, wordt de toewijzing verwijderd.
package com.journaldev.examples;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;
public class HashMapComputeIfPresentExample {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("1", "10");
map.put("2", "20");
map.put(null, "100");
map.put("10", null);
System.out.println("map before computeIfPresent = " + map);
BiFunction<String, String, String> function = new MyBiFunction1();
for (String key : map.keySet()) {
map.computeIfPresent(key, function);
}
System.out.println("map after computeIfPresent = " + map);
map.computeIfPresent("1", (k,v) -> {return null;}); // mapping will be removed
System.out.println("map after computeIfPresent = " + map);
}
}
class MyBiFunction1 implements BiFunction<String, String, String> {
@Override
public String apply(String t, String u) {
return t + u;
}
}
Het uitvoerresultaat geproduceerd door het voorbeeld van HashMap computeIfPresent is;
map before computeIfPresent = {null=100, 1=10, 2=20, 10=null}
map after computeIfPresent = {null=null100, 1=110, 2=220, 10=null}
map after computeIfPresent = {null=null100, 2=220, 10=null}
Java HashMap bereken
Als je een functie op alle toewijzingen wilt toepassen op basis van de sleutel en de waarde, dan moet de berekeningsmethode worden gebruikt. Als er geen toewijzing is en deze methode wordt gebruikt, zal de waarde null zijn voor de berekeningsfunctie.
package com.journaldev.examples;
import java.util.HashMap;
import java.util.Map;
public class HashMapComputeExample {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("1", "1");
map.put("2", "2");
map.put(null, "10");
map.put("10", null);
System.out.println("map before compute = "+map);
for (String key : map.keySet()) {
map.compute(key, (k,v) -> {return k+v;});
}
map.compute("5", (k,v) -> {return k+v;}); //key not present, v = null
System.out.println("map after compute = "+map);
}
}
Het uitvoerresultaat van het voorbeeld van HashMap bereken is;
map before compute = {null=10, 1=1, 2=2, 10=null}
map after compute = {null=null10, 1=11, 2=22, 5=5null, 10=10null}
Java HashMap samenvoegen
Als de opgegeven sleutel niet aanwezig is of geassocieerd is met null, koppelt deze het aan de opgegeven niet-nul waarde. Anders vervangt het de geassocieerde waarde door de resultaten van de gegeven herschikkingsfunctie, of verwijdert het als het resultaat null is.
package com.journaldev.examples;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class HashMapMergeExample {
public static void main(String[] args) {
Map map = new HashMap<>();
map.put("1", "1");
map.put("2", "2");
map.put(null, "10");
map.put("10", null);
for (Entry entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
//samenvoegen gooit een NullPointerException als de sleutel of waarde null is
if(key != null && value != null)
map.merge(entry.getKey(), entry.getValue(),
(k, v) -> {return k + v;});
}
System.out.println(map);
map.merge("5", "5", (k, v) -> {return k + v;}); // key not present
System.out.println(map);
map.merge("1", "1", (k, v) -> {return null;}); // method return null, so remove
System.out.println(map);
}
}
Het uitvoerresultaat van bovenstaand programma is;
{null=10, 1=11, 2=22, 10=null}
{null=10, 1=11, 2=22, 5=5, 10=null}
{null=10, 2=22, 5=5, 10=null}
Dat is alles voor HashMap in Java, ik hoop dat er niets belangrijks is overgeslagen. Deel het ook met anderen als je het leuk vond. Referentie: API Doc
Source:
https://www.digitalocean.com/community/tutorials/java-hashmap