はじめに
Android等でKotlinを使用している場合、Javaから『Convert Java File to Kotlin File』で自動変換している人は多い。実際にそれでも動くのだが、そこをもう1歩先に進みKotlinをより使いこなす為のメモ。
第3回目
今回はListとfor文の処理を習得する。
Kotlinバージョン:1.4
Kotlin変換前のサンプルコード
あるオブジェクトからListを生成する処理があるとした例。
Listの作成にはいくつか条件がある。
ItemData.java
// Stringが7個あるオブジェクト
public class ItemData {
private String item1;
private String item2;
private String item3;
private String item4;
private String item5;
private String item6;
private String item7;
public ItemData2(String item1, String item2, String item3, String item4,
String item5, String item6, String item7) {
this.item1 = item1;
this.item2 = item2;
this.item3 = item3;
this.item4 = item4;
this.item5 = item5;
this.item6 = item6;
this.item7 = item7;
}
public String getItem1() {
return item1;
}
public String getItem2() {
return item2;
}
public String getItem3() {
return item3;
}
public String getItem4() {
return item4;
}
public String getItem5() {
return item5;
}
public String getItem6() {
return item6;
}
public String getItem7() {
return item7;
}
}
ListUtil.java
// オブジェクトからListを作成するUtil
public final class ListUtil {
private ListUtil() {
};
private static final int MAX_SIZE = 4;
// オブジェクトのitem1、item2、item3、item4、item5でリストを作る
// 但し、nullだったらListに追加しない
public static List<String> createItemList(final ItemData itemData) {
if (itemData == null) {
return new ArrayList<>();
}
final List<String> list = new ArrayList<>();
for (int i = 0; i <= MAX_SIZE; i++) {
switch (i) {
case 0:
if (itemData.item1 != null) {
list.add(itemData.item1);
}
break;
case 1:
if (itemData.item2 != null) {
list.add(itemData.item2);
}
break;
case 2:
if (itemData.item3 != null) {
list.add(itemData.item3);
}
break;
case 3:
if (itemData.item4 != null) {
list.add(itemData.item4);
}
break;
case 4:
if (itemData.item5 != null) {
list.add(itemData.item5);
}
break;
default:
}
}
return list;
}
}
Kotlin自動変換後のサンプルコード
これを自動変換したらこんな感じに・・・。
とりあえずこれでも動きはする。
ItemData.kt
// Stringが7個あるオブジェクト
class ItemData(
val item1: String,
val item2: String,
val item3: String,
val item4: String,
val item5: String,
val item6: String,
val item7: String
)
ListUtil.kt
// オブジェクトからListを作成するUtil
object ListUtil {
private const val MAX_SIZE = 4
// オブジェクトのitem1、item2、item3、item4、item5でリストを作る
// 但し、nullだったらListに追加しない
fun createItemList(itemData: ItemData?): List<String?> {
if (itemData == null) {
return ArrayList()
}
val list: MutableList<String?> = ArrayList()
for (i in 0 until MAX_SIZE) {
when (i) {
0 -> if (itemData.item1 != null) {
list.add(itemData.item1)
}
1 -> if (itemData.item2 != null) {
list.add(itemData.item2)
}
2 -> if (itemData.item3 != null) {
list.add(itemData.item3)
}
3 -> if (itemData.item4 != null) {
list.add(itemData.item4)
}
4 -> if (itemData.item5 != null) {
list.add(itemData.item5)
}
else -> {
}
}
}
return list
}
}
実装方法を考える
せっかくKotlinで実装しているのでもっとシンプルにしたい。
早速、修正してみる
ItemData.kt
// dataを付けてデータクラスと明示する
data class ItemData(
val item1: String,
val item2: String,
val item3: String,
val item4: String,
val item5: String,
val item6: String,
val item7: String
)
ListUtil.kt
// オブジェクトからListを作成するUtil
object ListUtil {
private const val MAX_SIZE = 4
// オブジェクトのitem1、item2、item3、item4、item5でリストを作る
// 但し、nullだったらListに追加しない
// 戻り値はList<String?>→List<String>が良い
fun createItemList(itemData: ItemData?): List<String> =
itemData?.let {
// nullの場合はここに入らない
mutableListOf<String?>().also { list ->
// for (i in 0..MAX_SIZE) という記述も可能
(0 until MAX_SIZE).forEach { i ->
when (i) {
0 -> it.item1
1 -> it.item2
2 -> it.item3
3 -> it.item4
4 -> it.item5
else -> null
}.also {
list += it
}
}
}.filterNotNull()
// これでListのnullが消えStringがNonNullになる
// add時にnullチェックしなくて済む
} ?: emptyList()
// null時は空Listを返す
// 空ListはArrayList()でなくemptyList()を返す
}
とてもシンプル!