これはやりにくいかもしれません。類似したオブジェクトを効率的に比較してマージする方法
私は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.");
}
}
を返すため、コンパレータに落とされ、このようなハックは全く予想外の何かを壊す場合は今のコーディングではなく、経験の浅いもの、私も推測を開始することはできません。
これは避けるべきですか?そうでない場合は、そのような解決策のために重要なスポットを経験していますか?
compare()メソッドは**値を**比較する必要があります。それらを更新/変更することはできません!その理由の1つは、その呼び出し方法を制御できないことです。 「古い、新しい」、「新しい、古い」と呼ばれています。今すぐ動作させるかもしれませんが、あなたが** compare()の使用に違反しているので、他のバージョンのJavaがコードを破る可能性があります。 – Andreas
ありがとう、それは "ない"です。それは私の質問に答えます。 –
あなたの質問に答えていませんが、 'Comparator'を使わず、' Comparator 'を使ってください。このようにして、無用で実装不可能な 'compare'を取り除きます。 +++あなたが望む 'ConcurrentSkipListMap'は' Map'です。ほぼすべてのJavaセットがマップに基づいていることに注意してください。 –
maaartinus