从内存缓存中获取前3个元素

时间:2019-03-04 10:03:52

标签: java sorting caching hashmap

当我需要从top 3获取Map项时,可以编写代码

private static Map<String, Integer> SortMapBasedOnValues(Map<String, Integer> map, int n) {

        Map<String, Integer> sortedDecreasingly = map.entrySet().stream()
                .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).limit(n)
                .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2, LinkedHashMap::new));

        return sortedDecreasingly;
    }

我有一个内存缓存,用于跟踪某些应用程序数据,

public class MemoryCache<K, T> {


    private long timeToLive;
    private LRUMap map;

    protected class CacheObject {

        public long lastAccessed = System.currentTimeMillis();
        public T value;

        protected CacheObject(T value) {
            this.value = value;
        }
    }

    public MemoryCache(long timeToLive, final long timerInterval, int maxItems) {

        this.timeToLive = timeToLive * 1000;

        map = new LRUMap(maxItems);

        if (this.timeToLive > 0 && timerInterval > 0) {

            Thread t = new Thread(new Runnable() {

                public void run() {
                    while (true) {
                        try {
                            Thread.sleep(timerInterval * 1000);
                        } catch (InterruptedException ex) {
                        }
                        cleanup();
                    }
                }
            });

            t.setDaemon(true);
            t.start();
        }
    }

    public void put(K key, T value) {
        synchronized (map) {
            map.put(key, new CacheObject(value));
        }
    }

    @SuppressWarnings("unchecked")
    public T get(K key) {

        synchronized (map) {

            CacheObject c = (CacheObject) map.get(key);

            if (c == null)
                return null;
            else {
                c.lastAccessed = System.currentTimeMillis();
                return c.value;
            }
        }
    }

    public void remove(K key) {
        synchronized (map) {
            map.remove(key);
        }
    }

    public int size() {
        synchronized (map) {
            return map.size();
        }
    }

    @SuppressWarnings("unchecked")
    public void cleanup() {

        long now = System.currentTimeMillis();
        ArrayList<K> deleteKey = null;

        synchronized (map) {
            MapIterator itr = map.mapIterator();

            deleteKey = new ArrayList<K>((map.size() / 2) + 1);
            K key = null;
            CacheObject c = null;

            while (itr.hasNext()) {
                key = (K) itr.next();
                c = (CacheObject) itr.getValue();

                if (c != null && (now > (timeToLive + c.lastAccessed))) {
                    deleteKey.add(key);
                }
            }
        }

        for (K key : deleteKey) {
            synchronized (map) {
                map.remove(key);
            }

            Thread.yield();
        }
    }

}

在应用程序内部,我对其进行初始化

MemoryCache<String, Integer> cache = new MemoryCache<String, Integer>(200, 500, 100);

然后我可以添加数据

cache.put("productId", 500);

我想在MemoryCache类中添加功能,因此如果被调用,将基于该值返回前3个项目中的HashMap

您对如何实施有何建议?

1 个答案:

答案 0 :(得分:0)

虽然我没有一个好的答案,但是我将MemoryCache转换为HashMap,并在MemoryCache类中实现了附加功能,以后再将其与函数一起使用前面提供的可根据值

检索前3个项目

这是我更新的代码,

/**
 * convert the cache full of items to regular HashMap with the same
 * key and value pair
 *
 * @return
 */
public Map<Product, Integer> convertToMap() {

    synchronized (lruMap) {

        Map<Product, Integer> convertedMap = new HashMap<>();

        MapIterator iterator = lruMap.mapIterator();

        K k = null;
        V v = null;

        CacheObject o = null;

        while (iterator.hasNext()) {

            k = (K) iterator.next();
            v = (V) iterator.getValue();

            Product product = (Product) k;

            o = (CacheObject) v;
            int itemsSold = Integer.valueOf((o.value).toString());

            convertedMap.put(product, itemsSold);
        }

        return convertedMap;
    }
}