优化两个列表

时间:2016-03-22 15:43:06

标签: java algorithm optimization

我有两个Bill个对象列表,其date字段代表帐单创建的月份。我需要将bills列表中的一些对象添加到oldBills。如果oldBills列表中没有相同数据的帐单,则应添加帐单。

我是这样实现的:

outer:
for (Bill bill : bills) {
  Date billDate = bill.getDate();
  for (Bill bill1 : oldBills) {
    Date bill1Date = bill1.getDate();
    if (Objects.equals(billDate, bill1Date)) {
      continue outer;
    }
  }
  newBills.add(bill);
}
oldBills.addAll(newBills);

但我认为这不是最佳方式。

您可能有任何想法,如何优化此算法?

p.s。:java 7

5 个答案:

答案 0 :(得分:4)

由于Bill的getDate()必须是唯一的,我建议使用一个需要唯一密钥的Map,并且对密钥具有O(1)访问权限。

Map<Date, Bill> oldBills = new HashMap<>();
oldBills.putAll(newBills);

你也可以使用循环

for(Bill bill : newBills)
    oldBills.putIfAbsent(bill.getDate(), bill);

这将取代所有具有相同Date的账单。 putAll通常是O(N)操作,其中N是newBills

的大小

您可以从列表中构建这些地图。

// requires Java 8.
Map<Date, Bill> billByDate = bills.stream().collect(Collectors.groupingBy(Bill::getDate));

答案 1 :(得分:2)

如果比尔有&#39; n&#39;元素和oldBill有&#39; m,您的算法需要n * m次迭代。它是O(n^2)。可以通过对oldbill (O(n*logn) )进行排序,然后对bill (O(logn))的每个元素实施二进制搜索来改进它。因此,在这种情况下,所花费的总时间为O(nlog(n))

答案 2 :(得分:1)

for(Bill bill:bills)
    {
        if(!oldBills.contains(bill))
        {
            oldBills.add(bill);
        }

    }

我不确定你在做什么用'新账单',但是这会在没有重复记录的情况下向oldBills添加账单而不会强制执行并拥有^ 2算法。

答案 3 :(得分:1)

您可以使用HashMap对其进行优化。为此,您需要为Bill对象定义一个唯一的键。例如,日期和谁被支付到

count<<i->name; // for printing name.

答案 4 :(得分:0)

不是通过循环,而是使用返回布尔值的java.util.ArrayList.contains(Object o)。