Java HashMap类方法使用教程

x33g5p2x  于2021-08-20 转载在 Java  
字(10.5k)|赞(0)|评价(0)|浏览(502)

在本指南中,我们将学习Java集合框架中Map接口的HashMap实现。

本指南涵盖了所有重要的HashMap类API,并附有实例。

我们将学到什么?

  1. Map接口概述
  2. HashMapclass概述
  3. 创建一个HashMap并向其添加键值对

put(String key, Integer value).
putIfAbsent(String key, Integer value)

  1. HashMapAPI用于访问键并修改其相关值

isEmpty()
size()
containsKey(Object key).
containsValue(Object value).
get(Object key)

  1. HashMapremove API's with Examples

remove(Object key)
remove(Object key, Object value).

  1. 空键和空值的HashMap演示
  2. 如何在Map中执行范围视图操作?

keySet()
values()
entrySet()

  1. 对Map进行迭代的不同方法
  2. 如何在Map中存储多个值?
  3. Java 8 forEach()方法与Map的关系
  4. 同步访问Java HashMap

1. Map概述

  1. Map是一个将键映射到值的对象。每个键和值对都被称为一个条目。Map只包含唯一的键。
  2. 一个Map不能包含重复的键。每个键最多可以映射到一个值。它是数学函数抽象的模型。Java平台包含三种通用的Map实现。HashMap、TreeMap和LinkedHashMap。
    在本指南中,我们将重点讨论HashMap类的实现。

2. HashMap概述

Java HashMapclass通过使用一个哈希表来实现Map接口。它继承了AbstractMapclass并实现了Mapinterface。

关于Java HashMap类的重要观点。

  • 一个HashMap包含了基于键的值。
  • 它只包含唯一的元素。
  • 它可以有一个空键和多个空值。
  • 它不保持任何顺序。
  • Java HashMap不是线程安全的。你必须明确地同步对HashMap的并发修改。

3. 创建一个HashMap并向其添加键值对

下面的例子展示了如何创建一个HashMap, 并向其添加新的键值对.

// Creating a HashMap
Map<String, Integer> numberMapping = new HashMap<>();

// Adding key-value pairs to a HashMap
numberMapping.put("One", 1);
numberMapping.put("Two", 2);
numberMapping.put("Three", 3);

// Add a new key-value pair only if the key does not exist in the HashMap, or is mapped to `null`
numberMapping.putIfAbsent("Four", 4);

System.out.println(numberMapping);

put(String key, Integer value)

将指定的值与该Map中的指定键关联起来(可选操作)。

// Creating a HashMap
Map<String, Integer> numberMapping = new HashMap<>();

// Adding key-value pairs to a HashMap
numberMapping.put("One", 1);
numberMapping.put("Two", 2);
numberMapping.put("Three", 3);

putIfAbsent(String key, Integer value)

如果指定的键没有与一个值相关联(或者被映射为null),则将其与给定的值相关联并返回null,否则返回当前值。

// Creating a HashMap
Map<String, Integer> numberMapping = new HashMap<>();
// Add a new key-value pair only if the key does not exist in the HashMap, or is mapped to `null`
numberMapping.putIfAbsent("Four", 4);

4. HashMapAPI用于访问键并修改其关联值

  • 如何检查一个HashMap是否为空 | isEmpty()
  • 如何查找HashMap的大小| size()
  • 如何检查一个给定的键是否存在于HashMap中| containsKey()
  • 如何检查一个给定的值是否存在于HashMap中| containsValue()
  • 如何获得与HashMap中给定键相关的值| get()
  • 如何修改与HashMap中给定键相关的值| put()

isEmpty()

如果这个Map不包含键值映射,则返回true。

Map<String, String> userCityMapping = new HashMap<>();

// Check if a HashMap is empty
System.out.println("is userCityMapping empty? : " + userCityMapping.isEmpty());

size()

返回该Map中键值映射的数量。如果Map包含超过Integer.MAX_VALUE的元素,返回Integer.MAX_VALUE。

Map<String, String> userCityMapping = new HashMap<>();
userCityMapping.put("John", "New York");
userCityMapping.put("Rajeev", "Bengaluru");
userCityMapping.put("Steve", "London");
// Find the size of a HashMap
System.out.println("We have the city information of " + userCityMapping.size() + " users");

containsKey(Object key)

如果这个Map包含指定键的映射,返回true。更正式的说,如果且仅当此Map包含一个键的映射,且该键是(key==null ? k==null: key.equals(k)),则返回true。(最多只能有一个这样的映射)。)

Map<String, String> userCityMapping = new HashMap<>();
userCityMapping.put("John", "New York");
userCityMapping.put("Rajeev", "Bengaluru");
userCityMapping.put("Steve", "London");

String userName = "Steve";
// Check if a key exists in the HashMap
if(userCityMapping.containsKey(userName)) {
 // Get the value assigned to a given key in the HashMap
 String city = userCityMapping.get(userName);
 System.out.println(userName + " lives in " + city);
} else {
 System.out.println("City details not found for user " + userName);
}

containsValue(Object value)

如果该映射将一个或多个键映射到指定的值,返回true。更正式地说,如果并且只在这个Map包含至少一个映射到一个值v,并且(value==null ? v==null : value.equals(v))时返回true。对于大多数Map接口的实现来说,这个操作可能需要的时间与Map的大小成线性关系。

Map<String, String> userCityMapping = new HashMap<>();
userCityMapping.put("John", "New York");
userCityMapping.put("Rajeev", "Bengaluru");
userCityMapping.put("Steve", "London");

// Check if a value exists in a HashMap
if(userCityMapping.containsValue("New York")) {
 System.out.println("There is a user in the userCityMapping who lives in New York");
} else {
 System.out.println("There is not user in the userCityMapping who lives in New York");
}

get(Object key)

返回指定的键所映射的值,如果这个Map不包含键的映射,则返回空值。

Map<String, String> userCityMapping = new HashMap<>();
userCityMapping.put("John", "New York");
userCityMapping.put("Rajeev", "Bengaluru");
userCityMapping.put("Steve", "London");

System.out.println("Lisa's city : " + userCityMapping.get("Steve"));

5. HashMapremove API's with Examples

  • 从HashMap中删除一个键| remove(Object key)
  • 从HashMap中删除一个键,只有当它与一个给定的值相关联时| remove(Object key, Object value)

remove(Object key)

如果这个Map中存在一个键的映射,则从这个Map中移除该键的映射(可选操作)。更正式地说,如果这个Map包含一个从key k到value v的映射,并且(key==null ? k==null: key.equals(k)),那么这个映射就被移除。(该Map最多只能包含一个这样的映射)。)

Map<String, String> husbandWifeMapping = new HashMap<>();
husbandWifeMapping.put("Jack", "Marie");
husbandWifeMapping.put("Chris", "Lisa");
husbandWifeMapping.put("Steve", "Jennifer");

String husband = "Chris";
String wife = husbandWifeMapping.remove(husband);

remove(Object key, Object value)

只有当指定的键当前被映射到指定的值时,才会删除指定键的条目。

Map<String, String> husbandWifeMapping = new HashMap<>();
husbandWifeMapping.put("Jack", "Marie");
husbandWifeMapping.put("Chris", "Lisa");
husbandWifeMapping.put("Steve", "Jennifer");

// Remove a key from the HashMap only if it is mapped to the given value
// Ex - Divorce "Jack" only if He is married to "Linda"
boolean isRemoved = husbandWifeMapping.remove("Jack", "Linda");
System.out.println("Did Jack get removed from the mapping? : " + isRemoved);

6. 空键和空值的HashMapdemonstration

// HashMap demonstration for null keys and null values
private static void nullKeyValueDemo() {
 Map<String, String> map = new HashMap<>();
 map.put(null, null);
 map.put(null, null);

 // iterate map using java 8 forEach method
 map.forEach((k, v) -> {
  System.out.println(k);
  System.out.println(v);
 });

 for (Entry<String, String> entry : map.entrySet()) {
  System.out.println(entry.getKey());
  System.out.println(entry.getValue());
 }
}

// HashMap demonstration for duplicate keys
private static void duplicateKeyDemo() {
 Map<String, String> map = new HashMap<>();
 map.put("key1", "value1");
 map.put("key1", "value2");

 // iterate map using java 8 forEach method
 map.forEach((k, v) -> {
  System.out.println(k);
  System.out.println(v);
 });

 for (Entry<String, String> entry : map.entrySet()) {
  System.out.println(entry.getKey());
  System.out.println(entry.getValue());
 }
}

7. 如何在Map中执行范围视图操作?

集合视图方法允许以这三种方式将Map看成一个集合。

  • keySet- Map中包含的键的集合。
  • values- Map中包含的值的集合。这个集合不是一个集合,因为多个键可以映射到同一个值。
  • entrySet- Map中包含的键值对的集合。Mapinterface提供了一个叫做Map.Entry的小型嵌套接口,是这个Set中元素的类型。
private static void collectionViewsDemo() {

 Map<String, String> map = new HashMap<>();
 map.put("key1", "value1");
 map.put("key2", "value2");
 map.put("key3", "value3");

 // Returns a Set view of the keys contained in this map
 Set<String> keys = map.keySet();

 // Returns a Collection view of the values contained in this map
 Collection<String> values = map.values();

 // Returns a Set view of the mappings contained in this map
 Set<Entry<String, String>> entry = map.entrySet();

 // iterate map using java 8 forEach method
 map.forEach((k, v) -> {
  System.out.println(k);
  System.out.println(v);
 });

 for (Entry<String, String> pair : entry) {
  System.out.println(pair.getKey());
  System.out.println(pair.getValue());
 }
}

8. 迭代Map的不同方法

private static void iterateMap() {

 Map<String, String> map = new HashMap<>();
 map.put("key1", "value1");
 map.put("key2", "value2");
 map.put("key3", "value3");

 // Returns a Set view of the keys contained in this map
 Set<String> keys = map.keySet();
 // Returns a Collection view of the values contained in this map
 Collection<String> values = map.values();
 // Returns a Set view of the mappings contained in this map
 Set<Entry<String, String>> entry = map.entrySet();
 for (Entry<String, String> pair : entry) {
  System.out.println(pair.getKey());
  System.out.println(pair.getValue());
 }

 // iterate map using java 8 forEach method
 map.forEach((k, v) -> {
  System.out.println(k);
  System.out.println(v);
 });

}

9. 如何在Map中存储多个值?

Multimap就像一个Map,但它可以将每个键映射到多个值。

让我们创建一个对象的列表,并用键来映射。

private static void multmapDemo() {
 Map<String, List<String>> multimap = new HashMap<>();
 List<String> multiValueList = new ArrayList<>();
 multiValueList.add("value1");
 multiValueList.add("value2");
 multiValueList.add("value3");
 multimap.put("key1", multiValueList);
}

10. Java 8 forEach()方法与Map的关系

循环一个Map的正常方法。

public static void forEachWithMap() {

 // Before Java 8, how to loop map
 final Map<Integer, Person> map = new HashMap<>();
 map.put(1, new Person(100, "Ramesh"));
 map.put(2, new Person(100, "Ram"));
 map.put(3, new Person(100, "Prakash"));
 map.put(4, new Person(100, "Amir"));
 map.put(5, new Person(100, "Sharuk"));

 for (final Entry<Integer, Person> entry : map.entrySet()) {
  System.out.println(entry.getKey());
  System.out.println(entry.getValue().getName());
 }
}

在Java 8中,你可以用forEach和lambda表达式循环一个Map。

public static void forEachWithMap() {

 // Before Java 8, how to loop map
 final Map<Integer, Person> map = new HashMap<>();
 map.put(1, new Person(100, "Ramesh"));
 map.put(2, new Person(100, "Ram"));
 map.put(3, new Person(100, "Prakash"));
 map.put(4, new Person(100, "Amir"));
 map.put(5, new Person(100, "Sharuk"));

 //  In Java 8, you can loop a Map with forEach + lambda expression.
 map.forEach((k,p) -> {
  System.out.println(k);
  System.out.println(p.getName());
 });
}

11. 对Java HashMap的同步访问

HashMap是不同步的, 这意味着你不能在没有外部同步的情况下在一个多线程的Java程序中使用它。换句话说, 如果你在多个线程之间共享一个HashMap实例, 每个线程都在添加、删除或更新条目, 那么HashMap就有可能失去它的结构而不像预期的那样表现。

  • 使用*Collections.synchronizedMap()方法来获得HashMap的同步视图。
    将增量逻辑写在一个同步
    块内。
  • 我们可以使用ConcurrentHashMap来实现线程安全,而不是通过Collections.synchronizedMap()方法获得HashMap。ConcurrentHashMap在Map上提供了线程安全的操作。
Map<String, String> currencies = new HashMap<String, String>();
currencies.put("USA", "USD");
currencies.put("England", "GBP");
currencies.put("Canada", "CAD");
currencies.put("HongKong", "HKD");
currencies.put("Australia", "AUD");

// Synchronizing HashMap in Java
currencies = Collections.synchronizedMap(currencies);
// Make sure to synchronize Map while Iterating
// getting key set can be outside synchronized block
Set<String> keySet = currencies.keySet();

synchronized (currencies) {
 Iterator<String> itr = keySet.iterator();
 while (itr.hasNext()) {
  System.out.println(itr.next());
 }
}

相关文章