JDK 7についてのIllagalAgment Exception:Comprison method violates general contract

2680 ワード

JDK 7についてのIllagalAgment Exception:Comprison method violates general contract
今日コミュニティの質疑応答を見た時に見た問題の一つは、アリ開発マニュアルのCompartorの実現に関する問題で、対称性、伝達性、反性を満たすことを提案しています。
この時、JDK 7と以上のバージョンでは、比較のための関数は上記の性質を満たす必要があります。
原因
理由はJDK 7で並べ替えアルゴリズムが再設計されたためで、一般的な規格からTimSortに並べ替えられました。このアルゴリズムは対称性と伝達性を満たす比較関数を使用する必要があります。そうでなければ、並べ替えアルゴリズムは正常に動作しなくなり、IllegalArgumentException:Comparison method violates its general contractの異常を抛り出すことができます。前のJDKバージョンでは、性質を満たさない比較関数を無視するだけで、フィードバックがありません。関連内容を参照してください。
Area:API:Utililililities Sympopsis:Updated sort behavior for Arays and Collection may throw n IlelelegalAlegalAretmenmenment Exceptioioioion Description:The sorting algorithm used byjavautil. Arays.Ararays.sort.sotototototoandandandandand.inininininininininininininininininininininininininininininininininininininininininininininggggggggggtototototototototototototototototontException if it detects a Comprable thatviolates the Comprable contract.The previous implement ation silently ignored such a situation.If the previous bevior is desired:you can use the new system property,java.util.Arays.use Meter 68
Descriptionは、java.util.Arrays.sortjava.util.Collections.sortによって使用されたアルゴリズムが代替されたものであり、新しいアルゴリズムが比較可能なオブジェクトが違法であると発見された場合、比較的約束(すなわち3つの性質)はIllegalArgumentExceptionを抛り出すことができ、以前のバージョンの実装において、違法比較の約束の場合は、黙って無視されるだけである。新しいシステム属性が使用されてもよい。java.util.Arrays.useLegacyMergeSortは、以前のバージョンの規格化された順序付けの挙動を回復する。
どうしても性質を満たさない比較関数を使うなら、どうすればいいですか?
方法もあります。JDK 7は元の並べ替えアルゴリズムを保留しています。java.util.Arrays.useLegacyMergeSorttrueに設定した後、JDK 7にも不満足な比較関数を使用できます。具体的な方法は1.Appliation、またはIDEであれば、起動時にパラメータ-Djava.util.Arrays.useLegacyMergeSort=trueを追加します。サーバーまたは他の動作環境であれば、設定ファイルに追加できます。JAVA_OPTS="$JAVA_OPTS -Djava.util.Arrays.useLegacyMergeSort=true"。実行します。
System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
しかし、第3の方法は必ずしも効果があるとは限りません。この属性は静的なので、JVMにAraysをロードした後は変更できません。詳細には、文末の参照ソース2とソース3をご覧ください。
最後に、比較関数を実現するときは、対称性、伝達性、自己反性を満足させる比較関数を実現するのが望ましい。
ソースを参照
最後にTimSortの詳細な説明については、ソース1を参照してください。TimSortのリンクをさらに理解し、JDK 7にjava.util.Arrays.useLegacyMergeSortを配置する方法について、参照元2を参照してください。ソース3はJDK 7の互換性について、ソース4を参照してください。上で引用した関連内容はここから来たものです。1.JDK 7のComprison method violates general contract異常2.「Comprison method violates general contract!」TimSort and Gride Layout 3.Comprison method violates general contract!Java 7 only 4.Java SE 7 and JDK 7 Comppatibility