私はList
のランダム要素を選択して返します。リストは非常に長く(数百万の要素)、この関数は1秒間に数千回呼び出されるため、効率が重要です。O(1)を強制的に実行する
MyClass getRandomElement(List<MyClass> myClasses) {
return myClasses.get(getRandomNumber(myClasses.size()));
}
は、このソリューションには二つの問題があります。
私の現在の実装は次のようになります。
List.get
は、O(1)
で実行することはできません。例えば、LinkedList
は、O(n)
にそれを実装します。size
は、すべてList
の実装でO(1)
で実行することは保証されていません。
私が気づいているすべての実装がO(1)
に実装されているため、2番目の点はあまり説得力がありません。最初の点は問題のある点です。
実装がO(1)
であることを保証する(コンパイル/実行時例外ではない)方法はありますか?インターフェイスを次のように変更すると考えました。
MyClass getRandomElement(ArrayList<MyClass> myClasses)
これは厳しいものです。ユーザーがImmutableList
でこの機能を呼び出せるようにします。それはお勧めです。
値がArrayList
またはImmutableList
のインスタンスであると主張できます。これにより他のO(1)
実装が排除されますが、おそらくそれを使用して暮らすことができます。しかし、これは実行時の強制であり、コンパイル時の強制ではありません。そして、私はこのチェックのランタイムオーバーヘッドが何であるか分かりません。
これはベストプラクティスですか? RandomAccess
のJavadocのから
さらに一般性のために['instanceof RandomAccess'](https://docs.oracle.com/javase/8/docs/api/java/util/RandomAccess.html)をアサートすることができます。 –
サポートしたいインターフェイス/クラスごとにメソッドを実装するだけではどうですか? – sdgfsdh
興味深い点は、呼び出し元が1秒間に何千回もメソッドを呼び出すと仮定しているため、呼び出し元にランダムアクセスリストを渡す必要があるということです。明らかに、両方ともこのメソッドの責任外です。 – Holger