「リシ、Arrays クラスの残りのメソッドについて学ぶのをとても楽しみにしています。

「これほどの学習熱心は、老先生を喜ばせるほかないでしょう!でも、本当にすべてを知りたいなら、グーグルという名の親切な魔法使いが昼も夜も助けてくれるでしょう。」

「えっと…」

「冗談です。まあ、もちろんすべてをもっとわかりやすく説明しますが、何か思いついた場合は、優れた魔法使いのことを思い出してください。今日のレッスンは次の方法で始めます。Arrays.fill

「配列を扱うとき、Java プログラマーは配列に同じ値を入力する必要があることがよくあります。もちろん、ループを作成して、ループ内の配列の各セルに単純に値を代入することもできます。

int[] x = new int[100];
for (int i = 0; i < x.length; i++)
x[i] = 999;

「または、これらすべての代わりに、メソッドを呼び出すこともできますArrays.fill()。このメソッドはまったく同じことを行い、渡された配列に渡された値を埋め込みます。これは次のようになります。

Arrays.fill(name, value)

上記の例のコードは、もう少しコンパクトでわかりやすくすることができます。

int[] x = new int[100];
Arrays.fill(x, 999);

"美しい!"

「このArrays.fill()メソッドを使用して、配列全体ではなく、配列の一部に値を入力することもできます。

Arrays.fill(name, first, last, value)

" firstlastは、入力される最初と最後のセルのインデックスです。

Java の古き良き (または悪しき) 伝統に従って、最後の要素は範囲に含まれないことに注意してください

例:

int[] x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

Arrays.fill(x, 3, 7, 999);


String str = Arrays.toString(x);

セルx[3]x[4]x[5]x[6]に値 を入力します999。配列のセルには 0 から始まる番号が付けられます。

変数strには値が含まれています
"[1, 2, 3, 999, 999, 999, 999, 8, 9, 10]"

「このArrays.fill()メソッドは 1 次元配列でのみ機能します。2 次元配列をメソッドに渡すと、それは 1 次元として扱われ、その後のすべての結果が生じます。

Arrays.copyOf()

「アミーゴ、配列を作成した後にサイズを変更する方法を教えてください。」

「うーん...それはひっかけ質問ですよね。私はもう経験が浅いわけではありません。正解は、できないということです。配列の作成後にサイズを変更することはできません。」

「しかし、本当にそうしたい場合はどうしますか?」

「まだ無理だよ!

「実際のところ、本当にそうしたければ、それが可能です! プログラミングのトリックを使えば、次のようになります。

  1. まず、必要な長さの新しい配列を作成します。
  2. 次に、最初の配列のすべての要素をその配列にコピーします。

「このメソッドが行うことは次の 2 つですArrays.copyOf()。呼び出しは次のようになります。

Type[] name2 = Arrays.copyOf(name, length);

「このメソッドは既存の配列を変更しませんが、代わりに新しい配列を作成し、古い配列の要素をそこにコピーします。」

新しい配列の長さが既存の配列の長さより短い場合はどうなるでしょうか?

「素晴らしい質問ですね、アミーゴ! 要素が適合しない場合、余分な値は単純に無視されます。」

「逆に、余分なセルがある場合、その初期値は何になるでしょうか?

「新しい配列の長さが古い配列の長さより長い場合、セルはゼロで埋められます。

例:

int[] x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int[] x2 = Arrays.copyOf(x, 5);
String str2 = Arrays.toString(x2);

int[] x3 = Arrays.copyOf(x, 15);
String str3 = Arrays.toString(x3);


変数str2には値が含まれます 変数には値が含まれます
"[1, 2, 3, 4, 5]"

str3
"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0]"

Arrays.copyOfRange()

「そして、長さ 10 の配列から長さ 5 の配列を取得したいが、最初の 5 要素ではなく最後の 5 要素を含める必要がある場合はどうなるでしょうか? この場合、クラスの別のメソッドが必要ですArraysArrays.copyOfRange()これを呼び出すと次のようになります。

Type[] name2 = Arrays.copyOfRange(name, first, last);

「このメソッドも新しい配列を作成しますが、元の配列の任意の場所の要素で配列を埋めます。firstとlastは、新しい配列に入れる必要がある最初と最後の要素のインデックスです。教えていただけますか?最後の要素はこの範囲に含まれますか?」

「ハッ! 私の偉大な先生がよく言っていたように、『Java の古き良き(または悪しき)伝統に従って、最後の要素は範囲に含まれないことを覚えておいてください』。」

「アミーゴ、あなたは私たちの目の前で成長しています。

例:

int[] x = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20};

int[] x2 = Arrays.copyOfRange(x, 5, 10);
String str2 = Arrays.toString(x2);

int[] x3 = Arrays.copyOfRange(x, 5, 15);
String str3 = Arrays.toString(x3);


変数str2には値が含まれます 変数には値が含まれます
"[16, 17, 18, 19, 20]"

str3
"[16, 17, 18, 19, 20, 0, 0, 0, 0, 0]"

Arrays.sort()

「そして最後に、私は最も...うーん...楽しい方法を最後に残しました。sorting プログラミングでは配列は頻繁にソートされます。配列を扱うときに最もよく使われるアクションの上位 3 つは次のとおりです。

  • 配列のソート
  • 配列の最小 (または最大) 要素を見つける
  • 配列内の要素のインデックスを決定する (配列内の要素を検索する)

「優れたパフォーマンスのソート アルゴリズムを作成するのは、それほど簡単ではないと言わざるを得ません。より正確に言えば、これは標準的なタスクであり、学生として時々ソート アルゴリズムを書く練習をすることに害はありません。しかし、仕事では、車輪の再発明に時間を無駄にしないほうがよいでしょう。Java の作成者はこのsort()メソッドをクラスに含めましたArrays。呼び出しは次のようになります。

Arrays.sort(name);

このメソッドは、渡された配列を昇順にソートします。

例:

int[] x = {11, -2, 3, 0, 999, -20, 8, -20, 99, -20};

Arrays.sort(x);
String str = Arrays.toString(x);


変数strには値が含まれています
"[-20, -20, -20, -2, 0, 3, 8, 11, 99, 999]"

「素晴らしい! メソッドを 1 つだけ呼び出しただけで、配列がソートされました。素晴らしいことです。」

ちなみに、配列全体だけでなく、配列の一部だけをソートすることもできます。呼び出しは次のようになります。

Arrays.sort(name, first, last);

firstlast は、ソートが触れる必要がある最初と最後のセルのインデックスです。そして…

「あなたが言いたいことはもうわかっています! 「Java の古き良き (または悪しき) 伝統に従って、最後の要素は範囲に含まれないことを覚えておいてください。

例:

int[] x = {11, -2, 3, 0, 999, -20, 8, -20, 99, -20};

Arrays.sort(x, 4, 8);
String str = Arrays.toString(x);


変数strには値が含まれています
"[11, -2, 3, 0, -20, -20, 8, 999, 99, -20]"

「配列をソートするために、Java は最速のソート アルゴリズムであるQuickSortを使用します。その計算の複雑さは配列のサイズに依存し、式 N log(N) を使用して計算されます。

「1000 要素の配列をソートするには、配列要素の約 10,000 回の比較が必要になります。100 万要素の配列をソートするには、約 2000 万回の比較が必要になります。」

要素の数を考慮すると、それほど多くの比較はありません!」

「まさにその通りです。QuickSortアルゴリズムは非常に効率的です。

Arrays.binarySearch()

「そうですね、このクラスの最後の最も興味深いメソッドは、Arrays配列内の指定された値を検索できます。これは通常の検索ではありません。これは、人気の二分検索です。要約すると、次のようになります。

  • まず、配列がソートされます。
  • 次に、配列の中央の要素が、探している要素と比較されます。
  • 要素が中央の要素より大きい場合、配列の右半分で検索が続行されます。
  • 探している要素が中央の要素より小さい場合、配列の左半分で検索が続行されます。

「配列はソートされているため、1 回の比較で配列の半分を削除することができます。その後、次のステップで別の半分を廃棄する、というようになります。」

「素晴らしい! とても早くゴールに向かって進みます!」

「その通りです。100 万 (!) 個の要素からなる配列において、二分探索アルゴリズムは、わずか 20 回の比較で目的の要素のインデックスを見つけることができます。このアルゴリズムの欠点は、最初に配列を並べ替える必要があり、並べ替えにも時間がかかることです。

これを呼び出すと次のようになります。

int index = Arrays.binarySearch(name, value);

name配列の名前は、(たとえば、メソッドを使用してArrays.sort()) ソート済みで渡す必要があります。そしてvalue、配列内で検索している要素です。メソッドによって返される結果は、目的の配列要素のインデックスです。 。

例:

int[] x = {11, -2, 3, 0, 999, -20, 8, -20, 99, -20};
Arrays.sort(x);

int index1 = Arrays.binarySearch(x, 0);
int index2 = Arrays.binarySearch(x, -20);
int index3 = Arrays.binarySearch(x, 99);
int index4 = Arrays.binarySearch(x, 5);
xis
{-20, -20, -20, -2, 0, 3, 8, 11, 99, 999}

4
1(インデックス02でも可)
8
-7

「目的の要素が配列内に複数回出現したらどうなるでしょうか?」

「それは正しい質問です、アミーゴ。この場合、アルゴリズムはそのうちの 1 つのインデックスを返します (たとえば、それが重複要素の一番最初であるか、その逆であるかという保証はありません。重複要素の一番最後のものであるという保証はありません)。 。」

「配列に目的の要素がまったく含まれていない場合はどうなるでしょうか?」

「この場合、アルゴリズムは負のインデックスを返します。

ドキュメンテーション

「すべてが明らかです、リシ! これはとても興味深いものでした。」

「本当にこれが非常に興味深いと思われた場合は、 Oracle Web サイトArraysにあるクラスとそのメソッドの公式ドキュメントをゆっくり読んでください。

Arrays.mismatch()「たとえばやメソッドなどを詳しく見てみるとArrays.compare()、きっとうまく活用できるでしょう。

「メソッドの数に混乱しないでください。各メソッドには 5 ~ 10 のバリアントがあり、パラメータのタイプが異なるだけです。」