ラベル Kotlin の投稿を表示しています。 すべての投稿を表示
ラベル Kotlin の投稿を表示しています。 すべての投稿を表示

2019年7月15日月曜日

KotlinのHttp ClientのFuelでレスポンスをJacksonでデシリアライズする

FuelでレスポンスのjsonをJacksonでデシリアライズする方法

依存ライブラリ

  implementation("com.github.kittinunf.fuel:fuel:2.1.0")
  implementation("com.github.kittinunf.fuel:fuel-coroutines:2.1.0")
  implementation("com.github.kittinunf.fuel:fuel-jackson:2.1.0")

サンプル

responseObjectにjacksonDeserializerOfを指定する子でJacksonを使ったデシリアライズが行われる。
fun main() {
    "https://jsonplaceholder.typicode.com/todos/1"
            .httpGet()
            .responseObject(jacksonDeserializerOf()) { request, response, result ->
                println("response.statusCode = ${response.statusCode}")
                println("result.component1() = ${result.component1()}")
                println("result.component2() = ${result.component2()}")
            }
            .join()
}

data class Result(
        val userId:Int,
        val id: Int,
        val title: String,
        val completed: Boolean
)

2018年1月27日土曜日

はじめてのjackson-dataformat-xml

jackson-dataformat-xmlのメモ。

使うライブラリ

compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.9.4'

xmlに対応したクラスの定義

@JacksonXmlRootElement(localName = "root")
public class Simple {
    
    private Child child;

    public Child getChild() {
        return child;
    }

    public void setChild(final Child child) {
        this.child = child;
    }

    @Override
    public String toString() {
        return "Simple{" +
                "child=" + child +
                '}';
    }
}

public class Child {
    @JacksonXmlText
    private String text;
    
    @JacksonXmlProperty(isAttribute = true)
    private String attr;

    @Override
    public String toString() {
        return "Child{" +
                "text='" + text + '\'' +
                ", attr='" + attr + '\'' +
                '}';
    }
}

xml→Java

XmlMapperのreadValueを使う
final String xml = "あたい";
final XmlMapper xmlMapper = new XmlMapper();

final Simple simple = xmlMapper.readValue(xml, Simple.class);
System.out.println("simple = " + simple);  // simple = Simple{child=Child{text='あたい', attr='hoge'}}

java→xml

final Simple input = new Simple();
final Child child = new Child();
child.text = "値";
child.attr = "属性";
input.child = child;
System.out.println(xmlMapper.writeValueAsString(input)); // 

kotlin data classを使う

以下を追加する。
compile 'com.fasterxml.jackson.module:jackson-module-kotlin:2.9.4'

KotlinModuleを有効化することでdata classを使えるようになる。
@JacksonXmlRootElement(localName = "r")
data class Hoge(val hoge:String)

val xmlMapper = XmlMapper()
xmlMapper.registerModule(KotlinModule())
println(xmlMapper.writeValueAsString(Hoge("fugafuga")))

2012年3月31日土曜日

KotlinでJunit4系を使って自動テスト

githubみると、kotlinのテストはjunit3系(Testcaseを継承するやつ)でやっているので、
junit4系(アノテーションベースのやつ)での自動テストの実行方法を調べてみた。

テストコード

基本的にJavaでテストコード書く時と違いはない感じですね。
必要なアノテーションをimportしてあげて、メソッドの宣言時に指定してあげるだけです。
違いがあるとしたら、Javaとは異なりアノテーションを示す「@」は不要なとこですね。

あと、静的なメソッド作れないのでBeforeClassAfterClassを使っての、
テストクラスの初期処理と終了処理は実装できない感じです。(俺の知識が足りないだけかも?)

※junit4系でのテストコードの実装方法なので、ターゲットのコードは作ってません。
import org.junit.Before
import org.junit.After
import org.junit.Test

class SampleTest {

  Before fun setUp() {
    println("setUp")
  }

  After fun tearDown() {
    println("tearDown")
  }


  Test fun test1() {
    println("test1")
  }

  Test fun test2() {
    println("test2")
  }
}

実行結果

Javaと同じように、BeforeTestAfterが繰り返されているのがわかりますね。
setUp
test1
tearDown
setUp
test2
tearDown

2012年3月25日日曜日

Project Euler-Problem 2をkotlinで解いてみる

問題:http://se-bikou.blogspot.jp/2012/03/project-euler-problem-2scala.html

フィボナッチ数列をもつIterableなクラスを作って、偶数な値のみにフィルタして合計を求めてみてます。

import ext.sum
import java.util.Collection
import kotlin.util.arrayList

class Fibonacci(num : #(Int, Int), val end : Int) : Iterable {
  private var num : #(Int, Int) = num

  class InnerIterator() : Iterator {
    override val hasNext : Boolean
    get() = (num._1 + num._2) <= end

    override fun next() : Int {
      num = #(num._2, num._1 + num._2)
      return num._2
    }
  }
  override fun iterator() : Iterator {
    return InnerIterator()
  }
}

fun main(args : Array) {
  val sum = Fibonacci(#(0, 1), 4000000).filter({it % 2 == 0}).sum()
  println("sum = ${sum}")
}

2012年3月10日土曜日

Project Euler-Problem 1

Project Eulerなるものの存在を知ったので言語の勉強でつかってみた。

まずは、問題1をやってみた。

問題内容

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.

訳すとこんな感じ。

10未満の自然数のうち、3 もしくは 5 の倍数になっているものは 3, 5, 6, 9 の4つがあり、 これらの合計は 23 になる。
同じようにして、1,000 未満の 3 か 5 の倍数になっている数字の合計を求めよ。

解くために作ったプログラム

Scala

val ret = (0 to 999).filter(n =>{n % 5 == 0 || n % 3 == 0}).sum
println(ret)

Kotlin

Scalaと全く同じになるかなと思ったけど、sum関数がなかったので自作してみてます。
package p1

import java.util.Collection

fun Collection<Int<.sum():Int {
    var ret = 0
    for (item in this) {
        ret += item
    }
    return ret
}
fun main(args : Array<String>) {
    val result = (1..999).filter {it % 3 == 0 || it % 5 == 0}.sum()
    println("result = ${result}")
}

Java

いたって普通のコード。
package p1;

public class P1 {

    public static void main(String[] args) {
        int ret = 0;
        for (int i = 1; i <= 999; i++) {
            if (i % 3 ==0 || i % 5 == 0) {
                ret += i;
            }
        }
        System.out.println("ret = " + ret);
    }
}

javascript

とりあえず結果はあってる。
    var Num = function(s, e) {
        this.filter = function(func) {
            var arr = new Array();
            for (i = s; i <= e; i++) {
                if (func(i)) arr.push(i);
            }
            arr.sum = function() {
                var sum = 0;
                for (i = 0; i < this.length; i++) {
                    sum += this[i];
                }
                return sum;
            };
            return arr;
        }

    };

    var ret = new Num(1, 999).filter(function(val) {
        return val % 3 == 0 || val % 5 == 0;
    }).sum();
    document.write(ret);

groovy

def sum = (1..999).grep({it % 3 == 0 || it % 5 == 0}).sum()
println "sum = $sum"

2012年2月23日木曜日

Kotlinの配列を色々触ってみた

Kotlinの配列を色々試してみた。

繰り返し処理

Scalaなどでもお馴染みのforcachforEachでぐるぐるまわします。
foreachforEachに指定する関数では、要素を「it」で参照できるみたいです。groovyちっくですね。
rubyのように、each_widh_indexみたいなので添字付きでぐるぐるまわすことはできないのかな。

var arr1 = array(1, 2, 3, 4)
arr1.forEach {println(it)}

配列の各要素を連結

おなじみのjoin関数を使って連結出来る。
// カンマで連結
arr.join(",")    // -> 1,2,3,4

// プレフィックス、サフィックスを指定して連結
arr.join(",", "<", ">")    // -> <1,2,3,4>

要素の中身全てが指定した条件を満たすかチェック

all関数を使用する。条件は、all関数の引数として指定してあげる。
// 全ての要素で条件をみたすことができない場合
var arr1 = array(1, 1, 1, 0)
arr1.all {it == 1}    // -> false

// 全ての要素で条件をみたすことが出来る場合
var arr2 = array(1, 1, 1, 1)
arr2.all {it == 1}    // -> true

// 文字列の場合
var str = array("1", "2", "3")
str.all {it <= "3"}    // -> true
str.all {it <= "2"}    // -> false

要素の中のどれか1つが指定した条件を満たすかチェック

any関数を使用するる。条件は、any関数の引数として指定してあげる。
// 要素ないに1つでも条件を満たす値がある場合
var arr1 = array(1, 0, 2, 0)
arr1.any {it == 1}    // -> true

// 要素ないの値が全て条件を満たさない場合
var arr2 = array("1", "2", "3")
arr2.any{it > "3"}    // -> false

要素の中で条件を満たす最初の値を取得する

他の言語でもお馴染みのfind関数を使います。使い方も他の言語と同じですね。
var arr1 = array(1, 0, 2, 0)
// 要素が見つかる場合
arr1.find {it == 0}    // -> 0
arr1.find {it == 2}    // -> 2

// 要素が見つからない場合
arr1.find {it == -1}    // -> null

要素の中で条件に一致したものを新しい配列で取得する

他の言語(Scala)でもお馴染みのfilter関数を使います。使い方も他の言語と同じですね。
var arr1 = array(1, 0, 2, 0)
arr1.filter {it % 2 == 0}    // -> [0, 2, 0]

var arr2 = array("1", "2", "3")
arr2.filter {it.length() == 1}    // -> ["1", "2", "3"]
// 条件に一致する要素が存在しない場合は、空の配列が戻ってきます。
arr2.filter {it.length() != 1}    // -> []

要素の中で条件に一致しないものを新しい配列で習得する

filterの逆ですね。これも他の言語(Scala)でもお馴染みのfilterNot関数を使います。使い方も他の言語と同じですね。
var arr1 = array(1, 0, 2, 0)
arr1.filterNot {it % 2 == 0}    // -> [1]

var arr2 = array("1", "2", "3")
arr2.filterNot {it.length() != 1}    // -> ["1", "2", "3"]
arr2.filterNot {it.length() == 1}    // -> []

各要素の値を変換して新しいCollectionを取得する。

ScalaにもあるflatMapを使ってあげるといけます。
引数の型パラメータと戻りの型パラメータが異なるから、flatMapに型パラメータ指定してあげないと動かなかった。
なんか間違ってるのかな?
ちなみに、arrayListやlinkedList関数は、「std.utilパッケージ」にあるのでimportしてあげないと使えないです。
// 各要素の値を2倍にする。
var arr1 = array(1, 2, 3)
arr1.flatMap<Int, Int> {(n) -> arrayList(n * 2)}    // -> [2, 4, 6]

// 各要素先頭にstr =を加える。
var arr2 = array("1", "2", "3")
arr2.flatMap<String, String>{(s) -> linkedList("str = ${s}")}    // -> [str = 1, str = 2, str = 3]

2012年2月18日土曜日

[Kotlin]安全なnull参照

Kotlinではxnull参照が型システムでコントロールされているので、NullPointerExceptionが発生することがないようです。

実際にサンプルコードで動作を確認してみよ。

例1:nullを許可しない変数

通常の変数宣言は、nullを許容しない変数となります。つまり、nullを代入することが出来ない変数なので、
Javaの実装でよくあるnullだったらどうしよう・・・という分岐が必要なくなります。

例えば、以下のコードはnullを許容しない変数にたいするnull代入となるためコンパイルエラーとなります。
var s:String
s = null

例2:nullを許可する変数

nullを許容する変数は、型の末尾に「?」を付加する必要があります。これにより、nullを変数に代入可能となります。
また、その変数を参照する際には、変数の末尾に「?」を付加して参照しないとコンパイルエラーになります。

このnull許可変数は、参照した際にnullの場合はnullが返却されるようになっています。JavaのようにNullPointerExceptionが発生することはないわけですね。

// 型の末尾に「?」を付加する。
var s:String? = "hoge"
val length = s?.length() // -> 4

// 変数がnullの場合に、参照を行うと戻り値もnullとなります。
s = null
val length2 = s?.length() // -> null

例3:Javaと同じようにNullPointerExceptionを送出したい場合

sure関数を使用すると、nullの場合にNullPointerExceptionが送出されます。
var s:String? = "1"
var length = s.sure().length()      // nullでは無いので、「1」が返却されます。

s = null;
length = s.sure().length()          // nullなのでNullPointerExceptionが送出されます。

実際に送出された例外のStackTraceです。
Exception in thread "main" jet.runtime.Intrinsics$JetNullPointerException
 at nullCheck.namespace.main(hoge.kt:21)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:601)
 at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

例4:Elvis operator(null値の判定で使用する)

nullの場合に、何か別の値を返す場合に使用するらしいです。

例えば、Javaで文字列の長さを返す際にその値がnullの場合は、-1を返すとする場合は、
以下のように三項演算子を使うと思います。
s != null ? s.length() : -1
これを、KotlinのElvis operatorで書くとこんな感じになります。
null意外の場合は、「:」の左側の式の結果(この場合だとlengthの結果)が返却され、nullの場合は「:」の右側の結果が返却されるようです。
b?.length() ?: -1

例5:安全なキャスト

安全にキャストを行うためには、「as?」を使用する必要があります。
「as?」を使用した場合、その型にキャストができない方の場合にはnullが返却されます。
「as」を使用した場合には、TypeCastExceptionが送出されます。

val s = "123";
var i1:Int = s as Int    // これは、TypeCastExceptionが送出されます。
var i2:Int? = s as? Int  // これは、nullが返却されます。


Collection系のオブジェクトから値を代入したときにその値がnullだった場合どんな動きをするんだ?
これは、コンパイル時にチェックするのは不可能だし、どんな動きをするんだろう?と思って調べてみました。

調べたときにつかったコード
val arr:Array<String?> = array(null)   // nullを許容するArray
val s:String = arr[0]                  // nullが代入出来る。
s.length()                             // ぬるぽではなく、TypeCastExceptionが発生

nullが代入されたnull不可変数を参照したら、まさかのTypeCastExceptionが発生しました。
これだったらNullPointerExceptionのが分かりやすいんじゃね?TypeCastExceptionじゃ原因特定出来る気がしない・・・。
この辺はこれから改善されていくかもしれませんが。

ScalaのOptionなるものがあったからこんどScalaのほうもちゃんと勉強してみよう。

2012年2月15日水曜日

[Kotlin]IntellijでKotlinしてみた。

Intellij用のKotlin pluginがでたので、Intellijに導入してみた。

現時点では、Intellij11.1のEAPにしか対応していないので、Intellij11.02ではなく11.1のEAPを導入しておく必要があります。

プロジェクトの作成手順などは、Kotlinのサイト(下のリンク先)の動画を参考にしたら割と簡単に出来ると思います。
http://confluence.jetbrains.net/display/Kotlin/Welcome

では、上の動画を参考にプロジェクトを作成して、Hello Worldを動かしてみましょう。

Kotlinプラグインと、ライブラリのダウンロード

プラグインとライブラリは、github(https://github.com/JetBrains/kotlin/downloads)からダウンロード出来ます。

ダウンロードしたプラグイン(解凍して出来たKotlinディレクトリ)は、Intellijのプラグインディレクトリにコピーします。

macの場合:~/Library/Application\ Support/IntelliJIdea11
Windowsの場合:USER_HOME/.IntelliJIdea11/config/plugins

ライブラリは、任意のディレクトリに解凍しておきます。

Javaプロジェクトの作成

new projectから新しいプロジェクトを作成します。Javaのプロジェクトとして作成してあげたらいいので、特に迷うことはないと思います。

Kotlinのソースコードファイルの生成

ソースコードディレクトリで右クリック→Newとすると、下の画像のようにKotlin Fileが選択出来るようになっています。
これが出てこないときは、プラグインがうまく適用出来ていないので、Settingsからpluginが適用出来ているか確認してみた方がよいでしょう。


Kotlin Fileを選択すると、下の画像のようにファイル名を入力するダイアログが表示されるので、
ファイル名を入力してOKとしてあげましょう。なお、ファイル名には拡張子を入力する必要はありません。


Kotlinライブラリの設定

初めてKotlinのソースファイルを作成すると、Kotlin Runtimeをセットアップしてねとのバーが表示されます。
下の画像のように、ライブラリパスを設定するダイアログに一番最初にダウンロードして解凍したKotlinライブラリのlibディレクトリのパスを設定してあげます。


Hello Worldを出力するコードの作成

http://confluence.jetbrains.net/display/Kotlin/Welcomeを参考にして作成します。

作成したソースはこんな感じですね。
fun main(args : Array<string>) {
    println("Hello World")
}

実行してみよう

右クリックで表示されるメニューからrun namespaceを選択して実行してみよう。
なお、packageを定義しているとrun パッケージ名とメニューに表示されます。

実行した結果、下の画像のようにコンソールにHello Worldが出力されたら実行成功です。