Java - Как найти количество элементов в списке в другом списке - PullRequest
4 голосов
/ 22 апреля 2010

Скажите, у меня есть два списка:

List<String>products = new ArrayList<String>(); 
products.add("computer"); 
products.add("phone"); 
products.add("mouse"); 
products.add("keyboard"); 

List<String>cart = new ArrayList<String>(); 
cart.add("phone"); 
cart.add("monitor"); 

Мне нужно выяснить, сколько товаров в списке корзин существует в списке товаров. Для списков, приведенных выше, ответ будет 1 (так как телефон в продуктах и ​​корзине). Если список корзины был:

List<String>cart = new ArrayList<String>(); 
cart.add("desk"); 
cart.add("chair"); 

Результат будет равен 0. Если в корзине есть компьютер, мышь, стол, стул, результат будет равен 2 (для компьютера и мыши).

Есть ли что-то в коллекциях Apache Commons или Google Collections API ? Я просмотрел их и увидел способы подсчета сумок, но не из другого списка, хотя, возможно, я что-то упустил. Прямо сейчас, единственный способ, которым я могу придумать, состоит в том, чтобы перебрать элементы корзины и посмотреть, содержит ли продукция отдельный элемент и вести подсчет. Я не могу использовать containsAll , так как мне нужно количество (не логическое значение), и это может привести к сбою, если все товары в корзине отсутствуют в списке продуктов (что может произойти).

Я использую Java 1.6, если это имеет значение.

Ответы [ 7 ]

11 голосов
/ 22 апреля 2010

Если вы хотите создать другую коллекцию, вы можете сделать следующее:

List<String> productsInCart = new ArrayList<String>(products);
productsInCart.retainAll(cart);

Это даст вам все записи, которые появляются как в корзине, так и в товарах.

10 голосов
/ 22 апреля 2010
int count = 0;
for (String item : cart) {
   if (products.contains(item))
    count++;
   }
}
4 голосов
/ 22 апреля 2010

Для одной дополнительной строки кода для сортировки (плюс стоимость времени выполнения) и последующего вызова другого метода для проверки содержимого вы можете получить что-то, что может быть очень эффективным для списка продуктов, который очень long (пока список эффективен для произвольного доступа и порядок списка товаров не имеет значения для приложения):

Collections.sort(products);  // or maintain products in sort order at all times
int count = 0;
for(String i: cart) {
  if (Collections.binarySearch(products, i) >= 0) {
    count++;
  }
}
2 голосов
/ 22 апреля 2010

Если ваш набор данных небольшой или вас не интересует скорость, ответа Барта должно быть достаточно. Но когда у вас большой набор данных и вы не хотите, чтобы сложность O (N * N), вы можете использовать это (при условии, что название продукта не дублируется)

Set<String> productsSet = new HashSet<String>(products);

Затем используйте код Барта с products, замененным на productsSet.

Это должно дать вам результат в O (N) времени, хотя и будет стоить больше памяти.

2 голосов
/ 22 апреля 2010

Я уверен, что статический частотный метод в Collections пригодится здесь:

List<String>products = ...
List<String>cart = ...

for (String cartItem : cart) {
       int occurrences = Collections.frequency(products, cartItem);

       if (occurrences > 0) {
          System.out.println(cartItem + ": " + occurrences);
       }
} 

Это JDK 1.6 вверх. Если элемент в списке cart существует в продуктах, он будет напечатан с указанием количества вхождений. Просто удалите фразу if, если вы хотите также печатать 0 вхождений.

1 голос
/ 22 апреля 2010

Многие из опубликованных решений работают на «Мне нужно выяснить, сколько товаров в списке корзин существует в списке продуктов», но они могут основываться на других предположениях.

Некоторые работы, если вы предполагаете, что каждый элемент в продукте или корзине должен быть уникальным. В этом случае вы можете применить это с помощью HashSet вместо ArrayList.

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

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

1 голос
/ 22 апреля 2010

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

...