SwiftとJavaを比較してみた  Swift:Java互換表

# はじめに
普段はiOSエンジニアとしてSwiftを使用してアプリ開発をしています。
サーバーはJavaメインで書かれているので勉強がてらSwiftとJavaの互換表を作ってみます。
基礎的なところから少しづつ更新していきたいと思っています。
ただSwift歴も浅いのでJavaは勿論、Swiftも間違いや、より良い書き方、こんな書き方もあるよ! といった際はコメントでご教示いただけますと幸いです。

# 変数
## 変数
```swift:swift
// 宣言
var num: Int
// 代入
num = 0
// 初期化 (var 変数名 = 値)
var num = 0

var str = "もしもし"
var bool = true
```
```java:Java
// 宣言
int num;
// 代入
num = 0;
// 初期化 (データ型名 変数名 値;)
int num = 0;

String str = "もしもし";
boolean bool = true
```
・Javaには；セミコロンが付きます。忘れそうですね。
・Stringは大文字から始まります。理由は後述します。

## 定数

```swift:swift
// let 変数名 値
let num = 0
let num: Int = 0

let greetingStr = "もしもし"
```

```java:Java
// final データ型名 変数名 値;
final int NUM = 0;

final String GREETING_STR = "もしもし";
```
・先頭に「final」というキーワードを付与します。
・定数名はすべて大文字のアンダースコア形式で命名します。

## 数値
```swift:swift
// 整数 
var int: Int = 0  // 実行環境によって32bit or 64bit

// 浮動小数点型
var float: Float = 0.1  // 10の38乗の正負 最小で6桁の精度
var double: Double = 0.1 // 10の308乗の正負 最小で15桁の精度
```
```java:Java
// 整数
byte by = 0; // 8ビット
short sh = 0; // 16ビット
int in = 0; // 32ビット
long lo = 0; // 64ビット

// 浮動小数型
float fl = 0.1; // 32ビット
double dou = 0.1; // 64ビット

// 末尾にF,LをつけることでFloat,Long型になる
num = 100F; // float型
num = 200L; // long型
```
・SwiftのIntが実行環境によって範囲が変わるのは知りませんでした。

## 文字 論理
```swift:swift
// 文字列
var str: String = "Hello"

// Character型
var character: Character = "a"  

// 論理型
var bool: Bool = true
```

```java:Java
// 文字列
String str = "Hello";

// Character型
char ch = 'あ';

// 論理型
boolean bool = true;
```
・Javaのcharacter型はシングルクォーテーションで囲います 

## 配列
```swift:swift
var stringArray: [String] = ["サウナ", "水風呂", "ロウリュー"]
var boolArray: [Bool] = []

配列名.countで要素数を取得
```
```java:Java
// データ型[] 配列名 = new データ型[要素数];
String[] stringArray = new String["サウナ", "水風呂", "ロウリュー"];
boolean[] boolArray = new boolean[3]; // 3つの要素が入る配列
boolArray[0] = true;
int[] nums; // 配列の宣言
int[] nums2 = {0, 1, 2}

配列名.length で要素数を取得
```
・要素数を宣言するのは不思議な感覚です

## 辞書
```swift:swift
// 辞書
var intDictionary: [String: Int] = ["サウナ": 37, "水風呂": 32, "ロウリュー": 6]
```
```java:Java
// 辞書 
 //Map, HashMap, Hashtable, LinkedHashMap, TreeMap...
Map<String, int> map1 = new HashMap<String, int>() {
        put("サウナ", 37);
        put("水風呂", 32);
        put("ロウリュー", 6);
};
```
・HashMapが辞書型に対応するようですが、、理解を深めて追って詳細について記載したいと思います。

## タプル
```swift:swift
let position: (Int, Int, Int) = (35, 2, 90)
let x = position.0
let y = position.1
let z = position.2
```
```java:Java
// Javaにタプルはありませんが、クラスやライブラリを使ってタプルとして使う方法があるようです。
```

## Optional nil、null許容

```swift:swift
var str: String?
var int: Int? = 0
var double: Double? = nil
var bool: Bool?
```

```java:Java
String str;
Integer int = 0;
Double double = null;
Boolean boolean;
```
下記がプリミティブ型です。整数値や実数値といった、具体的な「値」を格納するための変数です。nullは入りません。
byte、short、int、long、float、double、char、boolean

プリミティブ型には、それぞれのクラス版(参照型)として「ラッパークラス」が存在します。
IntegerやDoubleなどと大文字で表記します。Stringにはプリミティブ型は存在せずクラスのみとなるため大文字で記述します。

参照型はメモリに保存されたアドレスを参照値として変数に保存　
クラスは3000種類以上

それとラッパークラス同士の比較は気をつけましょう。基本的に**equalsメソッド**を使っておけば良さそうです。
| 比較内容 | 結果 |
| :---: | :---: |
| ラッパークラスとラッパークラスを==で同値比較 | false |
| ラッパークラスとラッパークラスをequalsメソッドで同値比較 | true |
| ラッパークラスとプリミティブ型を==で同値比較 | true |
| ラッパークラスとプリミティブ型をequalsメソッドで同値比較| true |

## キャスト
```swift:swift
var int = 3
var double = 4.5
var result = Double(int) + double
```
```java:Java
int numInt = 3;
double numDouble = 4.5
double result = (double)numInt + numDouble;
```
・int型の値をlong型に代入するなどの拡大変換は可能ですが、その逆でlong型からint型に変換する縮小変換はできません。


## 演算子
基本的な演算子(>, <, ==, !=等)はSwiftもJavaも同じです。

少し話が変わりますがSwiftは違う型同士の計算はエラーとなります。
Javaは代入する変数が計算結果と一致していれば代入できます。
```swift:swift
var numInt = 3
var double: Double = 1.1
var double2: Double
double2 = numInt * double // エラー
```
```java:Java
int num = 3;
double numDouble = 1.1;
double numDouble2;
numDouble2 = num * numDouble; // 実行可能
```

## nilチェック
```swift:swift
if let hoge = hoge {
print(hoge)
}

if hoge != nil {
print(hoge)
}

guard let hoge = hoge else { 
  return
}
```
```java:Java
String str = null;
if (StringUtils.isEmpty(str)) {
    System.out.println("str == null");
}

// strがnull
if (str == null) {
    System.out.println("str == null");
}
// strがnull以外
if (str != null) {
    System.out.println("str != null");
}
```
・Javaはnilではなくnullです

# 構文
## if文
```swift:swift
if dollar > 130 { 
print("円安")
} else if  dollar < 90 {
print("円高")
}

if age >= 18 {
print("成人")
} else {
print("未成年")
}
```
```java:Java
if (dollar > 130) {
System.out.println("円安");
} else if dollar < 90 {
System.out.println("円高");
}

if (age >= 18) {
System.out.println("成人");
} else {
System.out.println("未成年");
}
```

## Switch
```swift:swift
switch num {
  case 1: print("1")
  case 2: print("2")
  case 3: print("3")
  default: print("default")
}
```
```java:Java
switch (num) {
  case 1: { System.out.print("1");
  break;
  }
  case 2: { System.out.print("2");
  break;
  }
  case 3: { System.out.print("3");
  break;
  }
  default: { System.out.print("default") }
}
```
case 節を {} で囲んでbreak;を記述します。

## while
```swift:swift
var num = 0
while num < 3 {
  num += 1
}
```
```java:Java
int num = 0;
while (num < 3) {
 num++;
}
```
・Swift3以降++は廃止されたそうです。

## for文
```swift:swift
for i in 0..<3 {
  print(i)
}
```
```java:Java
// for(式1; 条件式; 式2)　{ 処理 }
// for(カウンタ変数の準備,カウンタ変数の条件式,　実際に実行する式)

for(int i = 0; i < 3; i++) {
System.out.print(i);
}
```
・Javaのfor文は一見複雑そうですが行っていることはSwiftと同じです。
・昔はSwiftもJavaのようにC言語のようなfor文を使っていたようですが廃止されたそうです。

# クラス
## クラス
```swift:swift
class Swift {

}
```
```java:Java
Class Java {
    // メインメソッド
    public static void main(String[] args) {
    }
}
```
・クラスはSwift同様大文字から記述します。
・メインメソッドとはプログラムを実行する時に最初に呼び出されるメソッド。メインメソッドに関しては調べてみるとC言語の流れを汲んでいるなどさらっと調べてみても面白いです。


## init  (Java コンストラクタ)
```swift:swift
class Human {
    var name:String
    var age:Int

    init(name:String, age:Int){
        self.name = name
        self.age = age
    }
}

let miyamoto = Human(name: "宮本武蔵", age: 29)
```
```java:Java
class Human {
    String name;
    int age;
 
    // 引数を持つコンストラクタ
    public Human(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
 
//インスタンスの生成
Human miyamoto = new Human("宮本武蔵", 29);
```

## 構造体
```swift:swift
struct Human {
    var name: String
    var height: Int
}

let humanA = Human(name: "サウナ太郎", height: 180)
```

```java:Java
public class Human {
    private final String name;
    private final int height;

    public Human(String name, int height) {
        this.name = name;
        this.height = height;
    }
}
```
Swiftはイニシャライザが自動生成されるので基本的なイニシャライザは記載しなくても使用できる。
Javaにはstructの概念がないためではイミュータブル(変更不可能な)なクラスとして宣言する。

## プロトコル
```swift:swift
protocol Sauna { ... }
```

```java:Java
public interface Animal { ... }
```
インターフェースはプロトコル同様にクラスにメソッドの記述を強制する。
インターフェースはクラスで共通する仕様を定義するとき、抽象クラスは他のクラスの処理の骨組みを定義するときに利用する。




## アクセス修飾子
### Swift 
|  修飾子  |  同クラス  |  モジュール  |  ファイル  |  継承、オーバーライド  |
| ---- | ---- | ---- | ---- | ---- |
|  open  |  ○  |  ○  |  ○  |  ○  |
|  public  |  ○  |  ○  |  ○  |  -  |
|  fileprivate  |  ○  |  ○  |  ○  | ○ |
|  internal  |  ○  |  ○  |  -  |  -  |
|  private  |  ○  |  -  |  -  |  -  |

※上記リスト間違いあればご指摘ください

・open  そのモジュールをインポートしていればアクセス可能。継承やoverrideもできる。
・public  そのモジュールをインポートしていればアクセス可能。継承やoverrideはできない。
・fileprivate  同一ファイルからアクセス可能
・internal  同一モジュールからアクセスできる。継承やoverrideもできる。特にアクセス修飾子をつけない場合はデフォルトでこのレベルの制限になる。
・private(set)  setの時はprivateと同じ制限、getの時は同一モジュール内からアクセスできる
・private  そのクラスまたは構造体の中でのみアクセス可能（extension内でもアクセス可能）

### Java
|  修飾子  |  同クラス  |  同パッケージ  |  サブクラス  |  他  |
| ---- | ---- | ---- | ---- | ---- |
|  public  |  ○  |  ○  |  ○  |  ○  |
|  protected  |  ○  |  ○  |  ○  |  -  |
|  (なし)  |  ○  |  ○  |  -  |  -  |
|  private  |  ○  |  -  |  -  |  -  |


# 関数

## 返り値のない関数
```swift:swift
private func sayHello() {
    print("Hello")
}

```
```java:Java
private static void sayHello() {
    System.out.println("Hello");
}
```
・privateは修飾子です


## 返り値がある関数
```swift:swift
func getAge() -> Int {
    return 20
}
```
```java:Java
public static int getAge(){
    return 20;
}
```

## 返り値と引数がある関数
```swift:swift
func happyBirthDay(age: Int) -> Int {
    age += 1
    return age
}
```
```java:Java
public static int happyBirthDay(int age) {
    age++;
    return age;
}
```
メソッドの前にstatic修飾子を付けると、staticメソッドになります。
staticメソッドは、クラスのインスタンス化なしに直接呼び出して使用できます。staticメソッドを使用するメリットは以下の通りです。

・インスタンス化せずに利用できる
・状態に依存しないことが保証される
・インスタンスごとに動作が変わらないことが保証される


## 関数の呼び出し
```swift:swift
var age = getAge()
var newAge = happyBirthDay(age: age) // getAgeで取得したageを代入(Intの20)
// newAge 21
```
```java:Java
int age = getAge;
int newAge = happyBirthDay(age); // getAgeで取得したageを代入(intの20)
// newAge  21
```

## その他
とりあえずよく使いそうなメソッドや処理はここにまとめようと思います。
```swift:swift
// IntからStringへ変換
var str = String(5)

// StringからInt?へ変換
var int = Int("5")
```
```java:Java
// intからStringへ変換
int num = 10;
Integer numInt = Integer.valueOf(num); // Intergerへ変換
String str = numInt.toString(); // Stringへ変換

// StringからIntへ変換
int int1 = Integaer.parseInt("5");
```

# 終わりに
ある程度まとまったのでひとまず投稿しますが、今後も追記していきます。
SwiftもJavaもまとめている中で学びがあり面白かったです。