ProcessingでArrayList解説

この記事では、ArrayListとはなんぞや?ということを配列と比べながらなんとなーくわかってもらえるように解説します。

※これはプログラミング初心者にわかりやすく解説することを目的としております。そのため、説明として正確でないことも多々あると思いますが、何卒ご了承いただければと思います。

(予習)配列って何?

プログラミングを学んでいくと、配列というのを学びます。配列の詳しい説明はここではしませんが、配列は私の中で「箱」または「格納する場所」と解釈しています。

例えば、「5個の箱を用意して、その中に任意の数字を入れていく」ということをしたい場合、以下のように書くことができます。

//Processingで書いています

int box[] = new int[5];//5個の箱を用意する

void setup(){
 for(int i=0;i<box.length;i++){
   box[i]=i*10;//5個の箱に数字を入れていく
 }
 println(box);//出力して、数字が入っているかどうか確認する
}

/*
出力結果
[0] 0
[1] 10
[2] 20
[3] 30
[4] 40
*/

あらかじめ決められた数の箱を用意して、その中に何かを格納する、ということができます。

ArrayListって何?

さて本題です。ArrayListとは、「欲しいだけ箱を用意することができる」ものだと解釈しています。例えば、「欲しいカードが出るまでガチャを回し続ける」とか「勝つまでじゃんけんする」のようなイメージで、「ゴールが見えない」ときによく使います。

例として、「グー(ROCK)が出るまでじゃんけんする」というプログラムを書きたい場合、以下のように書くことができます。

//Processingで書いています

ArrayList list = new ArrayList();//listというArrayListを作る

//じゃんけんで分かりやすいように、1=グー、2=パー、3=チョキとする
int ROCK=1;
int PAPER=2;
int SCISSORS=3;

//「グーが出たらtrueにする」というフラグを作っておく
boolean flag=false;

void setup() {
//「グーが出るまで」=「flagがfalseの間」
 while (flag==false) {
   int RockPaperScissors= (int)random(1, 4);//1,2,3のランダム
   list.add(RockPaperScissors);//listにランダムの結果を入れる
   if (RockPaperScissors==ROCK) {
     flag=true;//出た数字が1、すなわちグー(ROCK)のときflagをtrueにする
   }
 }
 //グーが出るまでの結果をすべて出力する
 for(int i=0;i<list.size();i++){
   println(list.get(i));
 }
}

/*
出力結果(例)
2
3
3
3
3
2
3
3
1
*/

この場合、実行するたびに出力結果が変わります。1回目にグーを出すときもあれば、1回目がチョキで2回目がグーのときもあります。今回の例の場合は9回目に初めてグーが出ました。(出すのちょっと遅すぎでは…?)

いかがでしょうか?list.add()やlist.size()は後ほど解説しますが、雰囲気は分かったのではないでしょうか?

あらかじめ「○回」というのが決まっていないときにArrayListはとても便利です。(ガチャを引くときは上限を決めてほどほどに…)

ArrayList vs. 配列

ArrayListと配列、なんとなく違いが分かったでしょうか?

最初の段階として、あらかじめ決まった数があるときは配列、ない時(ゴールが見えないとき)はArrayListを使う、と考えておくとわかりやすいかと思います。

ここで、あくまで「最初の段階」であることを覚えておいてください。

「あらかじめ数が決まっているときはArrayList使っちゃダメなの?」

実はそういうわけではないです。whileで数を決めてしまえば、ArrayListでも決められた数でできますし、何十万個の配列を事前に用意しておけば、ある程度ゴールが見えなくてもできてしまいます。

アルゴリズム処理の問題であったり、時と場合によって使い分けたりするのですが、これはArrayListについて詳しく書いてある記事や書籍が色々あるので、そちらを参照してください。

要は、両方とも使えることが大切です。どちらがいいかどうかは、使っていくとわかることもありますし、プログラミング言語によってもどちらが使いやすい、といったこともあります。極論ではありますが、両方とも使えることを目指しましょう。

(知識パート)ArrayListでできること

ここからは、ArrayListの特徴的なものを先ほどのじゃんけんのプログラムを使いながら紹介していこうと思います。

・ArrayList list= new ArrayList() 

またはArrayList<型> list = new ArrayList<型>()

まず、ArrayListを使うよーと定義します。ArrayList型はクラスなんですね。「配列みたいなことができるクラス」みたいな認識でしょうか、なんと便利なクラスなんでしょう。このとき、「list」は「list2」「panda」「array」など任意の文字で定義して大丈夫です。今回は「list」として進めます。

これを定義しただけでは、中身は空っぽです。なので、以下のようにプログラムを書いてみると、listの中身が何もないのが分かります。

//Processingで書いています

ArrayList list = new ArrayList();

void setup() {
   println(list);//listの中身を出力する
}

/*
出力結果
[]
*/

・list.add() 

空っぽのlistの中に、何かを格納したい!というときに使うのが、list.add()です。addは日本語で「追加する」なので、イメージしやすいですね。

じゃんけんの場合、1,2,3の中からランダムで出た数字を、list.add(RockPaperScissors)で追加しています。このときのlistの中身を見てみると、ちゃんと数字が入っているのが分かります。

//Processingで書いています

ArrayList list = new ArrayList();

void setup() {
   int RockPaperScissors= (int)random(1, 4);
   list.add(RockPaperScissors);//listにじゃんけんの結果を追加する
   println(list);//listの中身を確認する
}

/*
出力結果(例)
[2]
*/

・list.size()

listに入っているもの(要素)の数、私の解釈で言うと、「用意した箱の数」を知りたい場合は、list.size()というものを使います。配列でいうと、基本的にbox.lengthに相当するものになります。

以下のプログラムの場合、1回だけaddをしているので、list.size()は1となります。list.add()をすればするほどlist.size()も増えていきます。

//Processingで書いています

ArrayList list = new ArrayList();

void setup() {
   int RockPaperScissors= (int)random(1, 4);
   list.add(RockPaperScissors);//listにじゃんけんの結果を追加する
   println(list.size());//listの要素の数を出力する
}

/*
出力結果
1
*/

・list.get()

「3番目の箱の中身を取り出したい!」

このようなときに使うのがlist.get()です。配列ではbox[2]に相当するものが、ArrayListだとlist.get(2)というように書きます。

じゃんけんしたときに、何を出したのかを見たい場合は、以下のように書きます。

//Processingで書いています

ArrayList list = new ArrayList();

void setup() {
   int RockPaperScissors= (int)random(1, 4);
   list.add(RockPaperScissors);
   //注意!!ここで、list.get(1)やlist.get(list.size())ではありません!!
   println(list.get(0));
}

/*
出力結果(例)
2
*/

このとき、よく間違ってしまうのが、list.get(1)やlist.get(list.size())と書いてしまうことです。

配列の時にもよく引っかかるのですが、最初は中身が空っぽの状態なので、addで最初に作られる箱は「0番」の箱なのです。しかもこのとき、list.size()は「箱の数」なので、1になっています。ややこしい。

これは数をこなして解決する…というのが一番早い解決方法だと個人的には思います。なので、「間違わないようにする」のではなく、「間違いにすぐ気づく」方法を知っておくといいと思います。

「あ、list.get(list.size())にしてしまった!!」

このとき、出てくるエラーが「IndexOutOfBoundsException」です。(プログラミング言語によってエラー文は違ったりしますが、今回はProcessing(java)準拠で説明しています…)

これは、ググると詳しいエラー内容が出てきますが、要は「範囲外だぞー」ということです。例えば、「5個しか箱が用意されてないのに、6個目にアクセスしてもそんなものねえよ」という感じです。なので、「IndexOutOfBoundsException」に遭遇したら、「あーgetのところ間違えたかもなー」と間違いを修正していくといいと思います。

・list.remove()

ArrayListの特徴でもある、「要素を削除する」というものです。

removeも「削除する」という意味なので覚えやすいですね。

以下のプログラムで実際に要素を削除してみましょう。

//Processingで書いてます

ArrayList list = new ArrayList();

void setup() {
 for (int i=0; i<3; i++) {
   int Number= (int)random(1, 10);//1から10のランダムな数字を決める
   list.add(Number);//listにNumberを追加する
 }
 
 println("list.size()="+list.size());//list.size()を出力
 println("list"+list);//listの中身を出力
 println("list.get(0)="+list.get(0));//0番目の要素を出力
 
 list.remove(0);//0番目の要素を削除する
 
 println("list.size()="+list.size());//list.size()を出力
 println("list"+list);//listの中身を出力
 println("list.get(0)="+list.get(0));//0番目の要素を出力
}

/*
出力結果(例)
list.size()=3
list[1, 9, 5]
list.get(0)=1
list.size()=2
list[9, 5]
list.get(0)=9

*/

削除する前は[1,9,5]が入っていたのに、削除したら[9,5]になりましたね!

list.size()もlist.get(0)も変わっているのが分かると思います。

イメージとしては、「箱ごと消しちゃう!」というイメージです。

・list.set()

これは、「既に入っている要素を上書きする」というものです。

配列の場合、box[0]=1の後にbox[0]=2と書けば上書きされますが、ArrayListの場合は、list.set(参照する箱の番号,入れるもの)といった感じで書くと上書きすることができます。

以下のプログラムで実際に0番目の要素を上書きしてみましょう。

//Processingで書いています

ArrayList list = new ArrayList();

void setup() {
 for (int i=0; i<3; i++) {
   int Number= (int)random(1, 10);//1から10のランダムな数字を決める
   list.add(Number);//listにNumberを追加する
 }
 println("list.size()="+list.size());//list.size()を出力
 println("list"+list);//listの中身を出力
 println("list.get(0)="+list.get(0));//0番目の要素を出力
 
 int Number2= (int)random(1, 10);//1から10のランダムな数字を決める
 list.set(0, Number2);//0番目にNumber2を上書きする
 
 println("list.size()="+list.size());//list.size()を出力
 println("list"+list);//listの中身を出力
 println("list.get(0)="+list.get(0));//0番目の要素を出力

}

/*
出力結果(例)
list.size()=3
list[4, 9, 3]
list.get(0)=4
list.size()=3
list[1, 9, 3]
list.get(0)=1

*/

上書きする前は[4,9,3]と入っていたのに、上書きしたら[1,9,3]に変わっていますね!list.get(0)も4→1に変わっています。

上書きしているだけなので、list.size()は変わっていません。

おわりに

代表例のものを紹介しました。今回はすべてint型のものしか使いませんでしたが、string型やfloat型などももちろん使えますので、ぜひいろいろと調べて使ってみてください!

最後に、これは「なんとなーくわかる」ことを目的としていて、「もっと詳しく知りたい!」と思った方は、ぜひプログラミングの書籍を読んでみたり、大学の先生に質問してみたりしてみてください!

また、「正確な表現としては間違っているけど、入門としてはこのくらいの認識でいいだろう」という範囲で書いています。化学の電子配置が綺麗な円ではない、というのと同じイメージです。何卒ご了承くださいますようよろしくお願いいたします。

この記事が気に入ったらサポートをしてみませんか?