Java LinkedHashMap与示例

时间:2020-01-09 10:36:48  来源:igfitidea点击:

Java中的LinkedHashMap也是Map接口的实现之一。它与其他实现HashMap的不同之处在于,与无序的HashMap不同,LinkedHashMap是有序的。 Java中的LinkedHashMap类除了实现Map接口之外,还扩展了HashMap。

LinkedHashMap维护一个遍历其所有条目的双向链接列表,该列表定义了迭代顺序。有两种订购方式:

  • 插入顺序–键在地图中的插入顺序。插入顺序是Java中LinkedHashMap的默认顺序。
  • 访问顺序-上次访问其条目的顺序,从最近到最近。有一个特殊的构造函数,用于使用访问顺序创建LinkedHashMap。

LinkedHashMap的功能

本文中讨论的Java中LinkedHashMap的某些功能如下:

  • 在LinkedHashMap中,值可以重复,但是键必须是唯一的。如果重新插入相同的密钥,则不会影响插入顺序。
  • LinkedHashMap是有序的。
  • LinkedHashMap允许空值和空键。但是只允许使用一个null键,因为可以有多个null值。
  • Java中的LinkedHashMap不是线程安全的。
  • 所有LinkedHashMap的"集合视图方法"返回的迭代器都是快速失败的。这意味着,如果在创建迭代器之后的任何时间对结构进行结构修改,则除了通过迭代器自己的remove方法之外,都可以通过其他方式修改该映射,否则迭代器将抛出ConcurrentModificationException。

Java LinkedHashMap构造函数

  • LinkedHashMap()–构造一个空的插入顺序的LinkedHashMap实例,其默认初始容量(16)和负载因子(0.75)。

  • LinkedHashMap(int initialCapacity)–构造一个空的插入顺序的LinkedHashMap实例,该实例具有指定的初始容量和默认负载因子(0.75)。

  • LinkedHashMap(int initialCapacity,float loadFactor)–使用指定的初始容量和负载因子构造一个空的插入顺序的LinkedHashMap实例。

  • LinkedHashMap(int initialCapacity,float loadFactor,boolean accessOrder)–构造一个空的LinkedHashMap实例,该实例具有指定的初始容量,负载系数和排序方式。如果将accessOrder作为true传递,则为true,然后为access-order,对于插入顺序为false。

  • LinkedHashMap(Map <?扩展K ,?扩展V> m)–构造插入顺序的LinkedHashMap实例,该实例具有与指定映射相同的映射。

Java示例,创建LinkedHashMap

本示例说明如何创建LinkedHashMap以及如何向其中添加元素。

import java.util.LinkedHashMap;
import java.util.Map;

public class LinkedHMDemo {
  public static void main(String[] args) {
    // Creating LinkedHashMap
    Map<String, String> carMap = new LinkedHashMap<String, String>();
    // Storing elements
    carMap.put("1", "Audi");
    carMap.put("2", "BMW");
    carMap.put(null, "Mercedes");
    carMap.put("3", "Jaguar");
    carMap.put("4", "Mini Cooper");
    carMap.put(null, "Range Rover");

    for(Map.Entry<String, String> entry : carMap.entrySet()){
      System.out.println("Key is " + entry.getKey() + " Value is " + entry.getValue());
    }
  }
}

输出:

Key is 1 Value is Audi
Key is 2 Value is BMW
Key is null Value is Range Rover
Key is 3 Value is Jaguar
Key is 4 Value is Mini Cooper

从输出中可以看到,插入顺序得到维护。此外,即使多次添加null,也只会添加一次。

LinkedHashMap与访问顺序

import java.util.LinkedHashMap;
import java.util.Map;

public class LinkedHMDemo {
  public static void main(String[] args) {
    // Creating LinkedHashMap
    Map<String, String> carMap = new LinkedHashMap<String, String>(16, 0.75f, true);
    // Storing elements
    carMap.put("1", "Audi");
    carMap.put("2", "BMW");
    carMap.put("3", "Jaguar");
    carMap.put("4", "Mini Cooper");
    System.out.println("value- " + carMap.get("2"));
    System.out.println("value- " + carMap.get("3"));
    for(Map.Entry<String, String> entry : carMap.entrySet()){
      System.out.println("Key is " + entry.getKey() + " Value is " + entry.getValue());
    }
  }
}

输出:

Key is 1 Value is Audi
Key is 4 Value is Mini Cooper
Key is 2 Value is BMW
Key is 3 Value is Jaguar

由于访问顺序从最近的访问到最近的访问,这就是为什么键2和3稍后显示的原因,因为这两个键是最近访问的。

LinkedHashMap类中的方法

  • containsValue(Object value)–如果此映射将一个或者多个键映射到指定值,则返回true。

  • entrySet()–返回此映射中包含的映射的Set视图。

  • get(Object key)–返回指定键所映射到的值;如果此映射不包含该键的映射,则返回null。

  • keySet()–返回此映射中包含的键的Set视图。

  • removeEldestEntry(Map.Entry <K,V> eldest)–如果此地图应删除其最旧的条目,则返回true。

  • values()–返回此映射中包含的值的Collection视图。

LinkedHashMap实现不同步

Java中的LinkedHashMap不同步,因此不是线程安全的。如果多个线程同时访问链接的哈希映射,并且至少有一个线程在结构上修改该映射,则必须在外部进行同步。我们可以使用Collections.synchronizedMap方法包装LinkedHashMap。

Map m = Collections.synchronizedMap(new LinkedHashMap(...));

Java LinkedHashMap迭代器

我们不能直接在Map中使用迭代器。我们将必须获取Map的集合视图,然后对其进行迭代。 LinkedHashMap的集合视图方法返回的迭代器是快速失败的。如果在创建迭代器之后的任何时候修改了集合,则除了通过迭代器自己的remove方法以外,都可以通过其他方式修改该集合,否则迭代器将抛出ConcurrentModificationException。

迭代LinkedHashMap Java示例

public class LinkedHMDemo {
  public static void main(String[] args) {
    // Creating HashMap
    Map<String, String> carMap = new LinkedHashMap<String, String>();
    // Storing elements
    carMap.put("1", "Audi");
    carMap.put("2", "BMW");
    carMap.put("3", "Jaguar");
    carMap.put("4", "Mini Cooper");
    // iterating map
    Iterator<Map.Entry<String, String>> itr = carMap.entrySet().iterator();
    while(itr.hasNext()) {
      Map.Entry<String, String> entry = itr.next();
      System.out.println("Key is " + entry.getKey() + " Value is " + entry.getValue());
    }
  }
}

输出:

Key is 1 Value is Audi
Key is 2 Value is BMW
Key is 3 Value is Jaguar
Key is 4 Value is Mini Cooper

LinkedHashMap的性能

像HashMap一样,LinkedHashMap为基本操作(添加,包含和删除)提供恒定时间的性能,假设哈希函数将元素正确地分散在存储桶中。由于维护链接列表会增加开销,因此LinkedHashMap的性能可能会略低于HashMap。一个例外是迭代,由于在链表中进行遍历,因此在LinkedHashMap中更快。