はじめに
kotlinはjavaを簡潔に記述するために作られた言語であり
javaと互換性のある言語である
(個人的に)kotlinがいいとおもうところ
val と var
kotlinではjavaと異なりmutable(再代入可)、imutable(再代入不可)な変数をそれぞれ定義できます。
javaだといちいちfinalをつけねばなりません
//kotlin
// 再代入可能な変数
var mutableValue : Int = 1
// 再代入不可能な変数
val imutableValue : Int = 1
//java
// 再代入可能な変数
var Integer mutableValue = 1
// 再代入不可能な変数
var final Integer imutableValue = 1
null safety(null安全)
javaのoptionalと同じことがkotlinでは?の一文字で済みます。
また、安全なことがわかっているのにget()をしなくてはならないjavaに比べると
kotlinの場合,直接メソッドを呼ぶことができます。
その他の挙動はこちらをご確認ください。
//kotlin
// null可能
var nullableValue : String? = "nullableValue"
// null不可
val notNullValue : String = "notNullValue"
//null可能な値の操作
if( nullableValue != null){
print(nullableValue.length)
}
//java
// null可能
var Optinal<String> nullableValue = "nullableValue"
// null不可
val String notNullValue = "notNullValue"
//null可能な値の操作
if( nullableValue.isPresent()){
System.out.print(nullableValue.get().length)
}
名前付き引数
引数が複数あるメソッドだと何番目にどの値をセットするかは関数定義を見に行く必要があります。
kotlinでは名前付き引数という機能で、呼び出し側がどの引数に入れるかを名前で指定することができます。
これによってコードの可読性や変数のセット間違い(二番目にいれるところを三番目にセットしてた等)が
なくなります。
名前付き引数の詳細はこちらご確認ください
//kotlin
fun reformat(str: String,
normalizeCase: Boolean,
upperCaseFirstLetter,
divideByCamelHumps,
wordSeparator: Char) {
...
}
// 引数の名前が記載されているため可読性が高い
reformat(str,
normalizeCase = true,
upperCaseFirstLetter = true,
divideByCamelHumps = false,
wordSeparator = '_'
)
//java
public void reformat(String str,
Boolean normalizeCase,
Boolean upperCaseFirstLetter: Boolean,
Boolean divideByCamelHumps: Boolean
Char wordSeparator) {
...
}
//引数に何を指定してるかメソッド定義を見ないとわからない
reformat(str, true, true, false, '_')
data class
javaだとlombokを使わないと苦痛なデータクラスを
標準機能で実現できます。
また、自動で作られるcopyメソッドが強力でオブジェクトをディープコピーして
一部プロパティを変えることが簡単にできます。
サンプルだとあまり有効性を感じられないかもしれませんが、
プロパティの数が多いデータクラスだと有効性が実感できます
データクラスの詳細はこちらご確認ください。
//kotlin
data class User(val name: String, val age: Int)
//オブジェクトの生成とコピー
var yamashita39 = User(name = "yamashita", age = 39)
var yamashita40 = yamashita39.copy(age = 40)
//java
// lombok使ってる前提
@Data
@RequiredArgsConstructor
class User{
var final String name
var final Integer age
}
//オブジェクトの生成とコピー
var yamashita39 = new User("yamashita", 39);
var yamashita40 = new User(yamashita39.getName(),40);
簡単に書けるStrem処理
こちらにjavaのメソッドとkotlinのメソッドの逆引きがまとめられていますが、
私がよく使うのは以下です
- filterNot
- flatten
- mapIndexed
- toList
- toMap
- groupBy
どれも便利なのですが、
特に便利と思ったのがmapIndexed、flattenです。
(mapIndexedはjavaにはない)
//kotlin
// mapIndexed
data class Word(val index: Int, val word: String)
val words = listOf("あ","い","う","え","お")
.mapIndexed { index, str -> Word(index = index, word = str)}
.toList()
//flatten
val result = listOf(listOf(1, 2), listOf(3, 4)).flatten()
// result = [1, 2, 3, 4]
//java
// lombok使ってる前提
@Data
@RequiredArgsConstructor
class Word{
var final Integer index
var final String word
}
// mapIndexed相当の処理
var seed = listOf("あ","い","う","え","お");
var words = new ArrayList();
for (int i = 1; i < list.size() - 1; i++) {
String w = seed.get(i);
words.add(new Word(i,w));
}
//flatten相当の処理
val listInList = List.of(List.of(1, 2), List.of(3, 4))
var result = listInList.stream().flatMap(x -> x.stream())
.collect(Collectors.toList())));
// result = [1, 2, 3, 4]
#その他
その他にもたくさんあります!
(個人的に)微妙と思うところ
kotlinには三項演算子がありません。
三項演算子がない理由は
if式の説明にあるように普通のif分がその(三項演算子)の役割を満たすため。
と書かれていいます。
//kotlin
val max = if (a > b) a else b
//java
var max = (a > b) ? a : b
僕はjavaの三項演算子の書き方の方が好きです。