Подсчет подмножества Java HashMap - PullRequest
1 голос
/ 12 февраля 2012

Как я могу легко найти размер подмножества HasMap, которое возвращает true для некоторого условия?

Допустим, у меня есть это:

HashMap<Company, Revenue> results;

И я хочу найти количество компаний, чей доход составляет 10.

Редактировать: Я хочу знать, есть ли у Java более быстрое решение, кроме for-loop.

Ответы [ 5 ]

1 голос
/ 12 февраля 2012

A Гуава Multimap, вероятно, самое простое решение, но это проще, чем предлагает @Fabian Barney ...

SetMultimap<Revenue, Company> companiesByRevenue =
  Multimaps.invertFrom(Multimaps.forMap(results), HashMultimap.create());
// view results as a Multimap, and then invert the key/value relationship to 
// find all keys associated with each value
return companiesByRevenue.get(desiredRevenue); // Set<Company>

Тем не менее, этоэто только быстрее, чем стандартный цикл for, если вам нужно сделать несколько запросов с разными доходами.Если вам нужно только искать компании с одним конкретным значением выручки, то нет более быстрого решения, чем простой цикл for.

1 голос
/ 12 февраля 2012

Вы можете использовать Guava Multimap в качестве второй карты. Эта карта связывает несколько значений с одним ключом. Таким образом, вы можете инвертировать свою текущую карту и использовать Доход в качестве ключа и связать с ней несколько компаний.

После этого вы можете легко получить все компании за определенный доход.

ListMultimap<Revenue, Company> revenue2Companies = ArrayListMultimap.create();
Revenue rev = ...;

List<Company> companies = revenue2Companies.get(rev);

Обязательно прочитайте javadoc о реализации, которую вы будете использовать. Для классов, используемых в качестве ключей, вам, скорее всего, придется реализовать правильный метод equals.

0 голосов
/ 12 февраля 2012

Попробуйте следующий фрагмент кода

List<Company> comp = new ArrayList<Company>();
for(Company cp : results.keySet()){
   if(results.get(cp).equals(10)){
     comp.add(cp);
   }
}

Преимущество хранения компаний в списке сделает доступным весь объект компании, когда вам нужно будет выполнить с ними какую-то операцию, а не просто хранить счет в переменной.

0 голосов
/ 12 февраля 2012

На самом деле не думаю, что есть способ сделать это без циклического перебора значений. В качестве значения вы можете использовать другую карту, которая определяется значением, по которому вы хотите выполнить поиск, и содержит список объектов «Доход». Однако это явно не динамично и довольно некрасиво.

0 голосов
/ 12 февраля 2012

Вы заботитесь о производительности или просто нуждаетесь в ответе?Простая версия:

int count = 0;
for (Revenue r : results.values()) {
  if (r.equals(10)) { // I'm not sure what your revenue class is, exactly.  Add appropriate comparison here. 
    count++
  }
}

Поскольку карты обычно основаны на ключах, операции на основе значений обычно неэффективны.

...