2016-10-14 7 views
0

これはやりにくいかもしれません。類似したオブジェクトを効率的に比較してマージする方法

私は4つのフィールド(ID、タイムスタンプ、タイプおよび値)を持つオブジェクトの入力を取得する次のよう

私のセットアップがあります。タイムスタンプの順序に従ったものをセットに挿入する必要があります。これまでのところ、そう簡単:

ConcurrentSkipListSet<ScheduleElement> storage = new ConcurrentSkipListSet<>(new SEComparator()); 

今トリッキーな部分は:オブジェクトの小さな割合が同じ「資産」から来て、合併する必要があります。基本的に "重複"(同じID、タイムスタンプ、タイプ)がある場合は、値を加算して1つにマージする必要があります。

私はこれを2つの別々のステップで簡単に行うことができました。

しかし、その場合は(かなり長い)セットを2回上回ります。パフォーマンスがかなり重大であることを考えれば、私はそうしたくないでしょう。

私の最初のアイデアは、比較器を変更するために、compareTo = 0の場合、オブジェクト1の値がオブジェクト2の値だけ増加することです。オブジェクト2が0

public class SEComparator implements Comparator { 

public int compare(ScheduleElement o1, ScheduleElement o2) { 
    int i = (o1.getTime().compareTo(o2.getTime())); 
    if (i == 0) { 
     i = (o1.getId()).compareTo(o2.getId()); 
     if (i == 0) { 
      i = (o1.getType().compareTo(o2.getType())); 
      if (i == 0) { 
       o1.setValue(o1.getValue()+o2.getValue()); 
      } 
     } 
    } 
    return i; 
} 

@Override 
public int compare(Object o1, Object o2) { 
    throw new UnsupportedOperationException("Not supported yet."); 
} 
} 

を返すため、コンパレータに落とされ、このようなハックは全く予想外の何かを壊す場合は今のコーディングではなく、経験の浅いもの、私も推測を開始することはできません。

これは避けるべきですか?そうでない場合は、そのような解決策のために重要なスポットを経験していますか?

+1

compare()メソッドは**値を**比較する必要があります。それらを更新/変更することはできません!その理由の1つは、その呼び出し方法を制御できないことです。 「古い、新しい」、「新しい、古い」と呼ばれています。今すぐ動作させるかもしれませんが、あなたが** compare()の使用に違反しているので、他のバージョンのJavaがコードを破る可能性があります。 – Andreas

+0

ありがとう、それは "ない"です。それは私の質問に答えます。 –

+0

あなたの質問に答えていませんが、 'Comparator'を使わず、' Comparator 'を使ってください。このようにして、無用で実装不可能な 'compare'を取り除きます。 +++あなたが望む 'ConcurrentSkipListMap'は' Map'です。ほぼすべてのJavaセットがマップに基づいていることに注意してください。 – maaartinus

答えて

0

あなたはキーIDによってtimestamptypeに必要とそれらの同じキーフィールドを持つデータのvalueを更新した場合は、SetMapをする必要はありません。

上記ののキーをどのように強調表示していますか?これは、Mapキーで構成されているためです。

したがって、3つのキーフィールドを持つキークラスを作成します。マップの値を単なる値にするか、完全なものにするかは、すべてあなた次第です。

+0

この場所に鍵は必要ありません。このセットは、スレッドが必要なものを取得するための一時的なストレージバッファです。 しかし、入力がDBから来て、消費者に比べてむしろ遅いので、このストレージはタイムリーに埋められることが必須です。 –

+0

あなたはあなたのパフォーマンスが問題だと言った。私はちょうどそれを修正する方法を教えました。それを受け入れることを拒否した場合、それはあなたの損失です。 – Andreas

+0

新しい地図の建物は、そこから得られる以上に遅くなるのではないですか?私はあなたの答えを拒否しようとは思わなかった、私はちょうど(まだ)それの利益を見ることはできません。 –

関連する問題