Java中的LinkedHashMap

Java中的LinkedHashMap

LinkedHashMap 与HashMap类似,只是增加了一个维护插入元素顺序的功能。HashMap提供了快速插入、搜索和删除的优势,但它从不维护插入的轨迹和顺序,而LinkedHashMap提供了这个特性,可以按插入顺序访问元素。

LinkedHashMap的重要特点如下:

  • LinkedHashMap基于键(Key)包含值(Value)。它实现了Map接口并扩展了HashMap类。
  • 它只包含唯一的元素。
  • 它可能有一个空键和多个空值。
  • 它是非同步的。
  • 它与HashMap相同,只是增加了一项维护插入顺序的功能。例如,当我们使用HashMap运行代码时,会得到不同的元素顺序。

声明:

public class LinkedHashMap<K,V>
    extends HashMap<K,V> implements Map<K,V>

这里, K 是键对象类型,而 V 是值对象类型。

  • K - 映射中键的类型。
  • V - 映射到映射中的值的类型。

它实现了Map<K,V>接口,并扩展了HashMap<K,V>类。尽管LinkedHashMap的层次结构如下面媒体所示

**** 如下

Java中的LinkedHashMap

LinkedHashMap的内部工作方式是什么?

LinkedHashMap是HashMap类的扩展,它实现了Map接口。因此,类被声明为:

public class LinkedHashMap
    extends HashMap
    implements Map

在这个类中,数据以节点的形式存储。LinkedHashMap的实现非常类似于双向链表。因此,LinkedHashMap的每个节点表示为:

Java中的LinkedHashMap

  • 哈希: 所有输入键都转换为哈希,这是键的缩写形式,以使搜索和插入更快。
  • 键: 由于这个类扩展了HashMap,数据以键值对的形式存储。因此,这个参数是数据的关键。
  • 值: 对于每个键,都关联有一个值。这个参数存储键的值。由于泛型的存在,该值可以是任何形式。
  • 下一个: 由于LinkedHashMap存储插入顺序,这个参数包含LinkedHashMap下一个节点的地址。
  • 上一个: 这个参数包含LinkedHashMap的上一个节点的地址。

同步LinkedHashMap

LinkedHashMap的实现不是同步的。如果多个线程同时访问一个LinkedHashMap,且至少一个线程在结构上修改了map,则它必须在外部同步。这通常通过在自然封装映射的某个对象上同步来实现。如果不存在这样的对象,则应使用 Collections.synchronizedMap 方法封装map。最好在创建时这样做,以避免意外的非同步访问map:

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

LinkedHashMap类的构造函数

为了创建一个 LinkedHashMap ,我们需要创建一个LinkedHashMap类的对象。LinkedHashMap类包括多种构造函数,允许可能的ArrayList的创建。以下是此类中可用的构造函数:

1.LinkedHashMap(): 这用于构造一个默认的LinkedHashMap构造函数。

LinkedHashMap<K,V> lhm= new LinkedHashMap<K,V>();

2.LinkedHashMap(int capacity): 用于使用指定的容量初始化特定的LinkedHashMap。

LinkedHashMap<K,V> lhm= new LinkedHashMap<K,V>(int capacity);

3.LinkedHashMap(Map? extends K, ? extends V> map): 用于使用指定地图的元素初始化具有特定值的特定LinkedHashMap。

LinkedHashMap<K,V> lhm = new LinkedHashMap<K,V>(Map<? extends K,? extends V> map);

4.LinkedHashMap(int capacity,float fillRatio): 用于初始化LinkedHashMap的容量和填充比。FillRatio也称为 loadFactor ,它是一个指标,用于确定何时自动增加LinkedHashMap的大小。默认情况下,此值为0.75,这意味着当地图的大小为75%时,会增加地图的大小。

LinkedHashMap<K,V> lhm= new LinkedHashMap<K,V>(int capacity,float fillRatio);

5.LinkedHashMap(int capacity, float fillRatio, boolean Order): 此构造函数也用于初始化具有特定容量和填充比率的LinkedHashMap,以及是否遵循插入顺序。

LinkedHashMap<K,V> lhm= new LinkedHashMap<K,V>(int capacity,float fillRatio, boolean Order);

在此,订单属性中,true表示最后访问订单,false表示插入顺序。

LinkedHashMap方法

方法 描述
含有合法值(Object value) 如果此地图将一个或多个键映射到指定的值,则返回true。
entrySet() 返回此地图中包含的映射的Set视图。
get(Object key) 返回特定键映射到的值,如果此地图不包含键的映射,则返回null。
keySet() 返回此地图中包含的键的Set视图。
removeEldestEntry (Map.Entry <K, V> eldest) 如果此图应删除其最古老的条目,则返回true。
values() 返回此地图中包含的值的集合视图。

应用: 由于LinkedHashMap使用双重LinkedList维护插入顺序,因此我们可以通过覆盖removeEldestEntry()方法来实现LRU缓存功能,以强制在将新映射添加到地图时自动删除旧图的策略。这样,您可以使用一些您定义的标准来过期数据。

例子:

// Java程序演示了LinkedHashMap的工作原理
  
// 导入所需的类
import java.util.*;
  
// LinkedHashMapExample
public class GFG {
  
    // 主驱动程序
    public static void main(String a[])
    {
  
        // 创建一个空的LinkedHashMap
        LinkedHashMap  lhm
            = new LinkedHashMap ();
  
        // 使用put()方法往Map中添加条目
        lhm.put("one", "practice.geeksforgeeks.org");
        lhm.put("two", "code.geeksforgeeks.org");
        lhm.put("four", "www.geeksforgeeks.org");
  
        // 打印Map中的所有条目
        System.out.println(lhm);
  
        // 注意:它按照插入的顺序打印元素
  
        // 获取并打印特定键的值
        System.out.println("Getting value for key 'one': "
                           + lhm.get("one"));
  
        // 使用size()方法获取Map的大小
        System.out.println("Size of the map: "
                           + lhm.size());
  
        // 检查Map是否为空
        System.out.println("Is map empty? "
                           + lhm.isEmpty());
  
        // 使用containsKey()方法检查键是否存在
        System.out.println("Contains key 'two'? "
                           + lhm.containsKey("two"));
  
        // 使用containsValue()方法检查值是否存在
        System.out.println(
            "Contains value 'practice.geeks"
            + "forgeeks.org'? "
            + lhm.containsValue("practice"
                                + ".geeksforgeeks.org"));
  
        // 使用remove()方法删除条目
        System.out.println("delete element 'one': "
                           + lhm.remove("one"));
  
        // 将映射关系打印到控制台
        System.out.println("Mappings of LinkedHashMap : "
                           + lhm);
    }
}

输出

{one=practice.geeksforgeeks.org, two=code.geeksforgeeks.org, four=www.geeksforgeeks.org}
Getting value for key 'one': practice.geeksforgeeks.org
Size of the map: 3
Is map empty? false
Contains key 'two'? true
Contains value 'practice.geeksforgeeks.org'? true
delete element 'one': practice.geeksforgeeks.org
Mappings of LinkedHashMap : {two=code.geeksforgeeks.org, four=www.geeksforgeeks.org}

LinkedHashMap类的各种操作

让我们看一下如何在LinkedHashMap类实例上执行一些经常使用的操作。

操作1:添加元素

为了将元素添加到LinkedHashMap中,我们可以使用put()方法。这与HashMap不同,因为在HashMap中不保留插入顺序,但在LinkedHashMap中保留它。

示例

// Java程序演示向LinkedHashMap添加元素
  
// 导入所需的类
import java.util.*;
  
// 主类
// AddElementsToLinkedHashMap
class GFG {
  
    // 主驱动程序
    public static void main(String args[])
    {
  
        // 使用泛型初始化一个LinkedHashMap
        LinkedHashMap  hm1
            = new LinkedHashMap ();
  
        // 使用put()方法向Map中添加映射关系
        hm1.put(3, "Geeks");
        hm1.put(2, "For");
        hm1.put(1, "Geeks");
  
        // 将映射关系打印到控制台
        System.out.println("Mappings of LinkedHashMap : "
                           + hm1);
    }
}

输出

Mappings of LinkedHashMap : {3=Geeks, 2=For, 1=Geeks}

操作 2:更改/更新元素

如果我们想要更改元素,则可以使用put()方法再次添加元素来实现。由于LinkedHashMap中的元素是使用键索引的,因此可以通过为我们希望更改的键重新插入更新后的值来更改键的值。

示例

// Java程序演示LinkedHashMap元素的更新
  
import java.util.*;
  
// 主类
// UpdatingLinkedHashMap
class GFG {
  
    // 主驱动程序方法
    public static void main(String args[])
    {
  
        // 使用泛型初始化LinkedHashMap
        LinkedHashMap<Integer, String> hm
            = new LinkedHashMap<Integer, String>();
  
        // 使用put()方法将映射插入Map中
        hm.put(3, "Geeks");
        hm.put(2, "Geeks");
        hm.put(1, "Geeks");
  
        // 将映射打印到控制台
        System.out.println("初始映射 : " + hm);
  
        // 使用键2更新值
        hm.put(2, "For");
  
        // 打印更新后的Map
        System.out.println("更新后的映射 : " + hm);
    }
}

输出

初始映射 : {3=Geeks, 2=Geeks, 1=Geeks}
更新后的映射 : {3=Geeks, 2=For, 1=Geeks}

操作 3:删除元素

为了从LinkedHashMap中删除元素,可以使用remove()方法。该方法将键的值作为输入,搜索是否存在此键,并如果该键存在于映射中,则从此LinkedHashMap中删除该键的映射。除此之外,还可以删除最先输入的元素(键值对)。

示例

// Java程序演示从LinkedHashMap中删除元素(键值对)
  
// 导入工具类
import java.util.*;
  
// 主类
// RemovingMappingsFromLinkedHashMap
class GFG {
  
    // 主驱动程序方法
    public static void main(String args[])
    {
        // 使用泛型初始化LinkedHashMap
        LinkedHashMap<Integer, String> hm
            = new LinkedHashMap<Integer, String>();
  
        // 使用put()方法插入元素
        hm.put(3, "Geeks");
        hm.put(2, "Geeks");
        hm.put(1, "Geeks");
        hm.put(4, "For");
  
        // 将结果打印到控制台
        System.out.println("初始映射 : " + hm);
  
        // 删除键值对(4, "For")
        hm.remove(4);
  
        // 将删除后的映射打印到控制台
        System.out.println("更新后的映射 : " + hm);
    }
}

输出

初始映射 : {3=Geeks, 2=Geeks, 1=Geeks, 4=For}
更新后的映射 : {3=Geeks, 2=Geeks, 1=Geeks}

操作 4:迭代访问LinkedHashMap

有多种方法可以迭代访问LinkedHashMap。最流行的方法是使用for-each循环遍历Map的set视图(使用map.entrySet()实例方法获取)。然后对于每个条目(set元素),可以使用getKey()和getValue()方法获取键和值的值。

示例

// Java程序演示
// 迭代遍历LinkedHashMap
  
// 导入必要的类
import java.util.*;
  
// 主类
// 迭代OverLinkedHashMap
class GFG {
  
    // 主驱动器方法
    public static void main(String args[])
    {
  
        // 使用泛型初始化LinkedHashMap
        LinkedHashMap<Integer, String> hm
            = new LinkedHashMap<Integer, String>();
  
        // 使用put()方法将元素插入映射中
        hm.put(3, "Geeks");
        hm.put(2, "For");
        hm.put(1, "Geeks");
  
        // 用于遍历映射的for-each循环
        for (Map.Entry<Integer, String> mapElement :
             hm.entrySet()) {
  
            Integer key = mapElement.getKey();
  
            // 使用getValue()方法查找值
            String value = mapElement.getValue();
  
            // 打印键值对
            System.out.println(key + " : " + value);
        }
    }
}

输出

3 : Geeks
2 : For
1 : Geeks

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程