
スケーラブルで関数型でオブジェクト指向なScala入門(3)
Scalaの基本的なコレクション4タイプと制御構文・例外
クラスメソッド株式会社
中村 修太
2012/3/15
Scalaの特徴を紹介し、基本構文や関数、クラスなど、Scalaの基本的な機能について解説する入門連載
基本構文は、まだまだある
| 今回の主な内容 |
前回の記事「Scalaプログラミングで知っておきたい基本構文まとめ」では、Scalaの構文ルール、基本データ型と配列型の使い方、さらに演算子について紹介しました。今回はScalaのコレクションクラスの基本的な使い方、条件分岐や繰り返しなどの制御構文やScalaでの例外の扱い方について紹介します。
第1回記事では、Scala標準のREPLとScala IDEで動作を確認してみました。今後本記事のサンプルコードは、どちらで確認しても問題はありませんが、対話的に実行でき、1文ごとにコードの結果が分かって便利なので、基本的にはREPLを用いて説明していきます。
Scala IDEを使用する場合、第1回記事の『Scala IDE for Eclipseで「Hello Scala!」』を参照してプロジェクトを作成して実行してください。REPLを使用する場合は、コンソール上でscalaコマンドを実行し、REPLを起動してください。
Scalaの基本的なコレクション4タイプ
複数のデータの集まりを「コレクション」と呼び、データ構造に応じて、いろいろな操作を実行できます(Javaでいえば「java.util.ArrayList」「java.util.HashMap」など)。
Scalaでもコレクションはよく使用します。その中から特に使用頻度の高いコレクションをいくつか紹介します。
■ 【1】可変と不変
前回の記事では、後から値の変更が可能な「var」と定義時に値が決まり、後から変更できない「val」について紹介しました。コレクションについても、定義後に要素の更新や削除が可能な「可変(ミュータブル/mutable)コレクション」と、定義時に要素が決まる「不変(イミュータブル/immutable)コレクション」があります。
不変コレクションは操作として要素の追加や削除が可能です。これは新しいコレクションを作成して返すようになっており、元のコレクションは変更されません。
scala> val list1 = List(1)
list1: List[Int] = List(1)
scala> val list2 = 2 :: list1 //::はリストに要素を追加して新しいリストを返すメソッド
list2: List[Int] = List(2, 1)
scala> list1
res1: List[Int] = List(1)変数のときにも少し述べましたが、基本的には副作用の生じない不変コレクションを使用するようにしましょう。
■ 【2】シーケンス型
Scalaの「Seq」は、要素を順番に並べて管理できるコレクションです。Javaの場合、「java.util.List」(を実装したクラス)がよく使用されるコレクションですが、 Scalaでは、そういった用途だとSeqが使用されます。
実際には、Listクラス(Seqを継承したLinearSeqクラスを継承)を使用することが多いと思います。Listは先頭項目の追加/削除が高速ですが、「ランダムアクセス(添え字を使用した要素へのアクセス)が遅い」という特徴を持っており、先頭から順番に任意の処理していくのに向いています。
では、Listを使用してみましょう。Listは「scala.collection.immutable」パッケージに属する不変コレクションです。そのため、一度定義したら要素の変更はできません(※もし、可変なListを使用したい場合、「scala.collection.mutable」パッケージの「ListBuffer」を使用してください)。
StringのListを定義するなら、以下のようにします(要素の型は省略可能)。
val x:List[要素の型] = List(要素...)前回解説した「Array」と似ていますね。要素内容にアクセスするには「()」でアクセスします。
scala> val list1 = List("Scala")
list1: List[java.lang.String] = List(Scala)
scala> list1(0)
res9: java.lang.String = ScalaListの要素に代入をしようとすると、「scala.List」は不変のため、エラーになります。
scala> list1(0) = "Java"
<console>:9: error: value update is not a member of List[java.lang.String]
list1(0) = "Java"リストを構築するには「Nil」(空のList)と「::」(cons/コンス)を使用して構築します。
scala> val list1 = Nil
list1: scala.collection.immutable.Nil.type = List()
scala> val list2 = "Scala" :: list1
list2: List[java.lang.String] = List(Scala)
scala> val list3 = "Java" :: list2
list3: List[java.lang.String] = List(Java, Scala)「::」とは、Listが持つメソッドで、要素とListを結合します。ここではNil(空のList)と「"Scala"」(要素)を結合しています。
結合した要素はListの先頭に追加され、新しいListが返されます。ちょっと分かりにくいですが、メソッド名の最後が「:」(コロン)の場合、メソッド名の左右を入れ替えて記述しなければなりません。つまり、「"Scala" :: list1」という記述は「list1.::("Scala")」という意味になります。
Listでよく使用するメソッドを表1に示します。
| 表1 Listでよく使用するメソッド | ||||||||||
|
また、これら以外にもListには多数のメソッドがあります。詳しくは、ScalaのAPIドキュメントをご覧ください。
■ 【3】マップ型
これは「連想配列」「ハッシュマップ」と呼ばれるもので、キーと値の組からなる要素を扱うコレクションです。Javaの場合は、「java.util.HashMap」を使用することが多いのではないでしょうか。
Scalaでマップを使用する場合、「scala.collection.immutable.Map」クラスを使用します。Listと同じく、不変コレクションです(※もし可変なMapを使用したい場合、「scala.collection.mutable」パッケージのMapを使用してください)。
Mapを作成するには、以下のようにします。
Map[キーの型,値の型](キー1->値1,キー2->値2・・・)実際には、以下のようにします。
scala> val m = Map[String,Int]("Scala"->1,"Java"->2,"Ruby"->3)
m: scala.collection.immutable.Map[String,Int] = Map(Scala -> 1, Java -> 2, Ruby -> 3)Mapから値を取り出すには、「()」でキーを指定します。
scala> m("Scala")
res50: Int = 1なお、存在しないキーを指定すると、例外が送出されます。
scala> m("Clojure")
java.util.NoSuchElementException: key not found: Clojure
……Mapでよく使用するメソッドを表2に示します。
| 表1 Mapでよく使用するメソッド | ||||||||||||||
|
これら以外にもMapには多数のメソッドがあります。詳しくはScalaのAPIドキュメントをご覧ください。
■ 【4】タプル(Tuple)型
これは、Scala特有の便利なオブジェクトで、異なる型の要素を格納可能です。値をカンマで区切り「()」で囲んで定義できます(※Mapで要素に指定するキーと値のペアはTuple型になっています)。
また、要素の数は22個まで指定でき、要素の数に応じてクラスが決定されます。例えば、要素数が「String」「Int」の2つであれば、「Tuple2[String,Int]」と表せます。
scala> val t1 = ("Scala",10)
t1: (java.lang.String, Int) = (Scala,10)
scala> val t2:Tuple2[String,Int] = ("Java",20)
t2: (String, Int) = (Java,20)各要素を取得するためには、「t1._1(_と要素の順番)」と指定すればアクセスできます。_1は1番目の要素、_2は2番目の要素です。なお、不変なので値の代入はできません。
scala> val t = ("Scala",10,100.0d)
t: (java.lang.String, Int, Double) = (Scala,10,100.0)
scala> t._1
res71: java.lang.String = Scala
scala> t._2
res72: Int = 10Tupleはメソッドからの戻り値で複数要素を返したいときなどに便利です。JavaであればObjectの配列を利用したり、新たにクラスを定義して返したりすることもありますが、Tupleを使えば、わざわざクラスを作らなくても複数要素を返せます。
次ページでは、Scalaで用意されている制御構文を紹介します。Scalaでも、他の言語と同じように、条件分岐や繰り返しなど、基本的な制御構造を持っています。動作も、だいたい他の言語と同じですが、「Scalaの制御構造は値を返す(すべてではありません)」という特徴を持っているものもあります。それぞれ動きを見てみましょう。
1-2 |
| Index | ||||||
|
||||||
スケーラブルで関数型でオブジェクト指向なScala入門 バックナンバー 連載インデックスへ»
- 第1回 EclipseでScalaプログラミングを始めるための基礎
- 第2回 Scalaプログラミングで知っておきたい基本構文まとめ
- 第3回 Scalaの基本的なコレクション4タイプと制御構文・例外
- 第4回 基本的なパターンマッチとScalaで重要な“関数”
- 第5回 Scalaのクラスとオブジェクト、パターンマッチ
- 第6回 Scalaのパッケージ、アクセス修飾子、オブジェクト継承
- 第7回 Scalaのトレイトでプログラマをミックスインしてやんよ
- 第8回 JavaのGenericsよりも便利なScalaの型パラメータ
- 第9回 Scalaの抽象型と暗黙の型変換/引数、パラメータ制約
- 第10回 Scalaの並行処理とアクター、並列コレクション
- 最終回 カリー化、遅延評価などScalaの文法総まとめ&今後
| Java Solution全記事一覧 |
TechTargetジャパン
- Java SE 8、Java EE 7、Java Embeddedはどうなる? (2013/5/24)
OpenJDKで使えるJava 8の新機能、センサデータを企業で活用するJava Embedded、6月13日リリース予定のJava EE 7など - Play 2.xのScala Templatesでビュー&フォーム操作 (2013/5/21)
Play 2.xでビューを表現するための機能「Scala Templates」と、フォームを用いてデータをやりとりする方法を解説します - 知らないと現場で困るバージョン管理システムの基礎 (2013/5/20)
構成管理に不可欠ともいえるバージョン管理について、ブランチ機能を中心に紹介。SubversionからGitへの移行事例も - Hud美さんと学ぶRedmine×Jenkinsの神アジャイル (2013/5/17)
継続的インテグレーションとJenkinsとは何か紹介し、RedmineやGitとの連携方法を解説します
|
|
- TwilioとRailsで作る、電話でテキスト読み上げアプリ
- Java SE 8、Java EE 7、Java Embeddedはどうなる?
- 「Scalr」を使ったAWS管理を試す
- Google I/OでモバイルアプリUXの条件を考えた
- 秀丸スタートメニューで[スタート]ボタンを追加する
- Chrome拡張機能にpush通知をしよう
- データ分析に必要な「道具」を揃える
- 複雑なデータをバインドするには?
- LLMNRを使ったローカル・セグメント上での名前解決
- 「演算子のインジェクション」と「SSJI」
- DNSを使ってネットワークデバイスにホスト名で接続
- 「ポジションが上がる=マネージャ業務」ではない
キャリアアップ
- - PR -
イベントカレンダー
- - PR -
転職/派遣情報を探す
**先週の人気講座ランキング**
〜 Android編 〜
ホワイトペーパー(TechTargetジャパン)
「ITmedia マーケティング」新着記事
スマホ vs. タブレット、ユーザーの行動特性から考えるマーケティング戦略
これまで「PC対モバイルデバイス(スマートフォン/タブレット)」という図式で語られる...
リアルワールド、34万人のクラウドソーシングによるソーシャルリスニングサービスを開始
リアルワールドは5月23日、同社が提供する国内最大級のクラウドソーシングサービス「CROW...
Googleアナリティクスでテラバイト級のビッグデータ解析機能を提供――プレミアムユーザー限定
Google BigQueryは、2010年のGoogle I/Oで発表された、大量データセットの解析を実現する...

