c语言编程笔录

首页 >   > 笔记大全

笔记大全

Java如何设置过期时间的map

更新时间:2023-10-19
前言:Java中的Map是一种常用的数据结构,它用于存储键值对,并提供了丰富的操作方法。有时候我们需要给Map中的元素设置一个过期时间,当元素超过指定的时间没有被访问时,自动将其从Map中清除。本文将介绍如何实现一个带过期时间的Map。 段落一:使用HashMap实现带过期时间的Map 我们可以使用HashMap作为底层数据结构来实现带过期时间的Map。思路是在插入元素时,同时记录其插入时间;在访问元素时,判断元素是否已经过期,如果过期则将其从Map中删除。这个过期时间可以通过设置一个等待时间来进行控制,当等待时间过去后,元素就被认为过期了。 下面是一个简单的实现示例:
import java.util.HashMap;
import java.util.Map;

public class ExpiringMap {

    private HashMap map;
    private HashMap expirationTimes;
    private long defaultExpirationTime;

    public ExpiringMap() {
        this.map = new HashMap<>();
        this.expirationTimes = new HashMap<>();
        this.defaultExpirationTime = 1000; // 默认过期时间为1秒
    }

    public void put(K key, V value) {
        map.put(key, value);
        expirationTimes.put(key, System.currentTimeMillis() + defaultExpirationTime);
    }

    public V get(K key) {
        if (isExpired(key)) {
            map.remove(key);
            expirationTimes.remove(key);
            return null;
        }
        return map.get(key);
    }

    private boolean isExpired(K key) {
        Long expirationTime = expirationTimes.get(key);
        return expirationTime != null && System.currentTimeMillis() > expirationTime;
    }
}
在这个示例中,我们通过两个HashMap来分别存储键值对和过期时间。在插入元素时,同时记录其插入时间;在访问元素时,判断元素是否已经过期,如果过期则将其从Map中删除。 段落二:自动清理过期元素 我们可以借助Java的多线程功能,在一个单独的线程中定时清理过期元素。具体实现方法是使用ScheduledExecutorService定时执行一个任务,该任务负责遍历Map,检查过期元素并清除它们。 下面是一个实现示例:
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ExpiringMap {

    private HashMap map;
    private HashMap expirationTimes;
    private long defaultExpirationTime;

    public ExpiringMap() {
        this.map = new HashMap<>();
        this.expirationTimes = new HashMap<>();
        this.defaultExpirationTime = 1000; // 默认过期时间为1秒

        ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
        executorService.scheduleAtFixedRate(this::cleanExpired, defaultExpirationTime, defaultExpirationTime, TimeUnit.MILLISECONDS);
    }

    public void put(K key, V value) {
        map.put(key, value);
        expirationTimes.put(key, System.currentTimeMillis() + defaultExpirationTime);
    }

    public V get(K key) {
        if (isExpired(key)) {
            map.remove(key);
            expirationTimes.remove(key);
            return null;
        }
        return map.get(key);
    }

    private boolean isExpired(K key) {
        Long expirationTime = expirationTimes.get(key);
        return expirationTime != null && System.currentTimeMillis() > expirationTime;
    }

    private void cleanExpired() {
        for (Map.Entry entry : expirationTimes.entrySet()) {
            if (System.currentTimeMillis() > entry.getValue()) {
                map.remove(entry.getKey());
                expirationTimes.remove(entry.getKey());
            }
        }
    }
}
在这个示例中,我们通过ScheduledExecutorService定时执行一个任务,该任务负责定期调用cleanExpired方法来清理过期元素。这个任务会在初始化ExpiringMap对象时启动,并以指定的过期时间为周期执行。 段落三:使用Apache的Commons Collections库 上面的示例中,我们手动实现了一个带过期时间的Map。然而,如果你不想手动实现,也可以使用Apache的Commons Collections库中已有的实现。该库提供了一个名为ExpiringMap的类,它可以轻松地实现带过期时间的Map。 具体实现方法是使用ExpiringMap类的builder()方法创建一个ExpiringMap对象,并使用withExpiration()方法设置过期时间。之后,可以像使用普通的Map一样使用ExpiringMap,它会自动清理过期元素。 下面是一个使用Apache Commons Collections库实现的示例:
import org.apache.commons.collections4.map.ExpiringMap;

import java.util.concurrent.TimeUnit;

public class Main {

    public static void main(String[] args) {
        ExpiringMap map = ExpiringMap.builder()
                .expiration(1, TimeUnit.SECONDS)
                .build();

        map.put("key1", "value1");
        map.put("key2", "value2");

        System.out.println(map.get("key1")); // 输出"value1"
        System.out.println(map.get("key2")); // 输出"value2"

        try {
            Thread.sleep(2000); // 等待2秒,使过期时间过去
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(map.get("key1")); // 输出null,因为已经过期
        System.out.println(map.get("key2")); // 输出null,因为已经过期
    }
}
在这个示例中,我们使用ExpiringMap类的builder()方法创建一个ExpiringMap对象,并使用withExpiration()方法设置过期时间为1秒。之后,我们可以像使用普通的Map一样使用ExpiringMap。 总结:本文介绍了Java中如何设置过期时间的Map。我们首先手动实现了一个带过期时间的Map,通过记录插入时间和判断过期时间来实现自动清理。之后,我们使用ScheduledExecutorService定时清理过期元素,并介绍了Apache Commons Collections库中已有的实现。无论是手动实现还是使用第三方库,都可以方便地解决这个问题。