iOS/Swift→Android/Javaの移植ガイドライン

このドキュメントについて
==================================================

本ドキュメントは __Swift で書かれた iOS アプリを Android にポーティングする際の[Qoncept](http://qoncept.co.jp/)社内用ガイドライン__ を公開したものです。社内での利用を主目的としているため役に立つかわかりませんが、何かしら参考になれば幸いです。

__※ 本ドキュメントは Swift から Java への移植を対象としていますが、 Swift から移植する場合、 Java ではなく [Kotlin](http://kirimin.hatenablog.com/entry/2015/03/03/090603) に移植すると幸せになれるかもしれません（特に _Optional type_ とかクロージャとか）。 Java への移植を決定する前に一度 Kotlin を検討してみると良いと思います。__

iOS と Android は異なるプラットフォームであり、それぞれに最適な設計は異なります。特に、 UI/UX についてその傾向は顕著です。しかし、現実には予算やスケジュール、クライアントの意向などの要因によって、 iOS アプリをそのまま Android にポーティングしなければならないことがあります。また、 Model （ MVC とか MVVM とかの Model です）に関してはまったく同じロジックになっている方がメンテナンス上望ましいことも多いです。本ドキュメントはそのような __Swift のコードをそのまま Java にポーティングするケースを主な対象__ としています。

Swiftがリリースされたことにより今後社内で iOS / Swift → Android / Java のポーティングが多くなることが見込まれたため、ひとまず __ドラフト版として作成__ しました。足りない点も多いですが、今後運用しながら改善していければと考えています。

iOS/Swift→Android/Javaの移植ガイドライン
==================================================

Swift を Java にポーティングする際には、メンテナンス性を高めるためにこのドキュメントに基いてポーティング作業を行なって下さい。ただし、本ドキュメントは絶対的なルールではありません。 Java では大きく書き換えた方が良い箇所があれば、 Swift を書いた人に確認の上、作業を進めて下さい。

基本的な作業方針として、 __Swift のコードをロジックや変数名をそのまま Java にポーティングして下さい__。ただし、 Swift のコード中の `viewController` を Java では `activity` とするなど、明らかに読み替えた方が良いものは変更して下さい。識別子を変更する作業は、置換ではなく IDE （ Eclipse 、 Android Studio 等）の Refactor 機能を使って下さい。これは置換で変更するとコードを破壊する可能性があるためです。

__例__

```swift:Swift
let stringOrNil: String? = "ABC"

if let string = stringOrNil {
	for character in string {
		println(character)
	}
} else {
	println("No string")
}
```

```java:Java
final String stringOrNil = "ABC";

if (stringOrNull != null) {
	final String string = stringOrNil; // 意味のないコードに見えるが、Swift側と変数名をそろえるために必要
	for (char character : string.toCharArray()) {
		System.out.println(character);
	}
} else {
	System.out.println("No string");
}
```

バージョン
---------------------------------

- Swift 1.1
- Java 7

Java については、 Java 7 の新機能（特にダイアモンド演算子 `\<\>` ）を積極的に使うようにして下さい。

コメント
---------------------------------

Swift のコード中のコメントはそのまま Java に移植して下さい。

__例__

```swift:Swift
/*
 * 投票する。成人の場合にのみ有効。
 */
func vote() {
	if age >= 20 { // 成年の場合
		...
	}
}
```

```java:Java
/*
 * 投票する。成人の場合にのみ有効。
 */
public void vote() {
	if (age >= 20) { // 成年の場合
		...
	}
}
```

変数
---------------------------------

Swift で `let` で宣言された変数はJavaでは `final` で、 `var` で宣言された変数は `final` なしで宣言して下さい。

__例__

```swift:Swift
let a = 123
var b = "ABC"
```

```java:Java
final int a = 123;
String b = "ABC";
```
switch 文
---------------------------------

Swift の `switch` 文の `case` 節の中は独立したスコープになっているため、次のように同名の変数を定義することができます。

```swift:Swift
switch foo {
case 0:
	let a = 123
	println(a)
case 1:
	let a = 456
	println(a)
default:
	let a = 789
	println(a)
}
```

Java で同じことを実現するために、 `case` 節を `{}` で囲んでスコープを切るようにして下さい。

```java:Java
switch (foo) {
case 0: {
	final int a = 123;
	System.out.println(a);
	break;
}
case 1: {
	final int a = 456;
	System.out.println(a);
	break;
}
default: {
	final int a = 789;
	System.out.println(a);
	break;
}
}
```

for 文
---------------------------------

Swift には Java にはない便利な構文があるため、 Java で実装する際には等価なコードに変換して下さい。

__例1__

```swift:Swift
for i in 0..<100 {
	...
}
```

```java:Java
for (int i = 0; i < 100; i++) {
	...
}
```

__例2__

```swift:Swift
for (index, element) in enumerate([2, 3, 5, 7, 11, 13, 17]) {
	println("The \(index + 1)th prime number is \(element)")
}
```
```java:Java
{ // 変数 index のスコープを限定するためにこの {} が必要
	int index = 0;
	for (int element : Arrays.asList(2, 3, 5, 7, 11, 13, 17)) {
		System.out.println("The " + (index + 1) + "th prime number is " + element);
		index++;
	}
}
```

アクセス修飾子
---------------------------------

アクセス修飾子については、次の表に示すような対応で変換して下さい。

| Swift                                               | Java                             |
|-----------------------------------------------------|----------------------------------|
| public                                              | public                           |
| (internal) （アクセス修飾子を省略）          ※1       | public                           |
| internal                                            | (default) （アクセス修飾子を省略） |
| private                                             | private                          |
| public, (internal) （protectedを意図している場合） ※2 | protected                        |

※1 Swift の `internal` は Java の `(default)` に近いですが、 Swift で書かれたアプリのコードでは `public` を付けずに書くことが一般的なため、このようにポーティングルールを設定しています。

※2 `protected` を意図している場合はSwiftのコード中に次のようにコメントを記します。

```swift
class Animal {
	public /*protected*/ let numberOfLegs: Int
}
```

クラス
---------------------------------

### プレフィックスのないクラス（主に Swift で書かれたもの）

Swift でのクラス名をそのまま Java でのクラス名として下さい。

__例__

```swift:Swift
class Cat { ... }
```

```java:Java
public class Cat { ... }
```

### プレフィックスのあるクラス（主に Objective-C で書かれたもの）

Swift でのクラス名からプレフィックスを取り除いて Java でのクラス名として下さい。既存アプリの改修の場合などに、 Objective-C のコードと Swift のコードが混在している可能性があります。

__例__

```swift:Swift
class XYZCat { ... }
```

```java:Java
public class Cat { ... }
```

### 抽象クラス

Swift に抽象クラスはありませんが、次のように実装されている場合は Java では抽象クラスとして実装して下さい。

```swift:Swift
class Animal {
	private var numberOfLegs: Int

	init(numberOfLegs: Int) {
		self.numberOfLegs = numberOfLegs // dynamicTypeにアクセスする前にプロパティを初期化しなければならないのでここで初期化

		if (self.dynamicType === Animal.self) { // 抽象クラスのインスタンス化を防ぐ
			fatalError("Abstract")
		}
	}

	func walk() {
		fatalError("Abstract")
	}
}
```

```java:Java
public abstract class Animal {
	public Animal() {
	}

	public abstract void walk();
}
```

構造体（ struct ）
---------------------------------

Java には構造体がないため、 Swift で定義された構造体は Java ではイミュータブルなクラスとして実装して下さい（[値型はイミュータブルなクラスと等価なため](http://qiita.com/koher/items/81767a345d5ed53c04b7#2-2)）。

__例__

```swift:Swift
struct Vector {
	var x: Float
	var y: Float
}

var vector = Vector(x: 1, y: 2)
vector.x = 3
```

```java:Java
public class Vector {
	private final float x;
	private final float y;

	public Vector(float x, float y) {
		this.x = x;
		this.y = y;
	}

	public float getX() {
		return x;
	}

	public float getY() {
		return y;
	}
}

// 以下、どこかのメソッドの中
Vector vector = new Vector(1, 2);
vector = new Vector(3, vector.getY());
```

イニシャライザ
---------------------------------

Swift のイニシャライザは、 Java ではコンストラクタとして実装して下さい。

__例__

```swift:Swift
class Animal {
	private let name: String

	init(name: String) {
		self.name = name
	}
}
```

```java:Java
public class Animal {
	private final String name;

	public Animal(String name) {
		this.name = name;
	}
}
```

プロトコル
---------------------------------

Swift のプロトコルは、 Java ではインタフェースとして実装して下さい。命名についてはクラスと同様です。

__例__

```swift:Swift
protocol Animal { ... }
```

```java:Java
public interface Animal { ... }
```

列挙型（ enum ）
---------------------------------

Swift の列挙型は、 Java でも列挙型として実装して下さい。

```swift:Swift
enum Direction {
	case North, East, South, West
	
	var reverse: Direction {
		switch self {
		case .North:
			return .South
		case .East:
			return .West
		case .South:
			return .North
		case .West:
			return .East
		}
	}
}
```

```java:Java
public enum Direction {
	NORTH, EAST, SOUTH, WEST; // Javaのenumの値は大文字のSNAKE_CASEで書くのが一般的

	public Direction getReverse() {
		switch (this) {
		case NORTH:
			return SOUTH;
		case EAST:
			return WEST;
		case SOUTH:
			return NORTH;
		case WEST:
			return EAST;
		default:
			throw new Error("Never reach here.");
		}
	}
}
```

プロパティ
---------------------------------

Swift でのプロパティは、 Java において次のように実装して下さい。

- 通常のプロパティ（ _Stored Property_ ）
	- `public` または `internal` の場合
		- `let` の場合: フィールドおよび _getter_
		- `var` の場合: フィールドおよび _getter_ と _setter_
	- `private` の場合
		- フィールド
- _Computed Property_
	- Read Only （ `get` のみ）の場合: _getter_
	- Read/Write （ `get` と `set` ）の場合: _getter_ と _setter_

Swift でのプロパティへのアクセスは、そのクラスのメソッド内でも _getter_ / _setter_ の呼び出しとして実装して下さい。ただし、 `private` なプロパティへのアクセスはフィールドへのアクセスとして実装して下さい。また、イニシャライザの中でのプロパティへのアクセスについても、フィールドへのアクセスとして実装して下さい。

プロパティの型が `Bool` の場合、対応する Java の _getter_ 名は `getXxx` ではなく `isXxx` として下さい。

__例__

```swift:Swift
class Animal {
	let name: String
	var age: Int
	private let numberOfLegs: Int
	
	init(name: String, age: Int, numberOfLegs: Int) {
		self.name = name
		self.age = age
		self.numberOfLegs = numberOfLegs

		assert(self.age >= 0)
	}

	var detail: String {
		return "\(name) (\(age)) with \(numberOfLegs) legs"
	}
}
```

```java:Java
public class Animal {
	private final String name;
	private int age;
	private final int numberOfLegs;

	public Animal(String name, int age, int numberOfLegs) {
		this.name = name; // イニシャライザの中でのアクセスはフィールドへのアクセスに置き換える。
		this.age = age; // イニシャライザの中でのアクセスはフィールドへのアクセスに置き換える。
		this.numberOfLegs = numberOfLegs;

		assert this.age >= 0; // イニシャライザの中でのアクセスはフィールドへのアクセスに置き換える。
	}

	// nameプロパティはletなので対応するgetterを実装
	public String getName() {
		return name;
	}

	// ageプロパティはvarなので、対応するgetterとsetterを実装
	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	// numberOfLegsプロパティはprivateなのでgetterを実装しない
	
	// detailプロパティはRead Onlyなのでgetterを実装
	public String getDetail() {
		return getName() + " (" + getAge() + ") with " + numberOfLegs; // nameとageはgetterに、numberOfLegsは直接フィールドにアクセスしていることに注意
	}
}
```

メソッド
---------------------------------

Swift のメソッドを Java に移植するときは、基本的にはラベルを無視して下さい。

__例__

```swift:Swift
class Foo {
	func bar(baz: Int, qux: String) {
		...
	}
}

let foo = Foo()
foo.bar(123, qux: "ABC") // 呼び出し時にqaxのラベルが必要
```

```java:Java
public class Foo {
	public void bar(int baz, String qux) { // quxのラベルはメソッド名に現れない
		...
	}
}

// 以下、どこかのメソッドの中
final Foo foo = new Foo();
foo.bar(123, "ABC");
```

Optional, ImplicitlyUnwrappedOptional
---------------------------------

`Optional` （ `String?` や `Optional<String>` など）および `ImplicitlyUnwrappedOptional` （ `String!` や　`ImplicitlyUnwrappedOptional<String>` など）は、 Java では生の型として扱って下さい（ Java 8 からは `Optional` がありますが、 Android では現状で Java 7 までしか使えないので）。

ただし、 Swift で `ImplicitlyUnwrappedOptional` から生の型に代入している箇所（引数に渡す場合も同じ）については暗黙的に _Forced Unwrapping_ が発生するので、挙動を合わせる（ `null` だったら例外をスローする）ために後述の [Swift2Java](https://github.com/qoncept/Swift2Java) の `x` メソッドを使って下さい。

__例1__

```swift:Swift
let nameOrNil: String? = ...

if let name = nameOrNil {
	...
}
```

```java:Java
final String nameOrNil = ...;

if (nameOrNil != null) {
	final String name = nameOrNil; // 意味のないコードに見えるが、Swift側と変数名をそろえるために必要
	
	...
}
```

__例2:　`ImplicitlyUnwrappedOptional` の代入で暗黙的に _Forced Unwrapping_ が発生する例__

```swift:Swift
let nameOrNil: String! = ...
let name: String = nameOrNil
```

```java:Java
final String nameOrNil = ...;
final String name = x(nameOrNil); // ここで暗黙的にForced Unwrappingが発生
```

__例3: プリミティブ型に対応する型の `Optional`__

Java でプリミティブ型に移植すべき型（ Swift の `Int` や `Float` など）の `Optional` については、プリミティブ型として移植すると `null` を扱えないので、ラッパークラスの型として移植して下さい。

```swift:Swift
let fooOrNil: Int? = nil
if let foo = fooOrNil {
	...
}
```

```java:Java
Integer fooOrNil = null;
if (fooOrNil != null) {
	Integer foo = fooOrNil;
	...
}
```

__例4: _Optional Binding_ で関数やメソッドの戻り値を使っているとき__

```swift:Swift
if let foo = getFooOrNil() {
	...
}
```

```java:Java
{ // 変数 foo のスコープを限定するためにこの {} が必要
	final Foo foo = getFooOrNil();
	if (foo != null) {
		...
	}
}
```

タプル
---------------------------------

Swift にはタプルがありますが Java にはタプルがありません。そのため、移植の際には[こちらのライブラリ](https://github.com/qoncept/Tuple-Java)を使って下さい。

上記ライブラリには `Tuple0`, `Tuple1<T1>`, `Tuple2<T1, T2>`, `Tuple3<T1, T2, T3>`, ... といったクラスが用意されています。リポジトリの gen ディレクトリには `Tuple31` までが入っていますが、 src ディレクトリの `TupleGenerator` を使って任意の要素数までのタプルクラスを生成することができます。

__例1__

```swift:Swift
let t: (Int, Double, String) = (123, 456.0, "789")
let integer = t.0
let string = t.2
```

```java:Java
final Tuple3<Integer, Double, String> t = new Tuple3<>(123, 456.0, "789");
final Integer integer = t.get0();
final String string = t.get2();
```

しかし、 `Tuple` はイミュータブルであり、 _Covariant_ であることを意図して設計されています。上記の Java のコードはワイルドカードを使って次のように書かれている方がより望ましいです。

```java:Java
final Tuple3<? extends Integer, ? extends Double, ? extends String> t = new Tuple3<>(123, 456.0, "789");
final Integer integer = t.get0();
final String string = t.get2();
```

ただし、 Swift のタプルは現時点では _Invariant_ なようなので、 Swift からの移植という点では問題はないです。

※ _Variance_ についてよくわからない場合は[こちら](http://qiita.com/koher/items/7dea63e0ce52ebda9873)を読んで下さい。


Function Type
---------------------------------

Swift は第一級関数をサポートしているので関数を変数や引数に渡したり戻り値として受け取ったりすることができます。そのため、関数の型を表す構文（ `(Int) -> String` など）があります。

一方で Java にはそのような構文は存在しません。そのため、一つだけメソッドを持ったインタフェースを代わりに使います。 Java 8 にはそのための便利なインタフェース `Function<T, R>` が用意されており、例えば引数で `Integer` を受けて `String` を返す関数は `Function<Integer, String>` と書けます。

Java 7 にはそのようなインタフェースはないので、[こちらのライブラリ](https://github.com/qoncept/Functional-Java)を利用して下さい。 `Function` など、 Java 8 において関数の型を表すインタフェースを一式再現してあります。

`Function` の他には、引数の型がない関数を表す `Supplier<T>` （引数なく戻り値の型が `T` ）、戻り値ない（ `void` な）関数を表す `Consumer<T>` （引数の型が `T` で戻り値が `void` ）があります。戻り値が `boolean` な関数は多いので、それに特化した `Predicate<T>` （引数の型が `T` で戻り値の型が `boolean` ）もあります。 また、引数が二つの場合に対応した、 `BiFunction<T, U, R>`, `BiConsumer<T, U>` および `BiPredicate<T, U>` もあります。

しかし、それだけでは引数が三つ以上ある場合に対応することができません。 Java 8 にもそのようなインタフェースは用意されていません。そこで、引数が三つ以上の場合には前述のタプルを使います。

__例1__

```swift:Swift
let a: (Int) -> String = ...
let b: () -> String = ...
let c: (Int) -> Void = ...
let d: (Int) -> Bool = ...
let e: (Int, Double) -> String = ...
let f: (Int, Double, Char) -> String = ...
```

```java:Java
final Function<Integer, String> a = ...;
final Supplier<String> b = ...;
final Consumer<Integer> c = ...;
final Predicate<Integer> d = ...;
final BiFunction<Integer, Double, String> e = ...;
final Function<Tuple3<Integer, Double, Character>, String> f = ...;
```

ただし、タプルの項で説明したのと同様に、 `Supplier` は _Covariant_, `Consumer` と `Predicate` は _Contravariant_, `Function` は `T` については　_Contravariant_ で `R` については _Covariant_ です。そのため、上記の Java のコードは次のように書かれている方がより望ましいです。

```java:Java
final Function<? super Integer, ? extends String> a = ...;
final Supplier<? extends String> b = ...;
final Consumer<? super Integer> c = ...;
final Predicate<? super Integer> d = ...;
final BiFunction<? super Integer, ? super Double, ? extends String> e = ...;
final Function<? super Tuple3<? extends Integer, ? extends Double, ? extends Character>, ? extends String> f = ...;
```

__例2__

ワイルドカードを使っておらず困る例に次のようなものが考えられます（ `Cat` は `Animal` を継承したクラスとします）。

```swift:Swift
let getCat: () -> Cat = ...
let getAnimal: () -> Animal = getCat // 問題なし
```

```java:Java
final Supplier<Cat> getCat = ...;
final Supplier<Animal> getAnimal = getCat; // コンパイルエラー
```

次のようにワイルドカードを使えば問題ありません。

```java:Java
final Supplier<? extends Cat> getCat = ...;
final Supplier<? extends Animal> getAnimal = getCat; // 問題なし
```

※ _Variance_ についてよくわからない場合は[こちら](http://qiita.com/koher/items/7dea63e0ce52ebda9873)を読んで下さい。

クロージャ
---------------------------------

Java にはクロージャがないので、 Swift のクロージャは、前述の `Function` などのインタフェースを実装した匿名内部クラスのインスタンスとして移植して下さい。

__例1__

```swift:Swift
let stringToInt: (String) -> Int = { $0.toInt()! }
```

```java:Java
final Function<String, Integer> stringToInt = new Function<String, Integer>() {
	@Override
	public Integer apply(String object) {
		return Integer.parseInt(object);
	}
}
```

こちらも、タプルの項や _Function Type_ の項で述べたのと同じように _Variance_ を考慮して次のように書く方が望ましいです。

```java:Java
final Function<? super String, ? extends Integer> stringToInt = new Function<String, Integer>() {
	@Override
	public Integer apply(String object) {
		return Integer.parseInt(object);
	}
}
```

※ _Variance_ についてよくわからない場合は[こちら](http://qiita.com/koher/items/7dea63e0ce52ebda9873)を読んで下さい。

__例2__

次のようにクロージャが状態を持つ場合、Java の匿名内部クラスはそれを宣言するメソッド内の `final` でないローカル変数にアクセスすることができないので、次のように要素数 1 の配列を作って Swift の挙動を再現して下さい。

```swift:Swift
var count: Int = 0
let getCount: () -> Int = { count++ }

println(getCount()) // 0
println(getCount()) // 1
println(getCount()) // 2
```

```java:Java
final int[] count = {0};
Supplier<? extends Integer> getCount = new Supplier<Integer>() {
	@Override
	public Integer get() {
		return count[0]++;
	}
};

System.out.println(getCount.get()); // 0
System.out.println(getCount.get()); // 1
System.out.println(getCount.get()); // 2
```

Void
---------------------------------

Swift では `Void` は `()` （空のタプルの型）のシンタックスシュガーです。稀なケースですが、 Swift で `Void` 型の値を扱っている箇所を移植しなければならない場合には Java の `Void` クラスを使うのではなく空のタプルを表す `Tuple0` クラスを使うようにして下さい。 Java の `Void` クラスはインスタンスを生成できないため `null` で代用すると、次のようなコードで想定外の誤動作を起こす可能性があります（次のコードは意味のない処理に見えますが、実際にジェネリックなプログラムを移植した際に意味のあるコードで Swift の `Void` を Java の `Void` に移植して問題になったことがあります）。

```swift:Swift
func foo<T>(tOrNil: T?) {
	if let t = tOrNil {
		println("X")
	} else {
		println("Y")
	}
}

let a: Int = 123
foo(a) // X

let b: Int? = nil
foo(b) // Y

let c: Void = ()
foo(c) // X
```

```java:Java
public <T> void foo(T tOrNil) {
	if (tOrNil != null) {
		final T t = tOrNil;
		System.out.println("X");
	} else {
		System.out.println("Y");
	}
}

// 以下、どこかのメソッドの中
final Integer a = 123;
foo(123); // X

final Integer b = null;
foo(b); // Y

final Tuple0 c = new Tuple0();
foo(c); // X

// ダメな例
final Void d = null;
foo(d); // Y （cと同じことがやりたいけど結果が変わってしまう）
```

as, as?, is, ?, !, ??
---------------------------------

Swift のコード中での `as`, `as?`, `is`, `?` (_Optional Chaining_), `!` (_Forced Unwrapping_), `??` はそれぞれ、 [Swift2Java](https://github.com/qoncept/Swift2Java) の `Swift` クラスの `static` メソッドである `as`, `asq`, `is`, `q`, `x`, `qq` に変換して下さい。

`asq` や `x` のメソッド名は、 ? = <strong>q</strong>uestion, ! = e<strong>x</strong>clamation によります。 Swift での `?` を `q` に、 `!` を `x` に置き換えると考えるとわかりやすいです。

また、ここでの `!` は `ImplicitlyUnwrappedOptional` ではなく _Forced Unwrapping_ であることに注意して下さい。 `ImplicitlyUnwrappedOptional` は前述のように生の型として移植して下さい。

### as

__例1__

```swift:Swift
let animal: Animal = Cat()
let cat = animal as Cat
```

```java:Java
Animal animal = new Cat();
Cat cat = as(animal, Cat.class); // the created Cat object
```

__例2: 通常のキャストと違い `null` をキャストしようとしてクラッシュする例__

```swift:Swift
let animal: Animal? = nil
let cat = animal as Cat
```

```java:Java
Animal animal = null;
Cat cat = as(animal, Cat.class); // ClassCastException
```

### as?

__例1__

```swift:Swift
let animal: Animal? = Cat()
let cat = animal as? Cat

```

```java:Java
Animal animal = new Cat();
Cat cat = asq(animal, Cat.class); // the created Cat object
```

__例2__

```swift:Swift
let animal: Animal? = nil
let cat = animal as? Cat
```

```java:Java
Animal animal = null;
Cat cat = asq(animal, Cat.class); // null
```

### is

__例1__

```swift:Swift
let animal: Animal? = Cat()
let result = animal is Cat
```

```java:Java
Animal animal = new Cat();
boolean result = is(animal, Cat.class); // true
```

__例2__

```swift:Swift
let animal: Animal? = nil
let result = animal is Cat
```

```java:Java
Animal animal = new Cat();
boolean result = is(animal, Cat.class); // false
```

### ? (Optional Chaining)

__例1__

```swift:Swift
let s: String? = "abc"
let l = s?.length
```

```java:Java
String s = "abc";
Integer l = q(s, new Function<String, Integer>() {
    @Override
    public Integer apply(String object) {
        return object.length();
    }
}); // 3
```

__例2__

```swift:Swift
let s: String? = nil
let l = s?.utf16Count
```

```java:Java
String s = null;
Integer l = q(s, new Function<String, Integer>() {
    @Override
    public Integer apply(String object) {
        return object.length();
    }
}); // null
```

### ! (Forced Unwrapping)

__例1__

```swift:Swift
let s: String? = "abc"
let t = s!
```

```java:Java
String s = "abc";
String t = x(s);
```

__例2__

```swift:Swift
let s: String? = nil
let t = s!
```

```java:Java
String s = null;
String t = x(s); // NullPointerException
```

### ??

__例1__

```swift:Swift
let s = "abc"
let r = s ?? "xyz"

```

```java:Java
String s = "abc";
String r = qq(s, "xyz"); // "abc"
```

__例2__

```swift:Swift
let s: String? = nil
let r = s ?? "xyz"
```

```java:Java
String s = null;
String r = qq(s, "xyz"); // "xyz"
```

map, filter, reduce
---------------------------------

`map`, `filter`, `reduce` などの高階関数も Java 7 にはないので（ Java 8 には `Stream` があります）、 `as` などと同じく[Swift2Java](https://github.com/qoncept/Swift2Java) の `static` メソッドを使って移植して下さい。

なお下記の例で使っている `Function` などのインタフェースは _Function Type_ の項で説明したものです。

### map

__例: String の Array を Int の Array に変換__

```swift:Swift
let result = ["123", "456", "789"].map { $0.toInt()! }
```

```java:Java
List<Integer> result = map(Arrays.asList("123", "456", "789"),
    new Function<String, Integer>() {
        @Override
        public Integer apply(String t) {
            return Integer.parseInt(t);
        }
    });
```

### filter

__例: 奇数の要素だけを残す__

```swift:Swift
let result = [123, 456, 789].filter { $0 % 2 == 1 }
```

```java:Java
List<Integer> result = filter(Arrays.asList(123, 456, 789),
    new Predicate<Integer>() {
        @Override
        public boolean test(Integer t) {
            return t % 2 == 1;
        }
    });
```

### reduce

__例: 要素の合計を計算__

```swift:Swift
let result = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].reduce(0) { $0 + $1 }
```

```java:Java
Integer result = reduce(
    Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), 0,
    new BiFunction<Integer, Integer, Integer>() {
        @Override
        public Integer apply(Integer t, Integer u) {
            return t + u;
        }
    });
```

Extension
---------------------------------

Swift には _Extension_ という構文があります。これは、既存の型に対して後からメソッドやプロパティ等を追加するものです。このような構文は Java にはないため、次のように移植して下さい。

### ライブラリで宣言された型に対して _Extension_ を実装する場合

Java で元の型に対してメソッドを付け足すことはできないので、 その型を第一引数としてとる `static` メソッドとして実装して下さい。クラス名は、 Swift でのファイル名と同名にして下さい。

__例__

```swift:Swift
// ファイル名が ArrayExtension.swift の場合
extension Array {
	func flatMap<U>(transform: (T) -> [U]) -> [U] {
		return map(transform).reduce([]) { $0 + $1 }
	}
}
```

```java:Java
import static jp.co.qoncept.swift.Swift.map;
import static jp.co.qoncept.swift.Swift.reduce;

...

public class ArrayExtension { // クラス名は Swift でのファイル名と同名とする
	private ArrayExtension() { // インスタンス生成を防ぐためにコンストラクタを private にする
	}

	public static <T, U> List<U> flatMap(List<T> thiz,
			Function<T, List<U>> transform) { // 第一引数の名前は thiz とする
		return reduce(map(thiz, transform), new ArrayList<U>(),
				new BiFunction<List<U>, List<U>, List<U>>() {
					@Override
					public List<U> apply(List<U> t, List<U> u) {
						t.addAll(u);
						return t;
					}
				});
	}
}
```

これを利用する際には `import static` するようにして下さい。

__例__

```swift:Swift
[[2], [3, 5], [7, 11, 13]].flatMap { $0 } // [2, 3, 5, 7, 11, 13]
```

```java:Java
import static foo.bar.ArrayExtension.flatMap;
import static java.util.Arrays.asList;

...

flatMap(asList(asList(2), asList(3, 5), asList(7, 11, 13)),
	new Function<List<Integer>, List<Integer>>() {
		@Override
		public List<Integer> apply(List<Integer> t) {
			return t;
		}
	}); // [2, 3, 5, 7, 11, 13]
```

### アプリ内で宣言された独自の型に対して _Extension_ を実装する場合

Swift では一つの型をあえて元の宣言と _Extension_ に分けて実装することができます。そのアプリ内で宣言された独自の型に対してわざわざ _Extension_ で分離して実装されている場合には、 Java ではすべて一つのクラス／インタフェース宣言の中に書くようにして下さい。

__例__

```swift:Swift
class Foo {
	func bar() {
	}
}

extension Foo {
	func baz() {
	}
}
```

```java:Java
public class Foo {
	public void bar() {
	}
	
	public void baz() {
	}
}
```

fatalError, assert
---------------------------------

`fatalError` は `Error` の `throw` に、 `assert` は `assert` に、次のように移植して下さい。

### fatalError

```swift:Swift
fatalError("Some Error Message.");
```

```java:Java
throw new Error("Some Error Message.");
```

### assert

```swift:Swift
assert(foo > 0, "Some Message.")
```

```java:Java
assert foo > 0 : "Some Message.";
```

標準ライブラリ
---------------------------------

下記のように、それぞれの言語の標準ライブラリで対応するものが用意されている場合には対応するものを利用して下さい。

### クラス、型

| Swift                                    | Objective-C          | Java                                                   |
|------------------------------------------|----------------------|--------------------------------------------------------|
| Int                                      | NSInteger            | int, Integer ※1                                        |
| UInt                                     | NSUInteger           | int, Integer ※1                                        |
| Float                                    | float                | float, Float ※1                                        |
| Double                                   | double               | double, Double ※1                                      |
| CGFloat                                  | CGFloat              | double, Double ※1                                      |
| NSTimeInterval                           | NSTimeInterval       | double, Double ※1                                      |
| String                                   | NSString             | String                                                 |
| let Array\<T\>                           | NSArray              | List\<T\> / Collections#unmodifiableList(List\<T\>) ※2 |
| var Array\<T\> ※3                        | NSMutableArray       | List\<T\> / ArrayList\<T\> ※2                          |
| let Dictionary\<T\>                      | NSDictionary         | Map\<T\> / Collections#unmodifiableMap(Map\<T\>) ※2    |
| var Dictionary\<T\> ※3                   | NSMutableDictionary  | Map\<T\> / HashMap\<T\> ※2                             |
| T?, Optional\<T\>                        | T                    | T                                                      |
| String (File path)                       | NSString (File path) | File                                                   |
| NSURL                                    | NSURL                | URL                                                    |
| UIViewController                         | UIViewController     | Activity                                               |
| UIViewController (Child view controller) | UIViewController (Child view controller) | Fragment                           |
| UIView                                   | UIView               | View                                                   |
| UITableView                              | UITableView          | ListView                                               |
| UIButton                                 | UIButton             | Button, ImageButton                                    |
| UIAlertView                              | UIAlertView          | AlertDialog ※4                                         |
| UIActionSheet                            | UIActionSheet        | AlertDialog ※5                                         |
| CGPoint                                  | CGPoint              | Vector2 ※6                                             |
| CGSize                                   | CGSize               | Vector2 ※6                                             |
| CGRect                                   | CGRect               | Rect2 ※6                                               |

※1 ラッパークラスは必要な場合（ジェネリクスの型パラメータなど）のみ使用して下さい。
※2 A / B の場合、変数の型としては A を、オブジェクトとしては B のインスタンスを使用して下さい。
※3 ただし、 `Array` や `Dictionary` 自体の変更ではなく、変数を再代入可とするために `var` を用いている場合は、オブジェクト生成のためには `Collections#unmodifiableList(...)/unmodifiableMap(...)` を使用して下さい。
※4 `AlertDialog.Builder#setPositiveButton(...)/setNegativeButton(...)` 等を使用して下さい。
※5 `AlertDialog.Builder#setItems()` を使用して下さい。
※6 Qoncept SDK のクラスです。

__例1__

```swift:Swift
let a = [1, 2, 3]
```

```java:Java
final List<Integer> a = Collections.unmodifiableList(Arrays.asList(1, 2, 3));
```

__例2__

```swift:Swift
var list = [1, 2, 3]
if flag {
	list = []
}
```

```java:Java
// Swiftでvarで宣言されているが、ミュータブルであることを意図しているのではなく、変数への再代入を可能にすることを意図しているので、JavaではunmodifiableListとする。
List<Integer> list = Collections.unmodifiableList(Arrays.asList(1, 2, 3));
if (flag) {
	list = Collections.emptyList();
}
```

__例3__

```swift:Swift
class SomeClass : UIAlertViewDelegate {
	func someMethod() {
		UIAlertView(title: "Title", message: "Message", delegate: self, cancelButtonTitle: "Cancel", otherButtonTitles: "OK")
	}

	func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int) {
		switch buttonIndex {
		case 0:
			println("Cancel was clicked.")
		default:
			println("OK was clicked")
		}
	}
}
```

```java:Java
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Title");
builder.setMessage("Message");
builder.setCancelable(false);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
	@Override
	public void onClick(DialogInterface dialog, int which) {
		System.out.println("OK was clicked.");
	}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
	@Override
	public void onClick(DialogInterface dialog, int which) {
		System.out.println("Cancel was clicked.");
	}
});
builder.create().show();
```

### プロパティ、メソッド、演算子

| Swift                         | Java                      |
|-------------------------------|---------------------------|
| Printable#description         | toString()                |
| Equatable#==                  | equals(...)               |
| Hashable#hashValue            | hashCode()                |
| Comparable#<, <=, >, >=       | Comparable#compareTo(...) |
| UIView#animateWithDuration... | Animationのサブクラス       |

__例1__

```swift:Swift
class Foo : Hashable, Printable {
	let name: String
	
	init(name: String) {
		self.name = name
	}
	
	var hashValue: Int {
		return name.hashValue
	}
	
	var description: String {
		return "Foo(\(name))"
	}
}

func ==(lhs: Foo, rhs: Foo) -> Bool {
	return lhs.name == rhs.name
}
```

```java:Java
public class Foo {
	private final String name;
	
	public Foo(String name) {
		this.name = name;
	}
	
	public String getName() {
		return name;
	}
	
	public int hashCode() {
		return name.hashCode();
	}
	
	public boolean equals(Object object) {
		if (!( object instanceof Foo)) {
			return false;
		}
		
		Foo another = (Foo)object;
		return name.equals(another.name);
	}
	
	public String toString() {
		return "Foo(" + name + ")";
	}
}
```

__例2__

```swift:Swift
someView.alpha = 0.0
UIView.animateWithDuration(0.5, animations: { () -> Void in
	self.someView.alpha = 1.0
}) { (finished) -> Void in
	// Do something
}
```

```java:Java
Animation animation = new AlphaAnimation(0.0f, 1.0f);
animation.setDuration(500L);
animation.setAnimationListener(new Animation.AnimationListener() {
		@Override
		public void onAnimationStart(
				Animation animation) {
		}

		@Override
		public void onAnimationRepeat(
				Animation animation) {
		}

		@Override
		public void onAnimationEnd(
				Animation animation) {
			// Do something
		}
	});

someView.startAnimation(animation);
```

### Array、Dictionary

[Swiftの `Array` と `Dictionary` は値型](http://qiita.com/koher/items/47f444200d4e02b6414e)なので、そのまま Java の `List` や `Map` に移植すると挙動が変わってしまう場合があります。

__例1__

```swift:Swift
var a = [1, 2, 3]
var b = a
b.append(4) // a = [1, 2, 3], b = [1, 2, 3, 4]
```

```java:Java（良くない例）
List<Integer> a = new ArrayList<>(Arrays.asList(1, 2, 3));
List<Integer> b = a;
b.add(4); // a = [1, 2, 3, 4], b = [1, 2, 3, 4]
```

このような場合は、 Swift のコードでの Array の代入に対応する箇所で、新しい `List` のオブジェクトを生成するようにします。

すべての代入でコピーが必要なのではなく、必要に応じてコピーするようにして下さい

```java:Java（良い例）
List<Integer> a = new ArrayList<>(Arrays.asList(1, 2, 3));
List<Integer> b = new ArrayList<>(a);
b.add(4); // a = [1, 2, 3], b = [1, 2, 3, 4]
```

__例2__

Swift でイニシャライザやメソッドに `Array` 等を渡しオブジェクト内に保持するようなケースでは、Javaでは `List` のコピーを保持するようにして下さい。 _getter_ 等で `return` する際には、 `return` した `List` を書き換えられてしまわないように、 `Collections#unmodifiableList(...)` でラップして `return` するようにして下さい。

```swift:Swift
class Foo {
	var list: [Int]

	init(list: [Int]) {
		self.list = list
	}
}
```

```java:Java
public class Foo {
	private List<Integer> list;

	public Foo(List<Integer> list) {
		this.list = new ArrayList<>(list);
	}

	public List<Integer> getList() {
		return Collections.unmodifiableList(list);
	}

	public void setList(List<Integer> list) {
		this.list = new ArrayList<>(list);
	}
}
```

上記コードの Java の `Foo#getList()` の実装では、 `getList()` した後に `Foo#list` が書き換えられると、 `getList()` で得たオブジェクトが変更されてしまいます。そのため、厳密には Swift のコードと等価になりません。しかし、そのような挙動が問題になるケースはまれですし、コピーのコストがパフォーマンス上の問題を引き起こす可能性の方が大きいと判断し、 `new ArrayList\<\>(list)` ではなく `Collections.unmodifiableList(list)` をポーティングルールとして採用しました。

### Delegate

Swift では _View Controller_ 等を _Delegate_ として実装することが多いですが、特に必要がない限り、 Java では匿名内部クラスとして実装して下さい。

```swift:Swift
class SomeViewController : UIViewController, FooDelegate {
	func someMethod() {
		let foo = Foo()
		foo.delegate = self
		foo.playBar(Bar())
	}

	func foo(foo: Foo, didPlayBar: Bar) {
		...
	}
}
```

```java:Java
public class SomeActivity extends Activity {
	public void someMethod() {
		final Foo foo = new Foo();
		foo.setDelegate(new Foo.Delegate() {
			public void didPlayBar(bar: Bar) {
				...
			}
		});
		foo.doBar(new Bar());
	}
}
```

### OpenGL ES

OpenGL ES の関数は、 Java では `import static` を使い、関数のように書いて下さい。

```swift:Swift
glEnableClientState(GLenum(GL_VERTEX_ARRAY))
glVertexPointer(3, GLenum(GL_FLOAT), 0, vertices)
glEnableClientState(GLenum(GL_COLOR_ARRAY))
glColorPointer(4, GLenum(GL_UNSIGNED_BYTE), 0, colors)
				
glDrawArrays(GLenum(GL_TRIANGLE_STRIP), 0, 4)
				
glDisableClientState(GLenum(GL_COLOR_ARRAY))
glDisableClientState(GLenum(GL_VERTEX_ARRAY))
```

```java:Java
import static android.opengl.GLES10.GL_COLOR_ARRAY;
import static android.opengl.GLES10.GL_FLOAT;
import static android.opengl.GLES10.GL_TRIANGLE_STRIP;
import static android.opengl.GLES10.GL_UNSIGNED_BYTE;
import static android.opengl.GLES10.GL_VERTEX_ARRAY;
import static android.opengl.GLES10.glColorPointer;
import static android.opengl.GLES10.glDisableClientState;
import static android.opengl.GLES10.glDrawArrays;
import static android.opengl.GLES10.glEnableClientState;
import static android.opengl.GLES10.glVertexPointer;

...

// 以下、どこかのメソッドの中
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
```

一つずつ `import static` を書くと大変なので、 `import static android.opengl.GLES10.*;` で一度書いてから、最後に Ctrl ( Mac は Command ) + Shift + O で展開（ Eclipse の場合）するのがオススメです。