Как получить ограниченное количество значений из HashMap или LinkedHashMap?

Скажем, у меня есть LinkedHashMap, содержащий 216 записей, как мне получить первые 100 значений (здесь, типа Object) из LinkedHashMap<Integer, Object>.


person Adnan Ali Ch.    schedule 28.02.2012    source источник
comment
Вам нужны значения (как в вашем вопросе/заголовке) или записи (пары ключ: значение, как в вашем заявлении)?   -  person haylem    schedule 28.02.2012
comment
Ок, так и думал. Спасибо, тогда смотрите мой ответ (или другие). Тогда я немного переписал ваш вопрос для ясности.   -  person haylem    schedule 28.02.2012


Ответы (6)


Уродливый однострочник

Этот уродливый однострочник подойдет (и вернет ArrayList<Object> в случае вопроса):

Collections.list(Collections.enumeration(lhMap.values())).subList(0, 100)

Это будет работать и для HashMap, однако HashMap при поддержке HashSet нет гарантии, что вы получите первые 100 введенных значений; он будет работать и с другими типами с аналогичными ограничениями.

Примечания:

  • относительно неэффективен (прочитайте Javadoc, чтобы узнать, почему — хотя есть и хуже!),
  • будьте осторожны при использовании представлений (прочитайте Javadoc, чтобы узнать больше),
  • Я упоминал, что это было некрасиво.

Пошаговый пример использования

(согласно комментарию OP)

Map<Integer, Pair<Double, SelectedRoad>> hashmap3 =
  new LinkedHashMap<Integer, Pair<Double, SelectedRoad>>();

// [...] add 216 elements to hasmap3 here somehow

ArrayList<Pair<Double,SelectedRoad>> firstPairs = 
  Collections.list(Collections.enumeration(hashmap3.values())).subList(0, 100)

// you can then view your Pairs' SelectedRow values with them with:
//  (assuming that:
//    - your Pair class comes from Apache Commons Lang 3.0
//    - your SelectedRoad class implements a decent toString() )
for (final Pair<Double, SelectedRoad> p : firstPairs) {
    System.out.println("double: " + p.left);
    System.out.println("road  : " + p.right);
}
person haylem    schedule 28.02.2012
comment
У меня есть Map‹Integer, Pair‹Double,SelectedRoad› › hashmap3 = new LinkedHashMap‹Integer, Pair‹Double,SelectedRoad› ›(); Теперь мне нужно всего 100 строк из него. Пожалуйста, напишите код. Спасибо! - person Adnan Ali Ch.; 29.02.2012
comment
Просто замените Pair<Double, SelectedRoad> на Object в приведенном выше примере кода. Вы получите List<Pair<Double, SelectedRoad>> из 100 элементов. - person haylem; 29.02.2012
comment
вы имеете в виду List‹Pair‹Double,SelectedRoad› › mylist = new ArrayList(); Collections.list(Collections.enumeration(hashmap3.values())).subList(0, 100); - person Adnan Ali Ch.; 29.02.2012
comment
@AdnanAliCh: Нет, это должно работать так, как описано. То, что вы написали, ничего не сделает с ArrayList. Вместо этого вы можете написать так: ArrayList<Pair<Double,SelectedRoad>> firstPairs = Collections.list(Collections.enumeration(hashmap3.values())).subList(0, 100). - person haylem; 29.02.2012
comment
@AdnanAliCh: Дайте нам знать, как это работает для вас, и примите ответ, который лучше всего соответствует вашим ожиданиям, когда вы довольны результатом. - person haylem; 29.02.2012
comment
Большое спасибо. Ваше решение работает для меня..... Есть ли у вас какое-либо улучшенное решение, а не использование функции subList()..in.... Какой-то другой хороший подход для получения того же результата...Collections.list(Collections.enumeration (hashmap3.values())).subList(0, 100) - person Adnan Ali Ch.; 29.02.2012
comment
@AdnanAliCh: определение улучшено. Вам нужно четко определить, чего вы хотите с самого начала, или мы будем продолжать идти вперед и назад. Этот работает, но с некоторыми оговорками. Чего еще вы хотите, и каких предостережений вы хотите избежать, или какой точный результат вам нужен? - person haylem; 29.02.2012
comment
Спасибо за ваш ответ. Я нашел именно тот результат, который мне нужен! - person Adnan Ali Ch.; 29.02.2012
comment
В целом спасибо за РЕШЕНИЕ! Он работает достаточно хорошо для меня! - person Adnan Ali Ch.; 29.02.2012

Ну, начнем с того, что делать это для HashMap в соответствии с вашим заголовком не имеет особого смысла - HashMap не имеет определенного порядка, и порядок может меняться между вызовами. Хотя это имеет больше смысла для LinkedHashMap.

Там я бы использовал Guava. Iterables.limit метод:

Iterable<Object> first100Values = Iterables.limit(map.values(), 100);

or

// Or whatever type you're interested in...
Iterable<Map.Entry<Integer, Object>> firstEntries =
    Iterables.limit(map.entrySet(), 100);

Затем вы можете создать список из этого, или перебрать его, или что-то еще, что вы хотите сделать.

person Jon Skeet    schedule 28.02.2012
comment
+1 для Гуавы, я сразу подумал об этом, но предположил, что по какой-то причине это здесь нежелательно. Определенно лучше - во многих отношениях - чем моя уродливая линия, и даже короче :) - person haylem; 28.02.2012

Ты можешь сделать:

Map<Integer, Object> records;
List<Entry<Integer, Object>> firstHundredRecords
    = new ArrayList<Entry<Integer, Object>>(records.entrySet()).subList(0, 100);

Хотя учтите, что при этом будут скопированы все записи с карты.

person Tom Anderson    schedule 28.02.2012
comment
Копирование 100 ссылок на объекты не так дорого. Нравится. - person Andreas Dolk; 28.02.2012
comment
На самом деле он скопирует 216 ссылок. Но все равно это не так дорого. - person Tom Anderson; 28.02.2012
comment
Ах - да - подсписок вызывается в новом списке, который получил весь набор записей. TooManyBracketsConfusionError ;) - person Andreas Dolk; 28.02.2012

Чтобы скопировать только нужные вам записи с помощью библиотеки.

Map<Integer, Object> records;

List<Entry<Integer, Object>> firstHundredRecords = new ArrayList<>();
for(Entry<Integer, Object> entry : records.entrySet()) {
    firstHundredRecords.add(entry);
    if (firstHundredRecords.size()>=100) break;
}
person Peter Lawrey    schedule 28.02.2012
comment
Спасибо .. действительно хорошее решение! - person Adnan Ali Ch.; 28.02.2012
comment
Map‹Integer, Pair‹Double,SelectedRoad› › hashmap3 = new LinkedHashMap‹Integer, Pair‹Double,SelectedRoad› ›(); Список‹Запись‹Целое, Объект›› firstHundredRecords = new ArrayList‹›(); for(Entry‹Integer, SelectedRoad› запись: hashmap3.entrySet()) { firstHundredRecords.add(entry); если (firstHundredRecords.size()›=100) перерыв; } Но это не подходит для Map‹Integer, Pair‹Double,SelectedRoad› › hashmap3 = new LinkedHashMap‹Integer, Pair‹Double,SelectedRoad› ›(); - person Adnan Ali Ch.; 28.02.2012
comment
У вас должно быть Map<Integer, Pair<Double,SelectedRoad>> entry ваша IDE должна автоматически исправить это для вас. - person Peter Lawrey; 28.02.2012
comment
Автокоррекция IDT вернет это для (Запись‹Целое число, Пара‹Двойная, ВыбраннаяДорога›› запись: hashmap3.entrySet()) { firstHundredRecords.addAll((Collection‹? extends Entry‹Integer, SelectedRoad››) запись); если (firstHundredRecords.size()›=100) перерыв; } количество_число=0; for(int j=0;j‹100;j++){ System.out.println(значение № +count + : + firstHundredRecords.get(j).getKey()+::: + firstHundredRecords.get(j). получить значение()); количество++; } - person Adnan Ali Ch.; 28.02.2012
comment
И при выполнении у меня есть следующее исключение исключения в потоке main java.lang.ClassCastException: java.util.LinkedHashMap$Entry не может быть приведен к java.util.Collection - person Adnan Ali Ch.; 28.02.2012
comment
Здравствуйте, мистер @Peter Lawrey: я ищу от вас решение. - person Adnan Ali Ch.; 28.02.2012
comment
А что вы видите в отладчике? Это означает, что у вас есть общий тип, который неверен, или вы неправильно выполняете кастинг. Вам нужно поместить точку останова на строку, где возникает эта ошибка, или перехватить это исключение в отладчике. - person Peter Lawrey; 29.02.2012

Вы можете использовать счетчик. Ваш цикл foreach завершится, когда ваш счетчик достигнет 100.

person Rahul Borkar    schedule 28.02.2012

Напишите цикл, который использует Iterator.next() 100 раз, а затем останавливается.

Я собирался сказать что-то о NavigableMap и SortedMap, но их интерфейсы определяются в терминах ключей, а не индексов. Но тем не менее они могут быть полезны, в зависимости от того, в чем заключается ваша реальная основная проблема.

person dty    schedule 28.02.2012