私は番号のリストを使用してピラミッドの構築に関するタスクを持っていますが、一つのテストの一つの問題があります。私の仕事では、私は、リストをソートする必要があります。私は)(Collections.sortを使用します。
Collections.sort(inputNumbers, (o1, o2) -> {
if (o1 != null && o2 != null) {
return o1.compareTo(o2);
} else {
throw new CannotBuildPyramidException("Unable to build a pyramid");
}
});
しかし、このテストは失敗します
@Test(expected = CannotBuildPyramidException.class)
public void buildPyramid8() {
// given
List<Integer> input = Collections.nCopies(Integer.MAX_VALUE - 1, 0);
// run
int[][] pyramid = pyramidBuilder.buildPyramid(input);
// assert (exception)
}
OutOfMemoryErrorが発生して代わりに自分のCannotBuildPyramidException(それはソートした後、別の方法でスローされます)。私はそれをCollections.sort()メソッドであるためTimSortであることを理解しています。私はヒープソートを使用しようとしましたが、私の入力リストは、()は、Arrays.asListとして初期化されたので、私もスワップ要素をcouldn`tと私はセット()メソッドを使用するとき、私はUnsupportedOperationExceptionを取得します。それから私は、共通のArrayListに私のリストを変換しようとしました
ArrayList<Integer> list = new ArrayList<>(inputNumbers);
しかし、私は再びOutOfMemoryErrorを得ました。それは `sは、編集テストに許可されていません。私はこの問題をどうするか知りません。Java8とIntelliJIdea SDKを使用してイム
作成されたリストがあること注意Collections.nCopies(Integer.MAX_VALUE - 1, 0)
使用しています小さなメモリの量をしている不変。ドキュメントは言う、「指定されたオブジェクトのコピーn個から成る不変のリストを返します。新しく割り当てられたデータオブジェクトは、(それがデータオブジェクトへの1つの参照が含まれています)小さなです」。あなたが見ればと実装、あなたはそれが1はその記述から期待まさにん表示されます。それは返すList
だけというオブジェクトをふりはサイズのみと素子保持、大きくなるように一度にし、任意の指標について尋ねられたとき、その要素を返します。
問題はCollections.sort
、その後二つあります:
- リストは不変であってはなりませんが、そのリストがあります。それはところでも説明して
UnsupportedOperationException
あなたがしようとしたとき、あなたが得ましたset()
。 - パフォーマンス上の理由から、それは「このリスト内のすべての要素を含む配列を取得し、[リストに戻ると書き込み]配列を、ソート」。したがって、この時点では小さなふりリストは爆破して、メモリの問題が発生しますありません。
だから、ソートに他のいくつかの方法を見つける必要があります。インプレース動作し、(リストがすでにソートされているように、正しいです)この入力のスワップ何もしないもの。あなたは、この入力にO(n)の時間とO(1)スペースを取り、ここで任意のスワップをしようとしない使用例のバブルソート、のためでした。
ところで、メモリの問題を得ることについて「理由TimSortの」:Timsortは非難に本当にないです。それはメモリの問題が発生する準備へのコピーの配列だとあなたも、Timsort部分に得ることはありません。さらに、Timsortは、スマートであり、データがすでにソートされ、その後、何もしないだろうことを検出します。あなたが実際にTimsort部分に手に入れた場合、またはあなたが直接リストにそれを適用できるのであれば、Timsortは問題を起こさないでしょう。