2

JavaFX TableViewを裏付ける1秒に数百の更新を受け取る数千のエントリを持つJava ObservableListがあります。

ObservableList はArrayList によって支えられています。リストには任意の並べ替え順序を適用できます。更新により、リスト内の 1 つのエンティティの並べ替え順序が変更される場合があります。各更新後に並べ替えを実行しようとするとパフォーマンスの問題が発生するため、現在、毎秒並べ替えを実行するバックグラウンド タスクがあります。ただし、できればリアルタイムでソートしてみたいと思います。

リストが既にソートされていて、変更する要素のインデックスがわかっていると仮定すると、リストでソートを再度呼び出すよりも要素のインデックスを更新する効率的な方法はありますか?

Collections.binarySearch()更新する要素のインデックスを効率的に見つけるために使用できることは既に決定しています。更新された要素が移動する必要があるインデックスを効率的に見つけて ArrayList をシフトし、順番を維持する方法はありますか?

追加操作と削除操作も処理する必要がありますが、それらはあまり一般的ではありません。

4

6 に答える 6

4

JavaFX ObservableList / TableViewコンボでソートを処理する場合のいくつかの提案:

  1. モデル クラスに Property アクセサーが含まれていることを確認します。

    JavaFX 8+ には存在しない JavaFX 2.2 実装の奇妙な癖により、TableView は、プロパティ アクセサー関数を含むものを処理する場合よりも、プロパティ アクセサーを持たない大規模なデータ モデルを処理する場合の方がはるかに効率的ではありません。詳細については、JavaSwing のようにソート速度を改善する方法を参照してください。

  2. ObservableList で一括変更を実行します。

    監視されている ObservableList を変更するたびに、リストのリスト変更リスナーが起動され、変更の順列がオブザーバーに伝達されます。リストに加える変更の数を減らすことで、発生する変更イベントの数を減らすことができるため、オブザーバーの通知と処理のオーバーヘッドを減らすことができます。

    この手法の例としては、リスト データのミラー コピーを標準の観察不可能なリストに保持し、そのデータを並べ替えてから、その並べ替えられたデータを観察可能なリストに 1 回の操作で設定することが考えられます。

    時期尚早の最適化の問題を回避するには、操作が最初は遅く、最適化自体によって測定可能な大幅な改善が得られる場合にのみ、この種の最適化を行ってください。

  3. ObservableList を必要以上に頻繁に更新しないでください。

    JavaFX 表示フレームレートは、デフォルトで 60fps に制限されています。可視コンポーネントをパルス (フレーム レンダリング トリガー) で複数回更新する必要はないため、パルスごとにすべての変更をまとめてください。

    たとえば、ミリ秒ごとに新しいレコードが到着する場合、20 ミリ秒ごとに到着するすべてのレコードを照合し、それらの変更を一度に適用します。

    時期尚早の最適化の問題を回避するには、操作が最初は遅く、最適化自体によって測定可能な大幅な改善が得られる場合にのみ、この種の最適化を行ってください。

  4. Java 8 には、テーブルでソートされたコンテンツの使用を支援する新しいクラスがいくつか含まれています。

    Java 8 で TableView の並べ替え関数と SortList がどのように機能するかはよくわかりません。jfx-docs-feedback_ww@oracle.com に電子メールを送信して、Java 8 の TableView 並べ替え機能のサンプルとベスト プラクティスを含むチュートリアルを作成するよう Oracle に依頼できます。

    詳細については、javadoc を参照してください。

于 2013-09-26T09:33:54.073 に答える
4

TreeSet を使用します。時間の複雑さで順序を更新できますがO(log N)、ArrayList はO(n)エントリごとに挿入ソートを行います。

于 2013-09-25T19:05:28.367 に答える
2

リストを常にソートする必要があるかどうかは、明確ではありません。エントリをすばやく取得して更新するためだけに並べ替える場合は、HashMap を使用してすばやく行うことができます。HashMap<YourClass, YourClass>クラスのキー フィールドに適切な hashCode() および equals() メソッドを実装すると、を作成できます。ソートされたリストをたまにしか出力する必要がない場合は、Comparable<YourClass>インターフェイスを実装しTreeSet<YourClass>( map.keySet() )て を作成するだけで、HashMap のデータがそのままの状態でソートされた表現が作成されます。常にソートする必要がある場合TreeMap<YourClass,YourClass>は、HashMap の代わりに使用することを検討できます。マップはオブジェクトを取得する方法を提供するため、セットよりも簡単です。

于 2013-09-25T19:18:34.127 に答える
1

いくつかの調査の結果、 Collections.sort() は1つのアイテムでもかなり高速であると結論付けました。リスト内の項目を更新し、並べ替えを呼び出すよりも効率的な方法は見つかりませんでした。TableView は List インターフェイスに依存しているため、TreeSet を使用できず、並べ替え順序が変更されるたびに TreeSet を再構築する必要があります。

Timer または KeyFrame を使用して 60 FPS で更新しても、妥当なパフォーマンスを維持できることがわかりました。JavaFX 8 にアップグレードしない限り、より良い解決策は見つかりませんでした。

于 2013-10-31T00:08:37.670 に答える
0

配列リストから要素を取り出して、更新された要素を (ソート順に) 挿入することができます。

于 2013-09-25T19:06:08.740 に答える