演算子は変数や値に対して操作を行うために使用されます。
値はオペランドと呼ばれ、2つのオペランドの間で行う操作は演算子によって定義されます。
以下の例では、100と50がオペランドで、+記号が演算子です。
var x = 100 + 50
+演算子は、上の例のように2つの値を加算するのによく使われますが、変数と値、または変数と変数を加算するのにも使用できます。
var sum1 = 100 + 50 // 150 (100 + 50)
var sum2 = sum1 + 250 // 400 (150 + 250)
var sum3 = sum2 + sum2 // 800 (400 + 400)
Kotlinの演算子は以下のグループに分かれています:
算術演算子は一般的な数学的操作を実行するために使用されます。
演算子 | 名前 | 説明 | 例 |
---|---|---|---|
+ | 加算 | 2つの値を加算します | x + y |
– | 減算 | 1つの値から別の値を引きます | x - y |
* | 乗算 | 2つの値を掛け算します | x * y |
/ | 除算 | 1つの値を別の値で割ります | x / y |
% | 剰余 | 除算の余りを返します | x % y |
++ | インクリメント | 値を1増やします | ++x |
— | デクリメント | 値を1減らします | --x |
代入演算子は、変数に値を代入するために使用されます。
以下の例では、代入演算子(=
)を使用して、変数x
に値10を代入しています。
var x = 10
加算代入演算子(+=
)は、変数に値を追加します。
var x = 10
x += 5
全ての代入演算子の一覧:
演算子 | 例 | 同じ意味 |
---|---|---|
= | x = 5 |
x = 5 |
+= | x += 3 |
x = x + 3 |
-= | x -= 3 |
x = x - 3 |
*= | x *= 3 |
x = x * 3 |
/= | x /= 3 |
x = x / 3 |
%= | x %= 3 |
x = x % 3 |
比較演算子は2つの値を比較し、ブール値(true または false)を返します。
演算子 | 名前 | 例 |
---|---|---|
== | 等しい | x == y |
!= | 等しくない | x != y |
> | より大きい | x > y |
< | より小さい | x < y |
>= | 以上 | x >= y |
<= | 以下 | x <= y |
論理演算子は変数や値間の論理を決定するために使用されます。
演算子 | 名前 | 説明 | 例 |
---|---|---|---|
&& | 論理積 | 両方の条件が真であれば true を返します | x < 5 && x < 10 |
|| | 論理和 | いずれかの条件が真であれば true を返します | x < 5 || x < 4 |
! | 論理否定 | 結果を反転させ、結果が真であれば false を返します |
Kotlinでは、変数の型はその値によって決まります。
val myNum = 5 // Int
val myDoubleNum = 5.99 // Double
val myLetter = 'D' // Char
val myBoolean = true // Boolean
val myText = "Hello" // String
ただし、前の章で学んだように、型を指定することも可能です。
val myNum: Int = 5 // Int
val myDoubleNum: Double = 5.99 // Double
val myLetter: Char = 'D' // Char
val myBoolean: Boolean = true // Boolean
val myText: String = "Hello" // String
型を指定する必要がある場合もあれば、指定しなくてもよい場合もありますが、異なる型が何を表すかを知っておくと良いでしょう。型を指定する必要がある場面については、後ほど詳しく学びます。
データ型は以下のグループに分かれます:
数値型は二つのグループに分かれます:
数値型を指定しない場合、整数値は通常 Int
として、浮動小数点数は Double
として返されます。
val myNum: Byte = 100
println(myNum)
val myNum: Short = 5000
println(myNum)
val myNum: Int = 100000
println(myNum)
L
」を付けることができます。val myNum: Long = 15000000000L
println(myNum)
整数値が 2147483647 までであれば Int ですが、それを超えると Long として定義されます。
val myNum1 = 2147483647 // Int
val myNum2 = 2147483648 // Long
浮動小数点型は小数を含む数値を表します。例えば、9.99 や 3.14515 です。Float と Double のデータ型が小数点数を格納できます。
F
」を付ける必要があります。val myNum: Float = 5.75F
println(myNum)
val myNum: Double = 19.99
println(myNum)
浮動小数点値の精度は、小数点以下の桁数を示します。Float の精度は約6〜7桁ですが、Double 変数の精度は約15桁です。そのため、大半の計算には Double を使用する方が安全です。
また、Float 型の値には末尾に「F
」を付ける必要があります。
浮動小数点数は、10のべき乗を示す「e
」または「E
」を使って科学的表記にすることもできます。
val myNum1: Float = 35E3F
val myNum2: Double = 12E4
println(myNum1)
println(myNum2)
ブール型は、値が true または false のいずれかしか取れません。
val isKotlinFun: Boolean = true
val isFishTasty: Boolean = false
println(isKotlinFun) // true を出力
println(isFishTasty) // false を出力
Char
データ型は単一の文字を格納するために使用します。文字は単一引用符で囲む必要があります。例えば、「'A'
」や「'c'
」です。
val myGrade: Char = 'B'
println(myGrade)
Java とは異なり、Kotlin では ASCII 値を使用して特定の文字を表示することはできません。Java では値 66 が「B」を出力しますが、Kotlin ではエラーになります。
val myLetter: Char = 66
println(myLetter) // エラー
String
データ型は文字列(テキスト)のシーケンスを格納するために使用します。文字列はダブルクォーテーションで囲む必要があります。
val myText: String = "Hello World"
println(myText)
配列は、複数の値を一つの変数に格納するために使用され、各値のために個別の変数を宣言する代わりに利用します。
型変換とは、あるデータ型の値を別の型に変換することです。
Kotlin では、数値型の変換は Java とは異なります。例えば、以下のコードでは Int 型を Long 型に変換することはできません。
val x: Int = 5
val y: Long = x
println(y) // エラー: 型が一致しません
数値型を別の型に変換するには、以下の関数のいずれかを使用する必要があります: toByte()
、toShort()
、toInt()
、toLong()
、toFloat()
、toDouble()
、または toChar()
です。
val x: Int = 5
val y: Long = x.toLong()
println(y)
変数はデータ値を格納するためのコンテナです。変数を作成するにはvar
またはval
を使用し、等号(=
)で値を割り当てます。
var 変数名 = 値
val 変数名 = 値
var name = "John"
val birthyear = 1975
println(name) // 名前の値を出力
println(birthyear) // 生年の値を出力
var
キーワードで宣言された変数は変更できますが、val
変数は変更できません。
他の多くのプログラミング言語とは異なり、Kotlinの変数は特定の型(例えば、テキスト用のString
や数字用のInt
)を宣言する必要がありません。以下の例では、テキストを格納する変数と数字を格納する変数を作成します。
var name = "John" // 文字列(テキスト)
val birthyear = 1975 // 整数(数字)
println(name) // 名前の値を出力
println(birthyear) // 生年の値を出力
Kotlinは「John」が文字列(テキスト)であり、1975が整数(数字)の変数であることを自動で理解することができます。しかし、もし必要であれば型を指定することも可能です。
var name: String = "John" // 文字列
val birthyear: Int = 1975 // 整数
println(name)
println(birthyear)
値を割り当てずに変数を宣言し、後で値を割り当てることもできます。ただし、これは型を指定した場合にのみ可能です。
以下のコードは正常に動作します:
var name: String
name = "John"
println(name)
以下のコードはエラーを生成します:
var name
name = "John"
println(name)
val
キーワードで変数を作成すると、その値は変更/再割り当てできません。
以下の例はエラーを生成します:
val name = "John"
name = "Robert" // エラー(valは再割り当てできません)
println(name)
var
を使用すると、値をいつでも変更できます。
var name = "John"
name = "Robert"
println(name)
val
を使用するかval
キーワードは、例えばPI(3.14159…)のように常に同じ値を保持する変数に使用すると便利です。
val pi = 3.14159265359
println(pi)
上記の例で見たように、println()
メソッドは変数を表示するために頻繁に使用されます。テキストと変数を組み合わせるには、+
文字を使用します。
val name = "John"
println("Hello " + name)
また、+
文字を使用して変数を他の変数に追加することもできます。
val firstName = "John "
val lastName = "Doe"
val fullName = firstName + lastName
println(fullName)
数値の場合、+
文字は数学の演算子として機能します。
val x = 5
val y = 6
println(x + y) // x + yの値を出力
上記の例では次のことを行っています。
println()
メソッドを使用してx + y
の値を表示します。結果は11です。変数は短い名前(例えばxやy)や、より説明的な名前(年齢、合計、総容量など)を持つことができます。Kotlinの変数に関する一般的なルールは次のとおりです:
$
および_
で始めることもできます(ただし、このチュートリアルでは使用しません)。myVar
とmyvar
は異なる変数です)。var
やString
などのKotlinキーワード)は名前として使用できません。上記の例でfirstName
とlastName
を変数名として使用したことに気づいたかもしれません。これは「キャメルケース」と呼ばれ、異なる単語を含む変数名を読みやすくするために良い習慣とされています。例えば、myFavoriteFood
やrateActionMovies
などです。
コメントはKotlinコードを説明し、より読みやすくするために使用できます。また、別のコードをテストする際に実行を防ぐためにも使用できます。
シングルラインコメントは二つのスラッシュ(//
)で始まります。//
から行の終わりまでのテキストはKotlinによって無視されます(実行されません)。
以下の例では、コードの行の前にシングルラインコメントを使用しています。
// これはコメントです
println("Hello World")
以下の例では、コードの行の最後にシングルラインコメントを使用しています。
println("Hello World") // これはコメントです
マルチラインコメントは/*
で始まり、*/
で終わります。/*
と*/
の間のテキストはKotlinによって無視されます。
以下の例では、コードを説明するためにマルチラインコメント(コメントブロック)を使用しています。
/* 以下のコードは画面に
Hello Worldと表示します。*/
println("Hello World")
println()
関数は値を出力したり、テキストを表示するために使用します。
fun main() {
println("Hello World")
}
いくつでもprintln()
関数を追加することができます。各関数の実行後に新しい行が追加されることに注意してください。
fun main() {
println("Hello World!")
println("I am learning Kotlin.")
println("It is awesome!")
}
また、数字を表示したり、数学的な計算を行うこともできます。
fun main() {
println(3 + 3)
}
また、print()
関数もあり、これはprintln()
関数と似ています。唯一の違いは、出力の最後に新しい行を挿入しないことです。
fun main() {
print("Hello World! ")
print("I am learning Kotlin. ")
print("It is awesome!")
}
前の章で、Main.ktというKotlinファイルを作成し、次のコードを使って「Hello World」を画面に表示しました。
fun main() {
println("Hello World")
}
fun
キーワードは関数を宣言するために使います。関数は特定のタスクを実行するために設計されたコードのブロックです。上記の例では、main()
関数を宣言しています。
main()
関数は、すべてのKotlinプログラムで見ることになります。この関数はコードを実行するために使用されます。main()
関数の中括弧 {}
の中のコードはすべて実行されます。
例えば、println()
関数はmain()
関数の中にあり、これが実行されます。println()
関数はテキストを出力・表示するために使用され、私たちの例では「Hello World」を出力します。
ポイント:Kotlinでは、コードの文の末尾にセミコロン ;
を付ける必要はありません(Java、C++、C#など他のプログラミング言語では必要なことが多い)。
Kotlinバージョン1.3以前では、パラメータ付きのmain()
関数を使用する必要がありました。例としては、fun main(args : Array<String>)
のように書かれていました。上記の例は次のように書かなければなりませんでした。
fun main(args : Array<String>) {
println("Hello World")
}
注意:現在はもう必要ありません。しかしこのままでもプログラムは問題なく動作しますので、過去の古いバージョンのコードが残っている場合はこのまま使用することもできます。
Kotlinを始める最も簡単な方法は、IDEを使用することです。
IDE(統合開発環境)は、コードを編集してコンパイルするために使用されます。
この章では、Kotlinを作成した同じ開発者によって開発されたIntelliJを使用します。IntelliJはこちらから無料でダウンロードできます。インストールは基本的にすべてデフォルトの設定のままで問題ありません。
IntelliJをダウンロードしてインストールしたら、IntelliJを起動し、「New Project」ボタンをクリックして新しいプロジェクトを作成します:
左側のメニューから「Kotlin」を選択し、プロジェクトの名前を入力します:
次に、Kotlinプロジェクトを始めるためにJDK(Java開発キット)をインストールする必要があります。「Project JDK」メニューをクリックし、「Download JDK」を選択し、バージョンとベンダー(例:AdoptOpenJDK 11)を選んで「Download」ボタンをクリックします:
JDKがダウンロードされてインストールされたら、選択メニューからそれを選び、「Next」ボタンをクリックして最後に「Finish」ボタンをクリックします
これでKotlinプロジェクトの作業を開始できます。IntelliJは優秀なIDEなので、さまざまなボタンや機能がありますが、今は特に気にしなくて大丈夫です。src(ソース)フォルダーを開き、次の画像の手順に従ってKotlinファイルを作成します
「File」オプションを選択し、Kotlinファイルに名前を付けます。今回は「Main」とします。
これで最初のKotlinファイル(Main.kt)が作成されました。いくつかのKotlinコードを追加して、プログラムを実行し、どのように動作するか見てみましょう。Main.ktファイルに次のコードを追加します
fun main() {
println("Hello World")
}
上記のコードの内容が理解できなくても心配しないでください。後の章で詳しく説明します。今は、コードを実行する方法に焦点を当てましょう。上部のナビゲーションバーで「Run」ボタンをクリックし、次に「Run」をクリックし、「Mainkt」を選択します。
次に、IntelliJはプロジェクトをビルドし、Kotlinファイルを実行します。出力は次のようになります:
「Hello World」が出力されましたね。初めてのKotlinプログラムの実行ができました!
Kotlinは、JetBrainsによって2016年にリリースされたモダンでトレンドのプログラミング言語です。
Java(最も人気のあるプログラミング言語の一つ)と互換性があるため、非常に人気があります。これにより、Javaのコード(およびライブラリ)をKotlinプログラムで使用することができます。
Kotlinは以下の用途に使用されます:
事前のプログラミング経験は必要ありません。
コレクションの集計操作(最大値や最小値などを求める操作)に関しては以下の記事でも解説しました。
しかし、上記事で紹介した関数以外にも、reduce()とfold()という関数があります。
これらは与えられた処理をコレクションの要素に順次行っていき、蓄積された結果を返り値として返します。処理では二つの引数を取り、一つ目が蓄積された値で二つ目がコレクションの要素です。
reduce()とfold()の違いは、fold()は初期値を設定することができ、それを一番最初に蓄積された値として使いますが、reduce()は一つ目の要素と二つ目の要素を最初の処理で引数として使います。
何はともあれ、まずは使い方を実際のコードで見てみるのが一番わかりやすいかと思います。
val numbers = listOf(5, 2, 10, 4)
val sum = numbers.reduce { sum, element -> sum + element }
println(sum) //21
val sumDoubled = numbers.fold(0) { sum, element -> sum + element * 2 }
println(sumDoubled) //42
reduceの一回目の処理ではsumとelementという引数にnumbersというリストの最初の要素(5)と二番目の要素(2)が入っています。二回目の処理ではsumに7、elementに10というように順に処理を行っていくことで要素全体の合計を求めることができます。
一方でfoldのほうでは引数に0を与えているので、sumに0が代入されます。elementには5が入っています。処理の中身ではelementに代入された値を二倍してsumに足しているので、最終的には要素全体を2倍した数の合計が求められます。
上記のfoldで行っている処理をreduceで書こうとして失敗した例が以下になります。
val numbers = listOf(5, 2, 10, 4)
val sumDoubledReduce = numbers.reduce { sum, element -> sum + element * 2 }
println(sumDoubledReduce) //37
何が間違っているかわかりますか?
これも全て二倍にして足しているように見えますが、実は一回目の処理でsumには5が代入されますが、5は二倍になっていないのです。だからといって処理の中身で sum * 2 + element * 2のようにしてしまうと、処理ごとに合計が2倍されてしまうため、求めていた結果は得られません。
このようにして行わせたい処理に応じてfoldとreduceを使い分けることが大切です。
foldを使って全ての顧客によって注文された商品のセットを返す関数を実装してください。
また前回の問題(コレクション flatMapでネスト構造をフラットにする)で実装したCustomer.getOrderedProducts()を使うこともできます。
なお、全ての関連するクラスはShop.ktに含まれています。
問題コード:
//全ての顧客によって注文された商品のセットを返す
fun Shop.getProductsOrderedByAll(): Set<Product> {
TODO()
}
fun Customer.getOrderedProducts(): List<Product> =
orders.flatMap(Order::products)
Shop.kt:
data class Shop(val name: String, val customers: List<Customer>)
data class Customer(val name: String, val city: City, val orders: List<Order>) {
override fun toString() = "$name from ${city.name}"
}
data class Order(val products: List<Product>, val isDelivered: Boolean)
data class Product(val name: String, val price: Double) {
override fun toString() = "'$name' for $price"
}
data class City(val name: String) {
override fun toString() = name
}
[expander_maker id=”1″ more=”ヒント” less=”非表示”]
2つのリストの積集合(リストAにもリストBにも含まれる要素)を求めるにはintersect関数を用います。
使用例)
val listA = listOf(1, 2, 3)
val listB = listOf(3, 4, 5)
val result = listA.intersect(listB)
println(result) //[3]
[/expander_maker]
[expander_maker id=”1″ more=”答え” less=”非表示”]
//全ての顧客によって注文された商品のセットを返す
fun Shop.getProductsOrderedByAll(): Set<Product> {
val allProducts = customers.flatMap { it.getOrderedProducts() }.toSet()
return customers.fold(allProducts, { orderedByAll, customer ->
orderedByAll.intersect(customer.getOrderedProducts())
})
}
fun Customer.getOrderedProducts(): List<Product> =
orders.flatMap(Order::products)
[解説]
初めにallProductsという定数に一人でも顧客が注文した商品全てのセットを保存します。
それをfoldの初期値に設定し、その要素とそれぞれの顧客が注文した商品で一致するものだけをorderedByAllという変数に格納していくことで、全ての顧客によって注文された商品のセットを作成することができます。
[/expander_maker]その他の問題はこちらからどうぞ。
この問題が解けた方は既に入門レベルを超えています。
次のステップとして、より実践的なKotlinスキルを身に着けたい方は以下の書籍がおすすめです。
[itemlink post_id=”2225″]
プログラミング学習はどうしても一人だとつまづいてしまう時がきます。調べればわかることも少なくないですが、最初のうちは調べ方もわからないことが多いため、あまり効率的ではありません。
効率的かつ挫折せずにプログラミングを学習したい方はスクールを検討してみるのも一つの手です。
中には無料で通えるスクールや、就職保証をしてくれるスクールなどもあるので、きっとあなたの目的に応じて最適のスクールが見つかります!以下の記事で評判がよく特におすすめのスクールをいくつかピックアップしているので、スクール選びで後悔したくない方は御覧ください!
コレクションの要素を操作したいとき、あるコレクションの要素がさらにリストになっているなど、ネスト構造を持つコレクションも少なくありません。コレクションの中のコレクションの要素にアクセスしたいときなどでも簡単にアクセスできるようにするための関数がKotlinには用意されています。
今回紹介するのはflatMap関数です。
flatMapは引数で指定した式や関数で要素を別のコレクションにしてくれます。引数に与えられた式や関数の戻り値である要素が全て格納されたリストが返されます。さっそく使用例を見てみましょう。
val containers = listOf(
StringContainer(listOf("one", "two", "three")),
StringContainer(listOf("four", "five", "six")),
StringContainer(listOf("seven", "eight"))
)
println(containers.flatMap { it.values })
//[one, two, three, four, five, six, seven, eight]
上のコード中のcontainersというリストは、3つのStringContainerというリストを要素として持っています。つまりリストの中にリストがあるネスト構造になっていますが、flatMapをcontainersに使ってあげることによって、3つのStringContainerの要素全てを要素にもつ新しいリストを生成しています。
新しくできた要素には元のリストの要素がネストされていない状態で入っているため、普通のリストのように処理ができるようになっています。
flatMapを用いて、以下の二つの関数を問題コードに実装してください。
なお、全ての関連するクラスはShop.ktに含まれています。
問題コード:
//与えられた顧客が注文した商品を全て返す
fun Customer.getOrderedProducts(): List<Product> =
TODO()
//一人からでも注文された商品を全て返す
fun Shop.getOrderedProducts(): Set<Product> =
TODO()
Shop.kt:
data class Shop(val name: String, val customers: List<Customer>)
data class Customer(val name: String, val city: City, val orders: List<Order>) {
override fun toString() = "$name from ${city.name}"
}
data class Order(val products: List<Product>, val isDelivered: Boolean)
data class Product(val name: String, val price: Double) {
override fun toString() = "'$name' for $price"
}
data class City(val name: String) {
override fun toString() = name
}
[expander_maker id=”1″ more=”ヒント” less=”非表示”]
val result = listOf("abc", "12")
.flatMap { it.toList() }
result == listOf('a', 'b', 'c', '1', '2')
flatMapは上記のようにして引数でフラット化したい対象を指定します。(上記例はネストではありませんが、文字列中の文字を一文字ずつフラット化しています)
また二つ目の関数に関しては、一つ目に実装したgetOrderedProducts()をflatMapの中で使うことによって簡単に実装することができます。
[/expander_maker] [expander_maker id=”1″ more=”答え” less=”非表示”]//与えられた顧客が注文した商品を全て返す
fun Customer.getOrderedProducts(): List<Product> =
orders.flatMap { it.products }
//一人からでも注文された商品を全て返す
fun Shop.getOrderedProducts(): Set<Product> =
customers.flatMap { it.getOrderedProducts() }.toSet()
別解
//与えられた顧客が注文した商品を全て返す
fun Customer.getOrderedProducts(): List<Product> =
orders.flatMap(Order::products)
//一人からでも注文された商品を全て返す
fun Shop.getOrderedProducts(): Set<Product> =
customers.flatMap(Customer::getOrderedProducts).toSet()
[解説]
①最終的にフラットにして利用したいのは顧客のもつ商品情報(Products)ですので、flatMapの引数にはproductsを指定します。
②一問目で実装したgetOrderedProducts()は顧客が注文した商品を全て返しているので、これを引数で全ての顧客上で呼び出すことによって、全ての顧客が注文した商品を全て取り出すことができます。つまり誰かが一度でも注文した商品は全てここに含まれていることになります。
戻り値の型はSetですので、忘れずにtoSet()で変換しましょう。
[/expander_maker]その他の問題はこちらからどうぞ。
プログラミング学習はどうしても一人だとつまづいてしまう時がきます。調べればわかることも少なくないですが、最初のうちは調べ方もわからないことが多いため、あまり効率的ではありません。
効率的かつ挫折せずにプログラミングを学習したい方はスクールを検討してみるのも一つの手です。
中には無料で通えるスクールや、就職保証をしてくれるスクールなどもあるので、きっとあなたの目的に応じて最適のスクールが見つかります!以下の記事で評判がよく特におすすめのスクールをいくつかピックアップしているので、スクール選びで後悔したくない方は御覧ください!
Kotlinの文法をまず学びたい!という方には以下の書籍がおすすめです。Kotlinは日本語書籍がまだ豊富とは言えない状況ですが、細かく解説されており、Kotlin入門者のかたでもつまずくことなく学習できると思います。
[itemlink post_id=”1743″]実際にアプリを作りながら覚えていきたい!という方には以下もお勧めです。はじめに上の書籍で文法をさらっと学んでから取り組むのがお勧めです。
[itemlink post_id=”1745″]