狠狠撸

狠狠撸Share a Scribd company logo
自然言語処理10010本ノックで比較
する
Java と Kotlin
@blac_k_ey
自己紹介
黒鍵(ぶらっきぃ)
Takumi Kadowaki
Twitter: @blac_k_ey
GitHub: NomadBlacky
おしごと
● SP,FP向けソーシャルゲームの開発
● Javaで実装された内製フレームワークの
保守開発
● Jenkinsおじさんと一緒にいろいろ自動化を頑
張ってる
しゅみ
● Scala?
Kotlin歴
● アプリ開発未経験だけど、Kotlinに触れる経験
欲しさに友人らとハッカソンに応募。
○ →書類審査で予選落選…
碍辞迟濒颈苍、どうやって学ぼう?
Kotlin スタートブック
https://www.amazon.co.jp/Kotlinスタートブック-新しいAndroidプログラミング-長澤-太郎
/dp/4865940391
Kotlin Koans
https://kotlinlang.org/docs/tutorials/koans.html
自然言語処理100本ノック
http://www.cl.ecei.tohoku.ac.jp/nlp100/
テキストや文字列を扱う題材に取り組みながら,プログラミング言語のやや高度なト
ピックを復習します。
文字列
ユニコード
リスト型
辞書型
集合型
イテレータ
スライス
乱数
第1章: 準備運動
VS.
実行環境
● Java
○ 1.8.0_131
● Kotlin
○ 1.1.3
● JUnit
○ 4.12
● ソースコード
○ https://github.com/NomadBlacky/nlp100_java_vs_kotlin
00. 文字列の逆順
文字列"stressed"の文字を逆に
(末尾から先頭に向かって)
並べた文字列を得よ.
→ "desserts"
00. 文字列の逆順 (Java)
@Test
public void q00() throws Exception {
StringBuilder sb = new StringBuilder("stressed");
assertThat(sb.reverse().toString(), is("desserts"));
}
00. 文字列の逆順 (Kotlin)
@Test
@Throws(Exception::class)
fun q00() {
assertThat("stressed".reversed(), `is`("desserts"))
}
00. 文字列の逆順 (Kotlin)
@Test
@Throws(Exception::class)
fun q00() {
assertThat("stressed".reversed(), `is`("desserts"))
}
00. 文字列の逆順 (Kotlin)
// _Strings.kt
@kotlin.internal.InlineOnly
public inline fun String.reversed(): String {
return (this as CharSequence).reversed().toString()
}
public fun CharSequence.reversed(): CharSequence {
return StringBuilder(this).reverse()
}
拡張関数
01. 「パタトクカシーー」
「パタトクカシーー」という文字列の
1,3,5,7文字目を取り出して
連結した文字列を得よ.
→ "パトカー"
01. 「パタトクカシーー」(Java)
@Test
public void q01() throws Exception {
String str = "パタトクカシーー";
String result =
Stream.of(str.charAt(0), str.charAt(2), str.charAt(4), str.charAt(6))
.map(c -> c.toString())
.collect(Collectors.joining());
assertThat(result, is("パトカー"));
}
01. 「パタトクカシーー」 (Kotlin)
@Test
@Throws(Exception::class)
fun q01() {
val str = "パタトクカシーー"
val result =
listOf(str[0], str[2], str[4], str[6])
.joinToString("")
assertThat(result, `is`("パトカー"))
}
01. 「パタトクカシーー」 (Kotlin)
@Test
@Throws(Exception::class)
fun q01() {
val str = "パタトクカシーー"
val result =
listOf(str[0], str[2], str[4], str[6])
.joinToString(separator = "")
assertThat(result, `is`("パトカー"))
} // Collections.kt
public fun <T> listOf(vararg elements: T): List<T> =
if (elements.size > 0) elements.asList()
else emptyList()
トップレベルで定
義
01. 「パタトクカシーー」 (Kotlin)
@Test
@Throws(Exception::class)
fun q01() {
val str = "パタトクカシーー"
val result =
listOf(str[0], str[2], str[4], str[6])
.joinToString(separator = "")
assertThat(result, `is`("パトカー"))
}
// CharSequence.kt
public operator fun get(index: Int): Char
01. 「パタトクカシーー」 (Kotlin)
@Test
@Throws(Exception::class)
fun q01() {
val str = "パタトクカシーー"
val result =
listOf(str.get(0), str.get(2), str.get(4), str.get(6))
.joinToString(separator = "")
assertThat(result, `is`("パトカー"))
}
// CharSequence.kt
public operator fun get(index: Int): Char
演算子オーバーロードの一例
参考
https://kotlinlang.org/docs/reference/operator-overloading.html
演算子 メソッド
a + b a.plus(b)
a - b a.minus(b)
a * b a.times(b)
a / b a.div(b)
01. 「パタトクカシーー」 (Kotlin)
@Test
@Throws(Exception::class)
fun q01() {
val str = "パタトクカシーー"
val result =
listOf(str[0], str[2], str[4], str[6])
.joinToString(separator = "")
assertThat(result, `is`("パトカー"))
}
キーワード引数
01. 「パタトクカシーー」 (Kotlin)
// _Collections.kt
public fun <T> Iterable<T>.joinToString(
separator: CharSequence = ", ",
prefix: CharSequence = "",
postfix: CharSequence = "",
limit: Int = -1,
truncated: CharSequence = "...",
transform: ((T) -> CharSequence)? = null
): String {
return joinTo(StringBuilder(), separator, prefix, postfix, limit,
truncated, transform).toString()
}
01. 「パタトクカシーー」 (Kotlin)
// _Collections.kt
public fun <T> Iterable<T>.joinToString(
separator: CharSequence = ", ",
prefix: CharSequence = "",
postfix: CharSequence = "",
limit: Int = -1,
truncated: CharSequence = "...",
transform: ((T) -> CharSequence)? = null
): String {
return joinTo(StringBuilder(), separator, prefix, postfix, limit,
truncated, transform).toString()
}
デフォルト引数
02. 「パトカー」+「タクシー」=「パタトクカ
シーー」
「パトカー」+「タクシー」の文字を
先頭から交互に連結して
文字列「パタトクカシーー」を得よ.
02. 「パトカー」+「タクシー」=「パタトクカシーー」(
Java)
@Test
public void q02() throws Exception {
String s1 = "パトカー";
String s2 = "タクシー";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < Math.min(s1.length(), s2.length()); i++) {
sb.append(s1.charAt(i)).append(s2.charAt(i));
}
assertThat(sb.toString(), is("パタトクカシーー"));
}
02. 「パトカー」+「タクシー」=「パタトクカシーー」(
Kotlin)
@Test
@Throws(Exception::class)
fun q02() {
val s1 = "パトカー"
val s2 = "タクシー"
val result =
s1.zip(s2, {a,b -> a.toString() + b.toString()})
.joinToString(separator = "")
assertThat(result, `is`("パタトクカシーー"))
}
02. 「パトカー」+「タクシー」=「パタトクカシーー」(
Kotlin)
@Test
@Throws(Exception::class)
fun q02() {
val s1 = "パトカー"
val s2 = "タクシー"
val result =
s1.zip(s2) { a, b ->
a.toString() + b.toString()
}.joinToString(separator = "")
assertThat(result, `is`("パタトクカシーー"))
}
03. 円周率
"Now I need a drink, alcoholic of course, after the
heavy lectures involving quantum mechanics."
という文を単語に分解し,
各単語の(アルファベットの)文字数を先頭か
ら出現順に並べたリストを作成せよ.
→ List(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9)
03. 円周率(Java)
@Test
public void q03() throws Exception {
String str = "Now I need a drink, alcoholic of course, after
the heavy lectures involving quantum mechanics.";
List<Integer> result = Stream.of(str.split("s+"))
.map(s -> s.replaceAll("W", ""))
.map(String::length)
.collect(Collectors.toList());
assertThat(result, contains(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9,
7, 9));
}
03. 円周率(Kotlin)
@Test
@Throws(Exception::class)
fun q03() {
val str = "Now I need a drink, alcoholic of course, after the
heavy lectures involving quantum mechanics."
val result = str.split("""s+""".toRegex())
.map { it.replace("""W+""".toRegex(), "") }
.map(String::length)
assertThat(result, contains(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9,
7, 9))
}
03. 円周率(Kotlin)
@Test
@Throws(Exception::class)
fun q03() {
val str = "Now I need a drink, alcoholic of course, after the
heavy lectures involving quantum mechanics."
val result = str.split("""s+""".toRegex())
.map { it.replace("""W+""".toRegex(), "") }
.map(String::length)
assertThat(result, contains(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9,
7, 9))
}
03. 円周率(Kotlin)
@Test
@Throws(Exception::class)
fun q03() {
val str = "Now I need a drink, alcoholic of course, after the
heavy lectures involving quantum mechanics."
val result = str.split("""s+""".toRegex())
.map { it.replace("""W+""".toRegex(), "") }
.map(String::length)
assertThat(result, contains(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9,
7, 9))
}
03. 円周率(Kotlin)
@Test
@Throws(Exception::class)
fun q03() {
val str = "Now I need a drink, alcoholic of course, after the
heavy lectures involving quantum mechanics."
val result = str.split("""s+""".toRegex())
.map { s -> s.replace("""W+""".toRegex(), "") }
.map(String::length)
assertThat(result, contains(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9,
7, 9))
}
04. 元素記号
"Hi He Lied Because Boron Could Not Oxidize Fluorine. New
Nations Might Also Sign Peace Security Clause. Arthur King
Can."
という文を単語に分解し,
1, 5, 6, 7, 8, 9, 15, 16, 19番目の単語は先頭の1文字,
それ以外の単語は先頭に2文字を取り出し,
取り出した文字列から単語の位置(先頭から何番目の単語か
)への連想配列(辞書型もしくはマップ型)を作成せよ.
→ Map(1 -> "H", 2 -> "He", 3 -> "Li", .... 20 -> "Ca")
04. 元素記号(Java)
@Test
public void q04() throws Exception {
String str = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace
Security Clause. Arthur King Can.";
List<Integer> takeOne = Arrays.asList(0, 4, 5, 6, 7, 8, 14, 15, 18);
String[] words = str.split("s+");
Map<Integer, String> result = new LinkedHashMap<>();
for (int i = 0; i < words.length; i++) {
int take = takeOne.contains(i) ? 1 : 2;
result.put(i + 1, words[i].substring(0, take));
}
Map<Integer, String> expect = new LinkedHashMap<>();
expect.put( 1, "H");
expect.put( 2, "He");
expect.put( 3, "Li");
// ...
expect.put(20, "Ca");
assertThat(result, is(expect));
}
04. 元素記号(Java)
@Test
public void q04() throws Exception {
String str = "Hi He Lied Because Boron Could Not Oxidize Fluorine.
New Nations Might Also Sign Peace Security Clause. Arthur King Can.";
List<Integer> takeOne = Arrays.asList(0, 4, 5, 6, 7, 8, 14, 15, 18);
String[] words = str.split("s+");
Map<Integer, String> result = new LinkedHashMap<>();
for (int i = 0; i < words.length; i++) {
int take = takeOne.contains(i) ? 1 : 2;
result.put(i + 1, words[i].substring(0, take));
}
// ...
}
@Test
@Throws(Exception::class)
fun q04() {
val text = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace
Security Clause. Arthur King Can."
val extractOne = listOf(0, 4, 5, 6, 7, 8, 14, 15, 18)
val result = text.split("""s+""".toRegex())
.mapIndexed { i, s ->
if (extractOne.contains(i)) i + 1 to s.take(1)
else i + 1 to s.take(2)
}.toMap()
val expect: Map<Int, String> = linkedMapOf(
1 to "H" ,
2 to "He",
3 to "Li",
// ...
20 to "Ca"
)
assertThat(result, `is`(expect))
}
04. 元素記号(Kotlin)
@Test
@Throws(Exception::class)
fun q04() {
val text = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New
Nations Might Also Sign Peace Security Clause. Arthur King Can."
val extractOne = listOf(0, 4, 5, 6, 7, 8, 14, 15, 18)
val result = text.split("""s+""".toRegex())
.mapIndexed { i, s ->
if (extractOne.contains(i)) i + 1 to s.take(1)
else i + 1 to s.take(2)
}.toMap()
// ...
}
04. 元素記号(Kotlin)
@Test
@Throws(Exception::class)
fun q04() {
val text = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New
Nations Might Also Sign Peace Security Clause. Arthur King Can."
val extractOne = listOf(0, 4, 5, 6, 7, 8, 14, 15, 18)
val result = text.split("""s+""".toRegex())
.mapIndexed { i, s ->
if (extractOne.contains(i)) i + 1 to s.take(1)
else i + 1 to s.take(2)
}.toMap()
// ...
}
04. 元素記号(Kotlin)
@Test
@Throws(Exception::class)
fun q04() {
val text = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New
Nations Might Also Sign Peace Security Clause. Arthur King Can."
val extractOne = listOf(0, 4, 5, 6, 7, 8, 14, 15, 18)
val result = text.split("""s+""".toRegex())
.mapIndexed { i, s ->
if (extractOne.contains(i)) i + 1 to s.take(1)
else i + 1 to s.take(2)
}.toMap()
// ...
}
04. 元素記号(Kotlin)
// Tuples.kt
public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
@Test
@Throws(Exception::class)
fun q04() {
val text = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New
Nations Might Also Sign Peace Security Clause. Arthur King Can."
val extractOne = listOf(0, 4, 5, 6, 7, 8, 14, 15, 18)
val result = text.split("""s+""".toRegex())
.mapIndexed { i, s ->
if (extractOne.contains(i)) i + 1 to s.take(1)
else i + 1 to s.take(2)
}.toMap()
// ...
}
04. 元素記号(Kotlin)
// Maps.kt
public fun <K, V> Iterable<Pair<K, V>>.toMap(): Map<K, V>
まとめ
105本ノックから見えたKotlinの利点
● 簡潔に、便利に書けるようになる仕組みが沢山ある!
○ 拡張関数による既存クラスの拡張
○ デフォルト引数、キーワード引数
○ 演算子オーバーロード、中置記法
○ 豊富なコレクション操作
○ …などなど
● Kotlinはいいぞ
「もっと良い実装あるぜ!」…というそこのあなた!
PRお待ちしてます!
Ad

Recommended

葉物野菜を見極めたい!by Keras
葉物野菜を見極めたい!by Keras
Yuji Kawakami
?
Esm lt threading_macro
Esm lt threading_macro
工 久納
?
第四回 JavaScriptから始めるプログラミング2016
第四回 JavaScriptから始めるプログラミング2016
kyoto university
?
第3回 JavaScriptから始めるプログラミング2016
第3回 JavaScriptから始めるプログラミング2016
kyoto university
?
Data processing at spotify using scio
Data processing at spotify using scio
Julien Tournay
?
第2回 JavaScriptから始めるプログラミング2016
第2回 JavaScriptから始めるプログラミング2016
kyoto university
?
「辫濒测谤パッケージで君も前処理スタ☆」改め「辫濒测谤パッケージ彻底入门」
「辫濒测谤パッケージで君も前処理スタ☆」改め「辫濒测谤パッケージ彻底入门」
Nagi Teramo
?
Haskell勉強会 14.1?14.3 の説明資料
Haskell勉強会 14.1?14.3 の説明資料
Etsuji Nakai
?
PythonでテキストをJSONにした話(PyCon mini sapporo 2015)
PythonでテキストをJSONにした話(PyCon mini sapporo 2015)
Satoshi Yamada
?
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」
de:code 2017
?
[DI05] Azure Event Hubs と Azure Stream Analytics で、”今を処理”する
[DI05] Azure Event Hubs と Azure Stream Analytics で、”今を処理”する
de:code 2017
?
笔辞蝉迟驳谤别厂蚕尝実行计画入门蔼関西笔辞蝉迟驳谤别厂蚕尝勉强会
笔辞蝉迟驳谤别厂蚕尝実行计画入门蔼関西笔辞蝉迟驳谤别厂蚕尝勉强会
Satoshi Yamada
?
KMC JavaScriptから始めるプログラミング2016 第一回
KMC JavaScriptから始めるプログラミング2016 第一回
kyoto university
?
R intro
R intro
yayamamo @ DBCLS Kashiwanoha
?
GPGPU deいろんな問題解いてみた
GPGPU deいろんな問題解いてみた
Ryo Sakamoto
?
Boost tour 1.60.0 merge
Boost tour 1.60.0 merge
Akira Takahashi
?
Cloud computing competition by Hapyrus
Cloud computing competition by Hapyrus
Koichi Fujikawa
?
Rakuten tech conf
Rakuten tech conf
Koichi Fujikawa
?
Ruby初級者向けレッスン 53回 ─── Array と Hash
Ruby初級者向けレッスン 53回 ─── Array と Hash
higaki
?
準同型暗号の実装とMontgomery, Karatsuba, FFT の性能
準同型暗号の実装とMontgomery, Karatsuba, FFT の性能
MITSUNARI Shigeo
?
20180728 halide-study
20180728 halide-study
Fixstars Corporation
?
尝尝痴惭最适化のこつ
尝尝痴惭最适化のこつ
MITSUNARI Shigeo
?
高速な倍精度指数関数别虫辫の実装
高速な倍精度指数関数别虫辫の実装
MITSUNARI Shigeo
?
グラフニューラルネットワーク入门
グラフニューラルネットワーク入门
ryosuke-kojima
?
2012 ce116 crowbar_snct_shirai
2012 ce116 crowbar_snct_shirai
铃鹿工业高等専门学校
?
笔辞蝉迟驳谤别厂蚕尝:行数推定を読み解く
笔辞蝉迟驳谤别厂蚕尝:行数推定を読み解く
Hiroya Kabata
?
Java で書かれたAndroid アプリに Kotlin を適用させていく
Java で書かれたAndroid アプリに Kotlin を適用させていく
Kenichi Tatsuhama
?
人工無脳バトル 1st STEP 回答と解説
人工無脳バトル 1st STEP 回答と解説
JustSystems Corporation
?

More Related Content

What's hot (20)

Haskell勉強会 14.1?14.3 の説明資料
Haskell勉強会 14.1?14.3 の説明資料
Etsuji Nakai
?
PythonでテキストをJSONにした話(PyCon mini sapporo 2015)
PythonでテキストをJSONにした話(PyCon mini sapporo 2015)
Satoshi Yamada
?
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」
de:code 2017
?
[DI05] Azure Event Hubs と Azure Stream Analytics で、”今を処理”する
[DI05] Azure Event Hubs と Azure Stream Analytics で、”今を処理”する
de:code 2017
?
笔辞蝉迟驳谤别厂蚕尝実行计画入门蔼関西笔辞蝉迟驳谤别厂蚕尝勉强会
笔辞蝉迟驳谤别厂蚕尝実行计画入门蔼関西笔辞蝉迟驳谤别厂蚕尝勉强会
Satoshi Yamada
?
KMC JavaScriptから始めるプログラミング2016 第一回
KMC JavaScriptから始めるプログラミング2016 第一回
kyoto university
?
R intro
R intro
yayamamo @ DBCLS Kashiwanoha
?
GPGPU deいろんな問題解いてみた
GPGPU deいろんな問題解いてみた
Ryo Sakamoto
?
Boost tour 1.60.0 merge
Boost tour 1.60.0 merge
Akira Takahashi
?
Cloud computing competition by Hapyrus
Cloud computing competition by Hapyrus
Koichi Fujikawa
?
Rakuten tech conf
Rakuten tech conf
Koichi Fujikawa
?
Ruby初級者向けレッスン 53回 ─── Array と Hash
Ruby初級者向けレッスン 53回 ─── Array と Hash
higaki
?
準同型暗号の実装とMontgomery, Karatsuba, FFT の性能
準同型暗号の実装とMontgomery, Karatsuba, FFT の性能
MITSUNARI Shigeo
?
20180728 halide-study
20180728 halide-study
Fixstars Corporation
?
尝尝痴惭最适化のこつ
尝尝痴惭最适化のこつ
MITSUNARI Shigeo
?
高速な倍精度指数関数别虫辫の実装
高速な倍精度指数関数别虫辫の実装
MITSUNARI Shigeo
?
グラフニューラルネットワーク入门
グラフニューラルネットワーク入门
ryosuke-kojima
?
2012 ce116 crowbar_snct_shirai
2012 ce116 crowbar_snct_shirai
铃鹿工业高等専门学校
?
笔辞蝉迟驳谤别厂蚕尝:行数推定を読み解く
笔辞蝉迟驳谤别厂蚕尝:行数推定を読み解く
Hiroya Kabata
?
Haskell勉強会 14.1?14.3 の説明資料
Haskell勉強会 14.1?14.3 の説明資料
Etsuji Nakai
?
PythonでテキストをJSONにした話(PyCon mini sapporo 2015)
PythonでテキストをJSONにした話(PyCon mini sapporo 2015)
Satoshi Yamada
?
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」
de:code 2017
?
[DI05] Azure Event Hubs と Azure Stream Analytics で、”今を処理”する
[DI05] Azure Event Hubs と Azure Stream Analytics で、”今を処理”する
de:code 2017
?
笔辞蝉迟驳谤别厂蚕尝実行计画入门蔼関西笔辞蝉迟驳谤别厂蚕尝勉强会
笔辞蝉迟驳谤别厂蚕尝実行计画入门蔼関西笔辞蝉迟驳谤别厂蚕尝勉强会
Satoshi Yamada
?
KMC JavaScriptから始めるプログラミング2016 第一回
KMC JavaScriptから始めるプログラミング2016 第一回
kyoto university
?
GPGPU deいろんな問題解いてみた
GPGPU deいろんな問題解いてみた
Ryo Sakamoto
?
Cloud computing competition by Hapyrus
Cloud computing competition by Hapyrus
Koichi Fujikawa
?
Ruby初級者向けレッスン 53回 ─── Array と Hash
Ruby初級者向けレッスン 53回 ─── Array と Hash
higaki
?
準同型暗号の実装とMontgomery, Karatsuba, FFT の性能
準同型暗号の実装とMontgomery, Karatsuba, FFT の性能
MITSUNARI Shigeo
?
尝尝痴惭最适化のこつ
尝尝痴惭最适化のこつ
MITSUNARI Shigeo
?
高速な倍精度指数関数别虫辫の実装
高速な倍精度指数関数别虫辫の実装
MITSUNARI Shigeo
?
グラフニューラルネットワーク入门
グラフニューラルネットワーク入门
ryosuke-kojima
?
笔辞蝉迟驳谤别厂蚕尝:行数推定を読み解く
笔辞蝉迟驳谤别厂蚕尝:行数推定を読み解く
Hiroya Kabata
?

Similar to 自然言語処理10本ノックで比較する java と kotlin (17)

Java で書かれたAndroid アプリに Kotlin を適用させていく
Java で書かれたAndroid アプリに Kotlin を適用させていく
Kenichi Tatsuhama
?
人工無脳バトル 1st STEP 回答と解説
人工無脳バトル 1st STEP 回答と解説
JustSystems Corporation
?
Kotlin handson
Kotlin handson
Ryuto Yasugi
?
Java で書かれた Android アプリに Kotlin を適用させていく
Java で書かれた Android アプリに Kotlin を適用させていく
Kenichi Tatsuhama
?
Kotlin勉強会 in ehime
Kotlin勉強会 in ehime
Eigoro Yamamura
?
Kotlin
Kotlin
Shumpei Hozumi
?
尝补蝉迟补贵濒耻迟别で碍辞迟濒颈苍をはじめよう
尝补蝉迟补贵濒耻迟别で碍辞迟濒颈苍をはじめよう
Shinsuke Sugaya
?
2018/2/20 Kotlin勉強会
2018/2/20 Kotlin勉強会
虎の穴 開発室
?
碍辞迟濒颈苍の绍介
碍辞迟濒颈苍の绍介
Taro Nagasawa
?
アルゴリズムのお勉強 アルゴリズムとデータ構造 [素数?文字列探索?簡単なソート]
アルゴリズムのお勉強 アルゴリズムとデータ構造 [素数?文字列探索?簡単なソート]
hixi365
?
Kotlin が公式サポートになったので Kotlin の話
Kotlin が公式サポートになったので Kotlin の話
Kenichi Tatsuhama
?
姫路 IT 系勉強会 Vol. 11 L1 グランプリ Haskell
姫路 IT 系勉強会 Vol. 11 L1 グランプリ Haskell
Kazkuki Oakamoto
?
Java x Groovy: improve your java development life
Java x Groovy: improve your java development life
Uehara Junji
?
From Scala/Clojure to Kotlin
From Scala/Clojure to Kotlin
Kent Ohashi
?
すごいHaskell読書会 第六章 発表資料
すごいHaskell読書会 第六章 発表資料
Hiromasa Ohashi
?
Lisp batton - Common LISP
Lisp batton - Common LISP
Masaomi CHIBA
?
Kotest を使って 快適にテストを書こう - KotlinFest 2024
Kotest を使って 快適にテストを書こう - KotlinFest 2024
Hirotaka Kawata
?
Java で書かれたAndroid アプリに Kotlin を適用させていく
Java で書かれたAndroid アプリに Kotlin を適用させていく
Kenichi Tatsuhama
?
人工無脳バトル 1st STEP 回答と解説
人工無脳バトル 1st STEP 回答と解説
JustSystems Corporation
?
Java で書かれた Android アプリに Kotlin を適用させていく
Java で書かれた Android アプリに Kotlin を適用させていく
Kenichi Tatsuhama
?
尝补蝉迟补贵濒耻迟别で碍辞迟濒颈苍をはじめよう
尝补蝉迟补贵濒耻迟别で碍辞迟濒颈苍をはじめよう
Shinsuke Sugaya
?
碍辞迟濒颈苍の绍介
碍辞迟濒颈苍の绍介
Taro Nagasawa
?
アルゴリズムのお勉強 アルゴリズムとデータ構造 [素数?文字列探索?簡単なソート]
アルゴリズムのお勉強 アルゴリズムとデータ構造 [素数?文字列探索?簡単なソート]
hixi365
?
Kotlin が公式サポートになったので Kotlin の話
Kotlin が公式サポートになったので Kotlin の話
Kenichi Tatsuhama
?
姫路 IT 系勉強会 Vol. 11 L1 グランプリ Haskell
姫路 IT 系勉強会 Vol. 11 L1 グランプリ Haskell
Kazkuki Oakamoto
?
Java x Groovy: improve your java development life
Java x Groovy: improve your java development life
Uehara Junji
?
From Scala/Clojure to Kotlin
From Scala/Clojure to Kotlin
Kent Ohashi
?
すごいHaskell読書会 第六章 発表資料
すごいHaskell読書会 第六章 発表資料
Hiromasa Ohashi
?
Lisp batton - Common LISP
Lisp batton - Common LISP
Masaomi CHIBA
?
Kotest を使って 快適にテストを書こう - KotlinFest 2024
Kotest を使って 快適にテストを書こう - KotlinFest 2024
Hirotaka Kawata
?
Ad

自然言語処理10本ノックで比較する java と kotlin

Editor's Notes

  • #2: それでは、「自然言語処理10本ノックで比較するJava と Kotlin」という題でLTを始めさせていただきます、宜しくお願い致します。
  • #3: まず簡単に自己紹介させてください。 黒鍵、と書いてぶらっきぃと読みます。 普段仕事では、Javaを使ってスマートフォン、フィーチャフォン向けのソーシャルゲームを開発しております。 Kotlinを始めたきっかけですが、友人らとアプリ開発のハッカソンに応募したのがきっかけです。 残念ながら、書類審査で落選してしまって、参加には至りませんでした…
  • #4: さて、まず新しい言语を学ぶあたり、どう勉强していけばいいか悩むことがあると思います。
  • #5: まず始めに思い浮かぶのが、書籍を買って勉強するという手です。 Kotlinでは通称「赤べこ本」が有名だと思います。
  • #6: もうひとつは、Kotlin公式で提供されているKotlinKoansというチュートリアルを使う手があります。 オンラインの実行環境が用意されているので、手軽にKotlinを触ることができます。 …ですが、Kotlinを学び始めた当時の自分はこれらの教材の存在を知らずに居ました。
  • #7: そこで友人におすすめされたのが、この自然言語処理100本ノックです。 もともとは東北大学の研究室で使われているプログラミング教材だそうです。 プログラミングに関する基礎的な問題から、言語処理の実用的な問題が計100問用意されています。
  • #8: 今回はその中でもはじめの章「準備運動」をJavaとKotlinで実装しました。 JavaとKotlinでの実装を比べることで、「Kotlinだとこう実装するんだ」とか、「Kotlinのここが便利なんだ」ということを知って頂ければと思います
  • #9: 実行環境はこのようになっています。 ソースコードも公開しておりますので、よろしければそちらもご覧ください。
  • #10: まず、一問目です。 文字列を反転させるいたって単純な問題です。
  • #11: まず、Javaから見ていきます。 StringBuilderにreverseメソッドが提供されているのでそれを利用しました。 至って単純ですね。
  • #12: 対するは碍辞迟濒颈苍です、碍辞迟濒颈苍では一行で実装されています。
  • #13: おや、谤别惫别谤蝉别诲()という见惯れないメソッドがありますね。见ていきましょう
  • #14: どうやら、Kotlinの標準ライブラリのファイルに、Stringドットreversed()という関数が定義されています。 これを拡張関数と言って、指定したクラスにメソッドを追加することができます。 Javaの場合ですと、interfaceを用いてクラスを拡張したりすると思いますが、JavaのStringはfinalクラスですのでinterfaceを用いてStringを拡張することはできません。 このように、Kotlinでは拡張関数を用いることで既存のクラスを拡張することができます。
  • #15: 続いて2問目です。 文字列を部分的に抜き出していく問題ですね。
  • #16: Javaの実装を見ましょう。指定された文字を取り出して、Streamにまとめています。 そしてそのCharacter型のStreamをStringに変換し、それを連結しています。 java8になって、StreamやLambda式が追加されて、便利になりましたね。
  • #17: 対して、Kotlinの実装を見てみましょう。Javaよりもだいぶすっきりしているのがわかります。 詳しく見ていきましょう。
  • #18: まず、いきなりlistOfというメソッドが出てきます。レシーバが無いですがこれどこから来たのでしょうか。 これはKotlinの標準ライブラリがトップレベルでlistOfというリストを定義しているからです。 リストやマップといった構造は、インポートする必要なくすぐ利用することができます。
  • #19: そして、配列のインデックスアクセスのような見た目をしている部分があります。 これは演算子オーバーロードの一種です。 関数にoperatorというキーワードをつけたうえで、特定のメソッド名を与えると、演算子オーバーロードが実装できます。
  • #20: また、演算子オーバーロードのメソッドは普通の呼び出しにも対応しています。 つまり、このように書いても結果は同じになります。
  • #21: これは演算子オーバーロードの一例です。 詳しくは、Kotlinの公式ドキュメントに乗っていますので、こちらを参照してください。
  • #22: つづけて、気になるのがjoinToStringの引数ですね。 これは、キーワード引数といって、引数名を明示的に書くことで、引数の順番に囚われることなく書くことができます。
  • #23: ちなみに、箩辞颈苍罢辞厂迟谤颈苍驳はこのように定义されています。
  • #24: 引数の部分になにやら代入のような記述があります。 これは、デフォルト引数といって、渡されなかった引数に対して、デフォルトの値を当てはめることができます。 Javaでこのようなデフォルト値を実装するばあい、メソッドのオーバーロードを使う必要があります。 同名メソッドが3つ4つ…と定義されるという欠点がありますが、Kotlinではデフォルト引数によってそれを解消しています。
  • #25: 次の問題です。 2つの文字列から1文字ずつ取り出して連結するといった問題です。
  • #26: Javaの実装を見ましょう。 StringBuilderを使って文字を連結という、ごく単純な実装です。
  • #27: 対してKotlinです。Kotlinで拡張されたzipというメソッドを使っています。 ラムダ式の引数a,bに、s1,s2の文字がそれぞれひとつずつ渡され、それを結合しています。 そして、文字列のリストができあがるので、それをjoinToStringで文字列にして返しています。 ところで、丸括弧の中に波括弧が入っているのが少し不格好ですね。これを直します。
  • #28: 波括弧を外に出すことができました。 Kotlinでは、最後の引数が関数である場合、丸括弧の外にラムダ式を書くことができます。
  • #29: 次の問題です。 各単語の文字数を並べると円周率が出来上がるというような問題です。
  • #30: Javaの実装を見ましょう。 空白文字で文字列を分割し、記号を除去します。 そして、単語の文字数を数え上げ、リストにしています。
  • #31: Kotlinの実装を見てみましょう。 Javaとやっていることはほぼ変わりませんが、気になるところがいくつかありますね。
  • #32: まず、3つのダブルクオーテーションで囲まれた文字列リテラルです。 これは生文字列といって、エスケープシーケンスを無視します。 この場合、正規表現に使うバッククオートがそのまま解釈されます。 生文字列はそのほか、複数行の文字列を定義するといったヒアドキュメントのような場合にも使用できます。
  • #33: もうひとつ気になるのが、このitというキーワードですね。 mapにメソッドに関数リテラルを渡しているのですが、この関数リテラルの引数がひとつの場合、暗黙の引数としてitを使うことができます。 この場合のitはsplitされた文字列ということになります。
  • #34: 引数を明示するとこうなります。 この引数に何が入っているのか伝わりにくい、といたような場合に明示的な引数を使うと良いかもしれません。
  • #35: 次の問題です。 問題文の通りに文字列を変換すると、元素記号のマップが出来上がるというような問題です。
  • #36: Javaの実装を見ましょう。 ちょっと長くなってしまったので肝となる部分を抜き出します。
  • #37: 文字をひとつだけ取り除くインデックスの番号を定义しておいて、蹿辞谤文の中の参考演算子で判定します。
  • #38: 対して碍辞迟濒颈苍です、これも少し长くなってしまったので重要な部分を抜き出します
  • #39: まず、mapIndexedというメソッドがあります。 これは、コレクションの要素とインデックスを一緒にイテレートして、値を変換します。
  • #40: ところで、参考演算子がifになっているのが気になりますね。 Kotlinでは参考演算子はサポートされていません。 しかし、Kotlinのifは式です。文ではありません。 つまり、if式は値を返す、ということですね。
  • #41: そして、このtoというメソッドは何でしょうか。 これはPairという2つの値をもつクラスを返します。 infixというキーワードがありますが、これは「メソッド呼び出しのレシーバ、メソッド名、引数を、ドットとかっこではなく、空白で区切る」という記述を可能にします。
  • #42: そして、末尾のtoMapです。 これも拡張関数の一種ですが、Iterable<Pair<K,V>>となっています。 これは、PairのIterableのみに対する拡張となっていて、たとえば、IntのIterableではtoMapメソッドは使えません。 このように拡張関数では、「特定の型引数を持ったクラスに対して拡張する」といったことが可能です。
  • #43: さて、まとめです。5本ノックをご覧頂きましたが、いかがでしたでしょうか。 本当は10本ノックぶんをお見せしたかったのですが、思いの外厚い内容になってしまいました。 この短いコードの中でもKotlinの言語機能が沢山含まれていることが分かったかと思います。 紹介しきれませんでしたが、ここに乗っている機能以外にも、型推論やnullable型などもっと沢山の言語機能がKotlinには含まれています。 冒頭で紹介したリポジトリには10本ノック分の問題が実装されていますので、良かったら見てください。 また、発表中に「もっと良い実装方法があるのになー」と思われた方がいらっしゃるかもしれません。 ぜひともPRを送っていただけると嬉しいです。 以上、「自然言語処理10010本ノックで比較するJava と Kotlin」でした。ご静聴ありがとうございました!