получить последние n элементов из карты элементов java - PullRequest
0 голосов
/ 11 октября 2018

У меня есть map, и я хотел бы получить последние 50 элементов , вставленные в map или элементы, добавленные к map в последние 2 секунды (в зависимости от того, что больше) ..

Какой самый эффективный способ сделать это?

Map<Date, Book> books = new HashMap<Date, Book>();

Примечания: - Я хочу максимизировать пропускную способность и минимизировать задержки.- Я хочу работать на JVM и минимизировать объем кучи.

Ответы [ 3 ]

0 голосов
/ 11 октября 2018

Чтобы ответить на ваш вопрос в одном предложении:

По умолчанию у Карт нет последней записи, это не является частью их контракта.Карта A (Hash) Хранит оптимизированную память элементов.

Возможные решения Сортированные карты:

Вы можете получить доступ к последней записи с помощью метода lastEntry:

NavigableMap<String,Integer> map = new TreeMap<String, Integer>();
// add some entries
Entry<String, Integer> 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);

оба являются нативными библиотеками Java.

0 голосов
/ 11 октября 2018

Так как вы хотите получить последние элементы по дате , таким образом, для ключа Map<Date, Book> books вы можете сделать следующее:

  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());
  }

In getBooksOfLastXSeconds Я добавил сортировку, чтобы результат можно было легко сравнить.Что касается вопроса, в этом нет необходимости.

Давайте рассмотрим пример:

  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]
  }

РЕДАКТИРОВАТЬ
Какой самый эффективный способ сделать это?
Самый эффективный способ - заказать книги уже по дате вставки.Тогда нет необходимости сравнивать все книги (выполните sort выше), чтобы получить последние 50 книг.Вы можете использовать LinkedHashMap, чтобы сохранить порядок вставки.Порядок вставки должен быть естественный порядок из Date, таким образом, хронологический порядок.

0 голосов
/ 11 октября 2018

Используйте стек для хранения Date, а затем извлекайте элементы как ключ из стека.Просто нажимайте Date как клавишу всякий раз, когда вы делаете запись в HashMap .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...