Java 从项目映射中检索最后n个项目
我有一个Java 从项目映射中检索最后n个项目,java,dictionary,data-structures,Java,Dictionary,Data Structures,我有一个map,我想检索插入map的最后50个项目,或者在最后2秒内添加到map的项目(以较大者为准) 我能做的最有效的方法是什么 Map<Date, Book> books = new HashMap<Date, Book>(); Map books=newhashmap(); 注: -我希望最大化吞吐量并最小化延迟。 -我希望在JVM上运行并最小化堆占用。使用堆栈存储日期,然后从堆栈中弹出项作为键。 只要在HashMap中输入内容时按Date作为键,就可以用一句话
map
,我想检索插入map
的最后50个项目,或者在最后2秒内添加到map
的项目(以较大者为准)
我能做的最有效的方法是什么
Map<Date, Book> books = new HashMap<Date, Book>();
Map books=newhashmap();
注:
-我希望最大化吞吐量并最小化延迟。
-我希望在JVM上运行并最小化堆占用。使用堆栈存储
日期,然后从堆栈中弹出项作为键。
只要在HashMap中输入内容时按Date
作为键,就可以用一句话回答您的问题:
默认情况下,地图没有最后一个条目,它不是合同的一部分。(散列)映射存储内存优化的项
可能的解决办法
已排序的地图:
您可以通过lastEntry方法访问最后一个条目:
NavigableMap<String,Integer> map = new TreeMap<String, Integer>();
// add some entries
Entry<String, Integer> lastEntry = map.lastEntry();
NavigableMap=newtreemap();
//添加一些条目
Entry lastEntry=map.lastEntry();
或者使用链接地图:
Map<String,String> map = new LinkedHashMap<String, Integer>();
// add some entries
List<Entry<String,Integer>> entryList =
new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
Entry<String, Integer> lastEntry =
entryList.get(entryList.size()-1);
Map Map=newlinkedhashmap();
//添加一些条目
列表条目列表=
新的ArrayList(map.entrySet());
最后一项=
get(entryList.size()-1);
两者都是本机Java库。因为您想要获取,因此地图册的键可以执行以下操作:
protected static List<Book> getLastXBooks(Map<Date, Book> books, int x) {
return books.entrySet().stream()
.sorted(Comparator.<Entry<Date, Book>, Date> comparing(Entry::getKey).reversed())
.limit(x)
.map(Entry::getValue)
.collect(Collectors.toList());
}
protected static List<Book> getBooksOfLastXSeconds(Map<Date, Book> books, int seconds) {
long now = System.currentTimeMillis();
long msAgo = System.currentTimeMillis() - seconds * 1000;
return books.entrySet().stream()
.filter(e -> e.getKey().getTime() <= now && e.getKey().getTime() >= msAgo)
.sorted(Comparator.<Entry<Date, Book>, Date> comparing(Entry::getKey).reversed())
.map(Entry::getValue)
.collect(Collectors.toList());
}
编辑
我能做的最有效的方法是什么?
最有效的方法是,在插入日期之前订购图书。这样就没有必要比较所有的书(进行上面的排序
)来得到最后50本书。您可以使用LinkedHashMap
来保留插入顺序。插入顺序必须是日期,因此是时间顺序。您可以使用树映射或类似的数据结构来保持顺序。如果您正在构建应用程序,我建议将所有数据存储到数据库中,并运行查询以按日期或最后50项提取数据。@ZenWright我不允许使用外部数据库..TreeMap按排序顺序维护顺序,但我希望维护最后的插入顺序..您必须只使用hashmap,否则您也可以使用其他数据结构?我想最大化吞吐量并最小化延迟。我想在JVM上运行并最小化堆占用。我想最大化吞吐量并最小化延迟。我想在JVM上运行并最小化堆占用。@KshitijRoshan推送和弹出操作在堆栈中非常有效,所以我想在这种情况下应该使用堆栈。Stack
不推荐使用(很久以前)使用ArrayDeque
instead@FedericoPeraltaSchaffnerLinkedList
也可以使用。@suvojit_007同意。它也可以使用,这是一个偏好问题。我认为ArrayDeque
在大多数情况下更好,但在这种特殊情况下,LinkedList
可以完成这项工作。TreeMap.lastEntry()
给出具有最大/最小键值的条目。向后迭代LinkedHashMap
应该可以做到这一点。
public static void main(String[] args) {
Map<Date, Book> books = new HashMap<Date, Book>();
for (int i = 0; i < 100; i++) {
Book book = new Book("Book " + (100 - i));
books.put(new Date(System.currentTimeMillis() - i * 100), book);
System.out.println(book);
}
List<Book> last50 = getLastXBooks(books, 50);
System.out.println(last50); // [Book: Book 100, Book: Book 99, ... Book 51, Book: Book 50]
List<Book> booksOfLast2Seconds = getBooksOfLastXSeconds(books, 2);
System.out.println(booksOfLast2Seconds); // [Book: Book 100, Book: Book 99, ... Book 82, Book: Book 81]
}