Kotlinに挑戦してみたので、いつも書いてるAndroidのコードを、Kotilnではどう書くのかわからなかったので、調べてみました。
やっていくうちに、Kotlinでできることがたくさんあって楽しくなったので、Javaとの比較だけでなく、Kotlinでできる便利な機能についても一部ご紹介しています。
また、自分で使った部分について記載しているので、情報に偏りがあるかもしれませんが、ご容赦ください。
入門したばかりなので、誤りがあった場合教えていただけるとうれしいです。
#基本
##定数・変数
変数には冒頭にvarを記述します。後で値を変更しない定数などではvalを使用します。
// 変数
int value = 1;
// 定数
final static int VALUE = 1;
// 値の変更不可
val value = 1
// 値の変更可
var value = 1
##型推定
Kotlinでは、入っているデータから型を推定するため、型を指定する必要がありません。
(もちろん、指定することもできます)
String text = "おはようございます。";
int number = 1234;
val text = "おはようございます。"
val number = 1234
// 型を明記する場合はコロン+型を追加する
var value: Integer = 1
##クラス・メソッド
メソッドの冒頭はfunと記述します。
クラスのextendsとimplementsはクラス名の後に:をつけて記述します
public class TestActivity extends AppCompatActivity implements OnMapReadyCallback {
@Override
public void onCreate(Bundle savedInstanceState) {
}
@Override
public void onMapReady(GoogleMap p0) {
}
}
class TestActivity : AppCompatActivity(), OnMapReadyCallback {
override fun onCreate(savedInstanceState: Bundle?) {
}
override fun onMapReady(p0: GoogleMap?) {
}
}
また、継承はoverrideを冒頭につけます。
なお、継承できるのはopenをつけたメソッドのみです。
public class Base {
public void print(String text) {
Log.d("print", text);
}
}
public class Sub extends Base {
@Override
public void print(String text) {
super.print(text);
}
}
// 継承できるクラス・メソッドはopenをつける
open class Base {
open fun print(text:String) {
Log.d("print", text)
}
}
// 継承するクラスは:の後に継承するクラスを記述する
class Sub : Base() {
// 継承するメソッドにoverrideをつける
override fun print(text: String) {
super.print(text)
}
}
##Nullable
?がついていない普通の型にはnullを代入できません。
クラス名の後に?を記述すると、Nullableとなり、nullを代入できます。
// nullを入れられる
String a = null;
val a:String = "test"
val b:String? = null
// aにはnullを入れられない(コンパイルエラー)
a = null
// nullがあり得ないので、NullPointerExceptionは起こらない
val aLength = a.length
// b(Nullable)にはnullを入れられる
b = null
// nullの可能性があるので、コンパイルエラーとなる
val bLength = b.length
// 下記のように書けば、コンパイルエラーとならない(nullの場合はnullが返却される)
val bLength = b?.length
// 下記のように書けば、nullの場合にはNullPointerExceptionが発生する
val bLength = b!!.length
// ただし、bがnullでない場合、!!を記述した処理以降の処理は、nullableではないString型として扱えるようになる
var chars = b.split("")
##文字列操作
Javaだと文字列と変数は+でくっつけたりしますが、Kotlinだと$をつけることで文字列の中に変数を入れることができます
int first = 1
int second = 2
String value = first + " * " + second + " = " + (first*second) + "です"
val first = 1
val second = 2
val value = "$first * $second = ${first * second}です"
##switch文
when文を使用します。switchより複雑なことができます。
また、whenではbreakは必要ありません。
switch(number) {
case 1:
// 1のとき
Log.d("test", "one");
break;
case 2:
case 3:
// 2もしくは3のとき
Log.d("test", "two or three");
break;
case 4:
case 5:
case 6:
// 範囲内か
Log.d("test", "four - six")
break;
default:
Log.d("test", "none")
}
when(number) {
// 1のとき
1 -> Log.d("test", "one")
// 2もしくは3のとき
2,3 -> Log.d("test", "two or three")
// 範囲内か
in 4..6 -> Log.d("test", "four - six")
// 範囲外か(Kotlinのみ)
!in 7..9 -> Log.d("test", "not seven - nine")
// 配列に含まれているか(Kotlinのみ)
in numberList -> Log.d("test", "list invalid")
// どれにも当てはまらない場合
else -> Log.d("test", "none")
}
when文を使って型のチェックをすることもできます。
fun <T> put(key:String, value:T) {
val pref = context!!.getSharedPreferences(NAME, Context.MODE_PRIVATE)
val editor = pref.edit()
when (value) {
is String -> editor.putString(key, value)
is Float -> editor.putFloat(key, value)
is Int -> editor.putInt(key, value)
is Boolean -> editor.putBoolean(key, value)
is Long -> editor.putLong(key, value)
else -> throw IllegalArgumentException("")
}
editor.apply()
}
##リスト
###リスト作成
String[] list = {"晴れ", "曇り", "晴れ時々曇り", "雨", "曇りのち雨", "雪"};
val list = arrayOf("晴れ", "曇り", "晴れ時々曇り", "雨", "曇りのち雨", "雪")
以降、上記のリストがある前提で説明します
###合致するアイテムを取り出す
ArrayList<String> outputList = new ArrayList<String>();
for(String item : list) {
if(item.contains("雨")) {
outputList.add(item);
}
}
val outputList = list.filter{ it.contains("雨") }
抽出結果(outputListの中身)
"雨", "曇りのち雨"
###合致しないアイテムを取り出す
ArrayList<String> outputList = new ArrayList<String>();
for(String item : list) {
if(!item.contains("雨")) {
outputList.add(item);
}
}
val outputList = list.filterNot{ it.contains("雨") }
抽出結果(outputListの中身)
"晴れ", "曇り", "晴れ時々曇り", "雪"
###先頭から指定数取り出す
2つだけ取り出す
ArrayList<String> outputList = new ArrayList<String>();
for(int i=0; i<2; i++) {
outputList.add(list[i]);
}
val outputList = list.take(2)
抽出結果(outputListの中身)
"晴れ", "曇り"
###後ろから指定数取り出す
後ろ3つだけ取り出す
val outputList = list.takeLast(3)
抽出結果(outputListの中身)
"雨", "曇りのち雨", "雪"
###先頭から指定数を削除
先頭から3つは削除
val outputList = list.drop(3)
抽出結果(outputListの中身)
"雨", "曇りのち雨", "雪"
#番外編
Kotlinなら簡単にできちゃう!そんな便利な機能のさわりをご紹介します
##Kotlin Android Extensions
もっとKotlinを便利にするために、入れておくと便利なExtensions
これを使用して、findViewByIdを使用せずに直接リソースのIDを使用することができます
(他にも機能があるのかもしれませんが、現時点でこれしか使えてないです)
###導入方法
Build.gradleのdependenciesに
classpath "org.jetbrains.Kotlin:Kotlin-android-extensions:$Kotlin_version"
を追加し、ActivityファイルのImport文に
import Kotlinx.android.synthetic.main.layoutファイル名.*
を追加する
(layoutファイル名は例えばactivity_main.xmlの場合、activity_mainを記述する)
###setText
指定のIDのTextViewのtextのPropertyに直接アクセスが可能
(直接リソースのIDのtextに代入する)
TextView tv = (TextView)findViewById(R.id.title);
tv.setText("明日の天気");
// id=titleのtextというPropertyに直接値を代入している
title.text = "明日の天気"
###onClick
さらに、ラムダ式と併用することでClickListenerの処理が1行で書けちゃう!
Button fabBtn = (Button)findViewById(R.id.fab);
fabBtn.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View view) {
Log.d("test", "onClick");
}
});
// fabはリソースのID
fab.setOnClickListener({ view -> Log.d("test", "onClick")})
##拡張関数
既存クラスに対して、よく使う処理などを拡張関数として定義しておくことができる
以下のように、startActivityの拡張関数を定義する(試したときはExtension用クラスを作成して下記を記述した)
// Activityの指定は必須とする
// Intentを詰める必要があるときだけbundleを設定する、それ以外はnullをデフォルトでセットする
fun <T: Activity> Activity.startActivity(classRef: KClass<T>, bundle: Bundle? = null) {
val intent = Intent(this, classRef.java).setAction(Intent.ACTION_VIEW)
bundle?.let {
intent.putExtra("args", bundle)
}
startActivity(intent)
}
呼び出す際は以下のように1行記述するだけで上述したstartActivityの処理が実行できます
startActivity(NextActivity::class)
#さいごに
Kotlin楽しいよ!