2016-03-22 24 views
3

Billの2つのリストがあり、請求書を作成した月を表すdateフィールドがあります。 billsリストからoldBillsにオブジェクトを追加する必要があります。 oldBillsリストに同じデータの請求書がない場合は、請求書を追加する必要があります。2つのリストの比較とマージを最適化

私はそれをこのように実装:

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); 

を私はこれが最善の方法ではないと思われます。

このアルゴリズムを最適化する方法はありますか?

PS:Javaの7

+0

請求書をユニークにするには? –

+0

日付は日付オブジェクトで表すことができます。これは、日付がミリ秒間異なっている可能性があることを意味します。 –

+0

カレンダーの日付で衝突を調べる場合は、['LocalDate']のオブジェクトを使用します( https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html)古いjava.util.Dateではなく、Java 8以降に組み込まれたjava.timeフレームワークのクラスクラス。上記の暦月ごとに比較する場合は、['YearMonth'](https://docs.oracle.com/javase/8/docs/api/java/time/YearMonth.html)クラスを使用してください。 –

答えて

4

ビルのgetDate()はユニークでなければならないので、ユニークなキーが必要なマップを使用し、キーにはO(1)アクセス権があります。

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

また、これは同じDateを持っている全ての紙幣を交換します

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

ループを使用することができます。 putAllは、通常O(N)操作です。ここでNはサイズです。newBills

このようなリストからこれらのマップを作成できます。

// requires Java 8. 
Map<Date, Bill> billByDate = bills.stream().collect(Collectors.groupingBy(Bill::getDate)); 
1
for(Bill bill:bills) 
    { 
     if(!oldBills.contains(bill)) 
     { 
      oldBills.add(bill); 
     } 

    } 

私はあなたが「新しい法案」でやっているが、これはそれを強制的にブルートせずにレコードを複製しなくても、oldBillsに手形を追加するかを正確にわからないんだけど^ 2アルゴリズム。

+0

私はこれが私のバージョンと同じだと思います。なぜなら、内部ループは実際に 'contains'関数であるからです。 – Kirill

+0

あなたのものは同じではありません。両方のループ(n^2)を反復していますが、ループは1つをループします。これにより、コンピュータの演算回数は少なくなりますが、同じ結果が得られます。 –

1

ハッシュマップを使用して最適化することができます。このためには、Billオブジェクトに対して一意のキーを定義する必要があります。例えば、日付、誰のために代わりにループを通過するの

public class Bill{ 
     ... 
     public String getKey(){ 
      return date.toString()+payedTo; 
     } 
} 

HahsMap<String,Bill> oldBills = ... 
for (Bill bill : bills){ 

    if (! oldBills.containsKey(bill.getKey()){ 
      oldBill.put(bill.getKey(),bill) 
    } 
} 
0

に払った、それはboolean型を返すjava.util.ArrayList.contains(オブジェクトo)を使用するのに十分です。

2

Billに「n」要素があり、oldBillに「m」がある場合、アルゴリズムにはn * m回の反復が必要です。それはO(n^2)です。 oldbill (O(n*logn))をソートしてから、請求書(O(logn))の各要素のバイナリ検索を実装することで改善できます。したがって、この場合、合計時間はO(nlog(n))となります。

+0

isnt n * logn + lognはn * lognと等価ですか? –

+0

@huseyintugrulbuyukisikそれを指摘していただきありがとうございます。それはタイプミスでした。 – learner