19.0406

配列(Array)

ここでは、配列 を、学習します。

ここで、Javaの話をして恐縮ですが、
  配列
  String型
は、class だと言われても、
なんか特殊で、得体の知れない感じが、あったのですが、
でも、私ぐらいのレベルでは、そんなに深く知らないからと言って、
別に困ることはないというか、そうなのですが、
でも、知っていた方が、何かいいことがあるような気がしてなりません。
今、Kotlin を、学習していますが、
出来れば、今度こそ、その謎にも迫りたいとは思っている、
今日この頃です。

まず、肝心なことは、
少しやり方が、classらしくなくても、
まずは、きっちりやり方を覚えることが、大切だ思います。
例えば、定義の方法。
配列や、String型 の深い部分に迫るのは、
普通のプログラミングでは、すぐコードを書けるようになって、
それから、考えても遅くはないでしょう。

全くなんのこっちゃと思われる方も多いと思いますので、
本題に入りましょう。
まず、
  配列とは?
それは、
  データの集まり
です。

例えば、
  (1, 2, 3)
  ("one", "two", "three", "for")
  (true, false, true)
  ("いち", "イチゴ", "にい", "にら")
  ('a', 'b', 'c')
などなどが、そうです。

まず、その、配列の作り方から始めましょう。
作り方は、2通りあります。


値型/ValueType で、配列を作る
Kotlin では、すべてが、オブジェクト であるということを読んで、
だったら、値型 とは何なんだだ?、みたいな気持ちでしたが、
ネットで検索していろいろ読んでいると、
値型 というのは、オブジェクトとしてふるまうべき時のみ、
そのための方法が用意されている、みたいな感じ?
いやまだ、きっちり理解はしてはいないのですが。
ということで、
  作り方のもう一つの、タイプとして、
  参照型(データはデータでも、実体がある住所のデータ)
で、行きます。

またまた前置きが長くなりましたが、
値型 で、配列を作るときは、
  Int型 の場合
  val iArray: IntArray = intArrayOf(1, 2, 3)
のように、
  int
という、名前がついてくることです。
サンプルアプリレベル の、アプリでは、使わないのも多いと思いますが、
ざっと、定義方法を、見た方が、理解しやすいと思われますので、
いろいろな、値型の、配列の定義を見てみましょう。

例えば、Int型 を集めた配列は、IntArray型 ですね。
また、Double型 を集めた配列は、DoubleArray型 になります。
(IntArray、DoubleArray は、class です。)
また、
  最初の文字を小文字にして、
  最後にOfがついた、、
例えば、
  intArrayOf(//配列に入れるもの)
は、例えば、println() のような、
  関数です。

まず、こうやって、配列を、作ります/定義します。

少し詳しく:

LongArray クラス/型 の、インスタンスである、Long型 の 要素 には、   
1L, 2L, 3L   
のように、後ろに、L が、ついていますが、   
これは、サフィックス/suffix と言います。   
これが、整数/Int型リテラル に付くと、Long型リテラル を、示すようになります。   
ただし、Byte型、Short型 には、用意されていません。   
また、FloatArray クラス/型 の、インスタンスである、   
Float型 の 要素 には、Fが、ついていますが、   
Double型リテラル(普通に少数を書いた場合)に付けると、   
Floatリテラル を、表すようになります。


参照型/クラス型 の、配列の作り方
参照型 配列 の 定義/作り方です。
クラス型 の、配列は、Array<T>クラス の、インスタンス です。
クラス型 は、まだ学習していませんが、
値型 以外だと言えます。
では、値型/ValueType とは、どのような、値 でしょうか?
これは、実は、「数値」 だそうです。
ただし、true/false に、関しては、そうであっても、
それを、数値に変換する方法は、Java/Kotlin では、数値に変換する手段は、
提供されていません。

値型 / value type
  Byte, Short, Int, Long, Char, Float, Double, Boolean型 を、指します。

なお、紛らわしいですが、Kotlinリファレンス・基本の型 の、区分とは、
一致していないので、気を付けましょう。
例えば、IntArray型 は、IntArrayクラス型 を、意味します。
それは、決して、値型 では、ありません。

また、Array<T> の T に、気づきました?
この T は、すべての、クラス型 に対応しており、
もし、Car型 の、配列を、作りたい時は、Array<Car> とすれば、OKです。
また、この部分は、推論できる場合、省略できます。
この T の使い方を、「ジェネリック」 と言いますが、この先学習します。
今回は、クラス型 の 配列 の、定義方法だけ覚えておきましょう。

いままで、class/クラス は、学習していませんが、一つ、すでに、class型を習っています
おなじみの?文字列 です。


配列を使う

1. 要素にアクセスする
まず、配列をイメージしてみましょう。
  val iArray: IntArray = intArrayOf(1, 2, 4, 8, 16)
このコードのイメージは、
  [1][2][4][8][16]
こんな風に、5つの要素が、[ ] という、箱に入っているイメージです。
ただし、気を付けることが、あります。
  この箱には、ナンバーが付けてありますが、
  0 スタート なのです。
つまり、
  0[1] 1[2] 2[4] 3[8] 4[16]
こんなイメージになりますね。

では、これを踏まえて、左から、2つ目の Int値 を、取り出して、コンソールに、
出力してみましょう。

こんなコードになります。

つまり、
  配列の変数名[ 箱に割り当てられたナンバー(インデックス)]
こんなコードで、配列の要素に、アクセスできるわけです。
(0スタート には、気を付けてください)


2. 配列の 要素 は、いくつ?
例えば、今のコードなら、配列の要素は、いくつありますか?
と聞かれたら、すぐに、「5つ」 と、答えられると思いますが、

  val iArray2: IntArray =
      intArrayOf(1, 2, 4, 8, 16, 4, 5, 111, 3, 10, 88, 124, 0, -3, -5, 121)

こんなコードでは、どうでしょう。
もっと長い配列でも、大丈夫ですが、こんなコードで、調べることが出来ます。

これは、
  配列の変数名.count()
とすれば、調べることが出来ます。


3. ArrayIndexOutOfBoundsExceptionについて
とても長い名前ですが、要は、
  例えば、
  3個しかない配列 に、対して、
  4番目 とか、5番目 の、要素に、アクセスしようとすると、
  「そんな要素は、存在しておじゃらぬぞ」
と、言っているわけです。

一度、これを試してみましょう
  println(iArray2[16])
このコードで、試しているのですが、「16」 なら、いいと思った人は、
  配列要素 の、インデックスは、0 スタート ということ
を、忘れています。
つまり、iArray2 の、
  インデックス番号 は、0 から 15 まで
ということになるわけです。

ここで、使っている、
  try
  catch
は、今後、学習しますが、
簡単に言うと、
  やって見る{
    コード
  } 例外(いわゆるエラー)をキャッチ(例外の変数: 例外の型) {
    処理(ここでは、「存在しておじゃらぬ」 と、コンソールに表示)
  }

ということで、ArrayIndex~Exception が、発生しました。
つまり、
  配列 においては、インデックスの外 に、アクセスしようとすると、例外(エラー)が、起こる!
ということです。


4. 配列の要素 を、for文 で、表示してみよう
for文 の、書き方は、覚えていますか?
忘れていたら、まず、復習してください。

ここでは、簡単な例で、試してみます。
配列の要素 が、多くなっても、やり方は同じですから。

では、コードを見てみましょう。

つまり、
  x が、0..(iArray3.count() -1) の、範囲で、変化していき、
    x の、それぞれの値(ここでは、012 / 0..2 なので)に対して、
     (-1なのは、3個の要素の時、0スタートにすると、
      インデックスは、1~3 ではなく、0~2 になるから.)
    println("iArray3[${x}]: ${iArray3[x]}")
  を、実行する
ということになります。

ただ、普通は、こんなややこしい書き方はせず、
  for文 は、
  配列のための機能
  を、備えています.

どういうことかと言うと、
  0..(iArray3.count() -1)
を、
  配列(配列インスタンス)に、置き換えられる
ということです。

すると、今のコードを、こんなに簡単に、書けます。
// UseArrayEasily.kt(簡単に、配列を使う)
fun main() {
    val iArray3: IntArray = intArrayOf(3, 9, -1)

    // element: 配列の要素
    for (element in iArray3) {
        println(element)
    }
}
/* 実行結果
3
9
-1
*/
さっき、
  x in 0..(iArray3.count() -1)
と、書いた部分が、
  element in iArray3
のように、とても簡単に書けます。

この意味は(element in iArray3)、
  配列の要素 in 作られた配列(配列インスタンス)
ということなのですが、
インスタンス とは、
  class/設計図 から作られた 実物/実体/実例
という意味です、インスタンス という言葉は、
オブジェクト指向プログラミング では、とても頻繁に出る言葉なので、
必ず覚えた方がいいです。

そして、
  for(配列の要素 in 配列インスタンス)
と書くと、
  つづく、{ // コード }
  の中で、
  順番に、配列の要素 が、使える

ようになります。

なお、element は、キーワード というわけではなく、
ここで、たまたま、element(要素 という意味)を使っただけで、何でも、OKです。
ここでの、element も、定義する必要はありません、、
Kotlin が、自動で、配列の要素 として、設定してくれます


では、最後に、classのインスタンス を、要素 にした 配列 でも、
同様なことが出来ることを、確認しましょう。
// UseStringArray.kt(文字列の配列 を使う)
fun main() {
    val StringArray = arrayOf(
        "Kotlin人気が沸騰して、", "Kotlinリファレンスがあふれる、", "世の中にならないかなあ~"
        )

    for (ele in StringArray) {
        println(ele)
    }
}
/*
Kotlin人気が沸騰して、
Kotlinリファレンスがあふれる、
世の中にならないかなあ~
 */
なお、上のコードでは、
  val StringArray: Array<String> = arrayOf( "文字列", "文字列", "文字列", "文字列")
において、
  文字列 の、配列 であることは、分かり切っているので、
  : Array<String>
を、省略してあります。



まとめ
値型(数値型) の、配列を、定義する/作る:
  変数ですよ 変数名: 変数の型 = 小文字で始まる変数の型と同じ名前Of(配列に入れるもの)

classインスタンス で、配列を、定義する/作る:
  変数ですよ 変数名: 変数の型 = arrayOf(配列に入れるもの)

要素にアクセスする:
  配列の変数名[箱に割り当てられたナンバー (インデックス)]

要素の数を調べる:
  配列の変数名.count()

ArrayIndexOutOfBoundsException とは:
  存在しない インデックスナンバー/要素 に、アクセスしようとして、
  発生する、例外(エラーの一種)

配列の要素 を、for文 で、利用する:
  for(配列の要素 in 配列インスタンス)
  と書くと、
  つづく、{ // コード }
  の中で、
  順番に、配列の要素 が、使える