Skip to content

Instantly share code, notes, and snippets.

@koduki
Created July 30, 2017 05:46
Show Gist options
  • Save koduki/fcfc0aede608634b17881918a8f47ace to your computer and use it in GitHub Desktop.
Save koduki/fcfc0aede608634b17881918a8f47ace to your computer and use it in GitHub Desktop.

Javaから使うScala


@koduki


こんなことはありませんか?

  • 仕事でもScalaを使いたい
  • ただ、新言語を採用するのは難易度が高い
  • そんな貴方にお勧めしたいライブラリがあります

scala-library.jar


これはただのOSSのライブラリです

  • Java8にはLambdaはあるけどTupleがない
  • そこでscala-library.jarというライブラリを使う
  • これはApache Commonsと同じく便利ライブラリ
  • mavenを使ってれば下記の通り
<dependency>
    <groupId>org.scala-lang</groupId>
    <artifactId>scala-library</artifactId>
    <version>2.12.2</version>
</dependency>

Tupleを使って見る

  • scala-libraryのTupleを使って見る
Tuple3<String, String, Integer> s1 = 
	new Tuple3<>("アサシン", "ステンノ", 4);
Tuple3<String, String, Integer> s2 = 
	new Tuple3<>("アーチャー", "エウリュアレ", 3);

System.out.println(s1._1)
//# => "アサシン"

System.out.println(s1._2)
//# => "ステンノ"

System.out.println(s1._3)
//# => 4

Tupleをもう少し使って見る

Javaには型推論がないのでその点はツラい

Tuple2<
    Tuple3<String, String, Integer>, 
    Tuple3<String, String, Integer>
    > sistrs = new Tuple2<>(s1, s2);

初期化は頑張ればこんな感じでもう少し簡単に書ける

Tuple2<String, Int> x = $("X", 1);

Tuple2<
   Tuple2<String, Integer>,
   Tuple2<String, Integer>> xs= $($("X", 1), $("Y", 2));

頑張りの舞台裏

泥臭く"$メソッド"のオーバーロードを書く事で実現

public Tuple2<T1, T2> $(T1 _1, T2 _2){ 
   return new Tuple2<>(_1, _2); 
};
.
.
.
public static <T1, T2, T3,.. T21> Tuple21<T1, T2,.. T21> $(T1 _1, T2 _2, T3 _3,.. T21 _21) {
    return new Tuple21<>(_1, _2, _3, .. _21);
}

Collectionを使う

  • Javaは8からStreamAPIでだいぶ使いやすくなった。
  • でも、Scalaと比べるとまだまだ不便
  • JavaからもScalaのコレクションが呼べる。そう、scala-library.jarならね!

Scalaのコレクションを使う

  • Scala 2.12からJavaのLambada(SAM形式)と互換があるので、Lambadaはそのまま使える
  • ただし、普段は暗黙的に利用されているCanBuildFromを渡す必要はある
final Buffer<String> xs = JavaConverters.
	asScalaBuffer(Arrays.asList("a", "b", "c"));
    
System.out.println(
	xs.map((x) -> x + "!!!", arrayBufferBuilder())
);
//# => ArrayBuffer(a!!!, b!!!, c!!!)><

arrayBufferBuilderの舞台裏

型推論が無い & JavaのGenerics型と相性が悪い問題

static CanBuildFrom<Traversable<String>, String, ArrayBuffer<String>> arrayBufferBuilder() {
  CanBuildFrom<ArrayBuffer<?>, String, ArrayBuffer<String>> 
    builder = ArrayBuffer.<String>canBuildFrom();
  CanBuildFrom<Traversable<String>, String, ArrayBuffer<String>> bf = new CanBuildFrom<Traversable<String>, String, ArrayBuffer<String>>() {
    public Builder<String, ArrayBuffer<String>> apply(Traversable<String> from) {
      return builder.apply((ArrayBuffer) from.toBuffer());
    }
    public Builder<String, ArrayBuffer<String>> apply() {
      return builder.apply();
    }
  };
  return bf;
}

まとめ

  • scala-libraryというJavaのユーティリティ系ライブラリを使えば、Javaでももう少し頑張れる

  • ScalaはJavaと相互運用が結構簡単

  • これで上司を騙くらかす説得して貴方も明日からScala三昧!

  • でも、型推論なくてツラいから、みんな素直にScala使ったほうがイイよ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment