5

假设我有两个列表:

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 CollectionsGoogle Collections API中有什么东西吗?我已经查看了它们并查看了获取行李数量的方法,但不是来自另一个列表,尽管我可能遗漏了一些东西。现在,我能想到的唯一方法是遍历购物车项目并查看产品是否包含单个项目并保持计数。我不能使用containsAll因为我需要计数(不是布尔值),如果购物车中的所有项目都不存在于产品列表中(这可能会发生),那将失败。

如果这很重要,我正在使用 Java 1.6。

4

8 回答 8

13

如果您愿意创建另一个集合,您可以执行以下操作:

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

这将为您提供出现在购物车和产品中的所有条目。

于 2010-04-22T01:33:48.520 回答
10
int count = 0;
for (String item : cart) {
   if (products.contains(item))
    count++;
   }
}
于 2010-04-22T01:08:12.033 回答
4

对于要排序的额外代码行(加上运行时成本),然后调用不同的方法来进行包含检查,对于很长的产品列表(只要list 对于随机访问是有效的,并且产品的列表顺序对应用程序并不重要):

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++;
  }
}
于 2010-04-22T01:51:56.130 回答
2

我很确定这里的静态频率方法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-list 中的项目存在于 products 中,则会打印出现次数。if如果您还想打印 0 次出现,只需删除- 子句。

于 2010-04-22T01:25:02.013 回答
2

如果您的数据集很小或者您不关心速度,巴特的回答应该就足够了。但是当你有一个大数据集并且不想要 O(N*N) 复杂度时,你可以使用这个(假设没有产品名称重复)

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

然后使用 Bart 的代码products替换为productsSet.

这应该会在 O(N) 时间内为您提供结果,尽管会花费更多内存。

于 2010-04-22T01:53:32.953 回答
1

如果创建另一个集合不是一个约束,那么只需将两个列表中的列表元素添加到一个集合中。那么最终集合大小和两个列表大小之和的差异就是你的答案

于 2010-04-22T01:09:44.143 回答
1

发布的许多解决方案都适用于“我需要找出购物车列表中有多少商品存在于产品列表中。”,但它们可能基于不同的假设。

如果您假设产品或购物车中的每个元素都必须是唯一的,则有些工作。在这种情况下,您可能希望通过使用 HashSet 而不是 ArrayList 来强制执行此操作。

其他工作甚至适用于购物车中的重复元素,如果我们假设如果一个元素在产品中,则存在无限数量的该特定产品。如果我们不能假设这一点是行不通的,即我们假设产品中某个元素的出现次数意味着公司拥有的股票数量。在这种情况下,您可能需要考虑使用其他数据结构,例如 HashMap。

我想最终归结为所做的假设。您应该找出确切的条件并确定最适合您的问题的解决方案。

于 2010-04-22T02:46:35.537 回答
0

您可以使用API 对inStream的元素进行过滤和计数。productscart

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        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");

        cart.forEach(item -> System.out.println(item + ": " + products.stream().filter(e -> e.equals(item)).count()));
    }
}

输出:

phone: 1
monitor: 0

或者,您可以使用打印inCollections#frequency的每个项目的频率:cartproducts

for (String item : cart) {
    System.out.println(item + ": " + Collections.frequency(products, item));
}

或者,对于 中的每个项目cart,您可以迭代products并计算出现次数:

for (String item : cart) {
    int count = 0;
    for (String product : products) {
        if (item.equals(product))
            count++;
    }
    System.out.println(item + ": " + count);
}
于 2021-05-08T13:17:41.743 回答