PythonとJavaの言語仕様比較
Pythonの言語仕様をベースに、Javaと比較する。そのため、一部言語仕様ではなく標準ライブラリにも言及する
数値
生成
i = 10 # 整数 d = 1.23 # 浮動小数 b = 0b101 # 2進数 o = 0o77 # 8進数 x = 0xff # 16進数 j = 1j # 複素数
int i = 10; // 整数 double d = 1.23; // 浮動小数 int b = 0b101; // 2進数 int o = 077; // 8進数 int x = 0xff; // 16進数 // 複素数は標準で提供刺されていない
数値演算子
a = 1 + 2 # 加算 b = 1 - 2 # 減算 c = 1 * 2 # 乗算 d = 1 / 2 # 除算 e = 1 // 2 # 除算(小数点以下切り捨て) f = 1 % 2 # 剰余 g = 1 ** 2 # 累乗
int a = 1 + 2; // 加算 int b = 1 - 2; // 減算 int c = 1 * 2; // 乗算 double d = 1.0 / 2.0; // 除算 int e = 1 / 2; // 除算(小数点以下切り捨て) int f = 1 % 2; // 剰余 int g = Math.pow(1, 2); // 累乗
ビット演算子
a = 1 & 2 # 論理積 b = 1 | 2 # 論理和 c = 1 ^ 2 # 排他的論理和 d = ~1 # ビット反転 e = 1 << 2 # 左シフト f = 1 >> 2 # 右シフト
int a = 1 & 2; // 論理積 int b = 1 | 2; // 論理和 int c = 1 ^ 2; // 排他的論理和 int d = ~1 // ビット反転 int e = 1 << 2; // 左シフト int f = 1 >> 2; // 右シフト
文字列
生成
a = 'Hello Python' # シングルクォートで文字列生成 b = "Hello Python" # ダブルクォートで文字列生成 c = """ Hello Python""" # 複数行の文字列生成 d = "Hello " + "Python" # 文字列の連結 e = "Hello Python" * 2 # 繰り返し文字列 f = str(100) + "%" # 整数と文字列の連結
// シングルクォートで文字列生成はできない String b = "Hello Java"; // ダブルクォートで文字列生成 String c = "Hello\nJava"; // 複数行の文字列を生成する構文はない String d = "Hello " + "Java"; // 文字列の連結 StringBuilder e = new StringBuilder(); for (int i = 0; i < 2; i++) e.append("Hello Java"); // 繰り返し文字列 String f = 100 + "%";
操作
s = "Hello Python" a = s[4] # 5文字目を取り出す b = s[-1] # 最後の文字を取り出す c = s[2:4] # 3文字目から5文字目をまでを取り出す d = s[2:] # 3文字目から最後までを取り出す e = s[:3] # 先頭から4文字目までを取り出す f = s[1:6:2] # 2文字目から7文字目まで1文字飛ばしの文字列を取り出す g = len(s) # 文字数
String s = "Hello Java"; char a = s.charAt(4); char b = s.charAt(s.length() - 1); String c = s.substring(2, 4); String d = s.substring(2); String e = s.substring(0, 3); // 部分文字列の取り出しでステップ数は指定できない int g = s.length();
真偽値
比較演算子
a = "a" == "b" # 値が等しいときTrue b = "a" != "b" # 値が等しくないときTrue c = 1 > 2 # 左辺が右辺より大きいときTrue d = 1 >= 2 # 左辺が右辺以上のときTrue e = 1 < 2 # 左辺が右辺より小さい時True f = 1 <= 2 # 左辺が右辺以下のときTrue g = 1 <= a <= 10 # aが1以上10以下のときTrue h = "a" is "b" # 同一オブジェクトのときTrue i = "a" is not "b" # 同一オブジェクトではないときTrue
boolean a = "a".equals("b"); // 値が等しいときtrue boolean b = !"a".equals("b"); // 値が等しくないときtrue boolean c = 1 > 2; // 左辺が右辺より大きいときtrue boolean d = 1 >= 2; // 左辺が右辺以上のときtrue boolean e = 1 < 2; // 左辺が右辺より小さい時true boolean f = 1 <= 2; // 左辺が右辺以下のときtrue boolean g = 1 <= a && a <= 10; // aが1以上10以下のときTrue boolean h = "a" == "b"; // 同一オブジェクトのときtrue boolean i = "a" != "b"; // 同一オブジェクトではないときtrue
論理演算子
a = True and False # 左辺と右辺がどちらもTrueのときTrue b = True or False # 左辺と右辺がどちらかTrueのときTrue c = not True # TrueのときFalse
boolean a = true && false; // 左辺と右辺がどちらもtrueのときtrue boolean b = true || false; // 左辺と右辺がどちらかtrueのときtrue boolean c = !true // trueのときfalse
条件分岐
if a > 0: print("a is grater than zero.") elif a < 0: print("a is less than 0.") else print("a is zero") b = a if a > 10 else 0 # aが10より大きいときaを返し、それ以外のとき0を返す
if (a > 0) { System.out.println("a is grater than zero."); } else if (a < 0) { System.out.println("a is less than zero."); } else { System.out.println("a is zero."); } boolean b = a > 10 ? a : 0; // aが10より大きいときaを返し、それ以外のとき0を返す
繰り返し
while
while a < 10 : # aが10より小さい間繰り返す print(a) a += 1
while (a < 10) { // aが10より小さい間繰り返す System.out.println(a++) }
for
numbers = [1, 2, 3] for number in numbers : # リストのすべての要素を繰り返す print(number) for i in range(5) # 5回繰り返す print(i)
int[] numbers = {1, 2, 3}; for (int i : numbers) { // リストのすべての要素を繰り返す System.out.println(i); } for (int i = 0; i < 5; i++) { // 5回繰り返す System.out.println(i); }
break
while a < 10 : # aが10より小さい間繰り返す print(a) a += 1 if a == 8 : # aが8のとき繰り返しを中断する break else : # breakせずにwhileを抜けた場合実行する print(a)
while (a < 10) { // aが10より小さい間繰り返す System.out.println(a++) if (a == 8) { // aが8のとき繰り返しを中断する break; } } // while-elseのような書き方はできない
continue
while a < 10 : # aが10より小さい間繰り返す if a == 5 : # aが5のとき繰り返しをスキップする a += 1 continue print(a) a += 1
while (a < 10) { // aが10より小さい間繰り返す if (a == 5) { a++; continue; } System.out.println(a++) }
関数
宣言と実行
def hello(name, prefix = "hello ", suffix = "!!") : # 関数定義 return prefix + name + suffix a = hello("Python") # 関数の実行 b = hello("Python", suffix = "!!!") # キーワード引数を使った関数の実行
public static String hello(String name, String prefix, String suffix) { // 関数定義 if (prefix == null || prefix.isEmpty()) { // 引数の初期値指定はできない prefix = "hello "; } if (suffix == null || suffix.isEmpty()) { suffix = "!!"; } return prefix + name + suffix; } String a = hello("Python", null, null); // 指定しない引数はnullを渡すか、オーバーライド舌メソッドを用意する String b = hello("Python", null, "!!!"); // キーワード引数で関数を実行することはできない
可変長引数
def total(*nums) : # 可変長引数の関数を定義 return sum(nums) a = total(1, 2, 3, 4, 5) # 可変長引数の関数を実行 def printlangs(**langs) : # キーワード引数を辞書で受け取る関数定義 for lang in langs : print(lang + "=" + str(langs[lang])) printlangs(python=1, java=2, ruby=3) # キーワード引数で関数実行
public static int total(int... nums) { // 可変長引数の関数を定義 return IntStream.of(nums).sum(); } int a = total(1, 2, 3, 4, 5); // 可変長引数の関数を実行 public static void printLangs(Map<String, Integer> langs) { // キーワード引数の指定はできない langs.entrySet().forEach(entry -> { System.out.println(entry.getKey() + "=" + entry.getValue()); }); } Map<String, Integer> z = new HashMap<>(); z.put("python", 1); z.put("java", 2); z.put("ruby", 3); printLangs(z);
関数オブジェクト
def hello() : print("hello") a = hello # 関数をオブジェクトとして変数に代入 a() # 関数オブジェクトを実行
// 関数をオブジェクトとして扱うことはできない
クロージャー
def settax(tax) : def calc(price, num) : # クロージャーを定義 return price * num * (1 + tax) return calc a = settax(0.08) # クロージャー生成 print(a(100, 5)) # クロージャー実行
// クロージャは用意されていない
ラムダ式
a = lambda x, y : x * y # ラムダ式で無名関数を定義 b = a(2, 3) # 無名関数を実行
BiFunction<Integer, Integer, Integer> a = (x, y) -> x * y; int b = a.apply(2, 3);
ジェネレータ
def langs() : # ジェネレータを定義 yield "python" yield from range(1, 4) # イテレータから値を作成 yield from [1, 2, 3] # イテレータから値を作成 yield from sublangs() # ジェネレータから値を作成 def sublangs() : yield "java" yield "ruby" for lang in langs() : # ジェネレータ呼び出し print(lang) a = (odd for odd in range(1, 10, 2)) # ジェネレータ式 for odd in a : print(odd) def count() : margin = 0 for n in range(1, 10) : recieved = yield (n + margin) # ジェネレータに送られた値を受け取る if recieved : margin = recieved a = count() print(next(a)) a.send(10) # ジェネレータに値を送る print(next(a))
// ジェネレータに相当する機能はない
クラス
定義
class Square : # クラス定義 name = "Square" # クラス変数 def __init__(self, width, height) : # 初期化メソッド self.width = width # インスタンス変数初期化 self.height = height def calc_area(self) : # インスタンスメソッド定義 return self.width * self.height @classmethod def print_name(cls) : # クラスメソッド定義 print(cls.name) a = Square(10, 20) # インスタンス生成 b = a.width # インスタンス変数参照 a.width = 15 # インスタンス変数更新 c = a.calc_area() # インスタンスメソッド実行 Square.print_name() # クラスメソッド実行
public class Square { // クラス定義 private static String name = "Square"; // クラス変数 public int width; // インスタンス変数 public int height; public Square(int width, int height) { // コンストラクタ this.width = width; // インスタンス変数初期化 this.height = height; } public int calcArea() { // インスタンスメソッド定義 return width * height; } public static void printName() { // クラスメソッド定義 System.out.println(name); } } Square a = new Square(10, 20); // インスタンス生成 int b = a.width; // インスタンス変数参照 a.width = 15; // インスタンス変数更新 int c = a.calcArea(); // インスタンスメソッド実行 Square.printName(); // クラスメソッド実行
継承
class A : # スーパークラス定義 def __init__(self, name) : self.name def hello(self) : return "hello " + name class B(A) : # サブクラス定義 def __init__(self, name) : super().__init__(name) # スーパークラスの初期化メソッド呼び出し def hello(self) : # メソッドのオーバーライド return "hello python"
public class A { // スーパークラス定義 private String name; public A(String name) { this.name = name; } public String hello() { return "hello " + name; } } public class B extends A { // サブクラス定義 public B(String name) { super(name); // スーパークラスのコンストラクタ呼び出し } @Override public String hello() { // メソッドのオーバーライド return "hello python"; } }
プロパティ
class A : def __init__(self, name) : self.__name = name # 非公開インスタンス変数 @property def name(self) : # ゲッター return self.__name @name.setter def name(self, value) : self.__name = value a = A("java") a.name = "python" print(a.name)
型
type("a") # 型を調べる str(1) # 文字列に変換する int("1") # 整数に変換する float("1.2") # 浮動小数点に変換する
"a".getClass(); // 型を調べる String.valueOf(1); // 文字列に変換する Integer.valueOf("1"); // 整数に変換する Double.valueOf("1.2"); // 浮動小数点に変換する
例外処理
try : a = int(b) except ValueError as error : # ValueError発生時に実行する print("ValueErrorr") print(error) else : # 例外が発生しなかったときに実行する print("success") finally : # 必ず実行する print("finish")
try { int a = Integer.valueOf(b); double c = 1.0 / a; } catch (NumberFormatException e) { // NumberFormatException発生時に実行する System.out.println("NumberFormatException") System.out.println(e.getMessage()); // 例外が発生しなかったときに実行する構文はない } finally { // 必ず実行する System.out.println("finish") }
リスト
生成
a = [1, 2, 3] # 要素を指定してリストを生成する b = [1] * 5 # 要素を繰り返すリストを生成する c = list(range(1, 5)) # 範囲からリストを生成する d = list("ABCDEFG") # 文字列から文字のリストを生成する
List<Integer> a = Arrays.asList(1, 2, 3); // 要素を指定してリストを生成する // 要素を繰り返すリストを生成する構文はない List<Integer> c = IntStream.range(1, 10).boxed().collect(Collectors.toList()); // 範囲からリスト(Stream)を生成する char[] d = "ABCDEFG".toCharArray(); // 文字列から文字のリスト(配列)を生成する
参照
z = list(range(1, 10)) a = z[4] # 5つ目の要素を取り出す b = z[-1] # 最後の要素を取り出す c = z[2:4] # 3つ目から5つ目をまでを取り出す d = z[2:] # 3つ目から最後までを取り出す e = z[:3] # 先頭から4つ目までを取り出す f = z[1:6:2] # 2つ目から7つ目まで1つ飛ばしのリストを取り出す g = len(z) # 要素数
List<Integer> z = IntStream.range(1, 10).boxed().collect(Collectors.toList()); int a = z.get(4); // 5つ目の要素を取り出す int b = z.get(z.size() - 1); // 最後の要素を取り出す List<Integer> c = z.subList(2, 4); // 3つ目から5つ目をまでを取り出す List<Integer> d = z.subList(2, z.size() - 1); // 3つ目から最後までを取り出す List<Integer> e = z.subList(0, 3); // 先頭から4つ目までを取り出す // ステップ数を指定してリストを取り出すことはできない
更新
z = list(range(1, 10)) z[4] = 12 # 5つ目の要素を変更する z[-1] = 13 # 最後の要素を変更する z[2:4] = [11, 12, 13, 14] # 3つ目から5つ目をまでを変更する z[2:] = [11, 12, 13, 14, 15, 16, 17] # 3つ目から最後までを変更する z[:3] = [11, 12, 13, 14] # 先頭から4つ目までを取り出す z[1:6:2] = [11, 12, 13] # 2つ目から7つ目まで1つ飛ばしで要素を変更する
int[] z = IntStream.range(1, 10).toArray(); z[4] = 12; z[z.length - 1] = 13; // 範囲指定の値更新はできない // 範囲指定の値更新はできない // 範囲指定の値更新はできない // 範囲指定の値更新はできない
追加・削除
z = [1, 2, 3] z.append(1) # 末尾に値を追加する z.insert(1, 2) # 指定位置に値を挿入する a = z.pop() # 末尾の値を取り出し削除する b = z.pop(0) # 指定位置の値を取り出し削除する z.remove(1) # 指定した値を削除する del z[1] # 値を削除する
List<Integer> z = Arrays.asList(1, 2, 3); z.add(1); // 末尾に値を追加する z.add(1, 2); // 指定位置に値を挿入する int a = z.remove(z.size() - 1); // 末尾の値を取り出し削除する int b = z.remove(0); // 指定位置の値を取り出し削除する z.remove(Integer.valueOf(1)); // 指定した値を削除する // del構文は存在しない
リスト内包表記
a = [num * 2 for num in range(1, 5)] # 値を評価したリストを生成する b = [num for num in range(1, 5) if num % 2 == 0] # 条件に一致した値でリストを生成する
// Javaにリスト内包表記に相当する構文は存在しない // ただし、Stream APIを使用することで同様の処理をさせることはできる List<Integer> z = Arrays.asList(1, 2, 3); List<Integer> a = z.stream().map(num -> num * 2).collect(Collectors.toList()); // 値を評価したリストを生成する List<Integer> b = z.stream().filter(num -> num % 2 == 0).collect(Collectors.toList()); // 条件に一致した値でリストを生成する
検索
z = [1, 2, 3] a = 1 in z # リストに値が含まれているときTrue b = z.index(2) # 値の位置を返す c = z.count(3) # リスト内の同じ値の数を返す
List<Integer> z = Arrays.asList(1, 2, 3); boolean a = z.contains(1); // リストに値が含まれているときtrue int b = z.indexOf(2); // 値の位置を返す long c = z.stream().filter(num -> num == 3).count(); // リスト内の同じ値の数を返す
タブル
生成・アンパック
a = (1, "Python") # タプルを生成する b = (1, "Python") + (2, "Hello") # タプルを連結する c = tuple(range(1, 5)) # 範囲からタプルを生成する d = zip([1, 2, 3], [4, 5, 6]) # 複数のリストを一つにまとめる e, f, g = d # アンパック e = {1, 4}, f = {2, 5}, g = {3, 6}
// Javaにタプルの構文は存在しない
参照
z = tuple(range(1, 10)) a = z[4] # 5つ目の要素を取り出す b = z[-1] # 最後の要素を取り出す c = z[2:4] # 3つ目から5つ目をまでを取り出す d = z[2:] # 3つ目から最後までを取り出す e = z[:3] # 先頭から4つ目までを取り出す f = z[1:6:2] # 2つ目から7つ目まで1つ飛ばしのリストを取り出す g = len(z) # 要素数
// Javaにタプルの構文は存在しない
検索
z = (1, 2, 3) a = 1 in z # タプルに値が含まれているときTrue
// Javaにタプルの構文は存在しない
セット
生成
a = {1, 2, 3} # セットを生成する b = set(range(1, 5)) # 範囲からセットを生成する c = frozenset({1, 2, 3}) # 変更不可のセットを生成する
Set<Integer> a = Stream.of(1, 2, 3).collect(Collectors.toSet()); // セットを生成する Set<Integer> c = Collections.unmodifiableSet(Stream.of(1, 2, 3).collect(Collectors.toSet())); // 変更不可のセットを生成する
追加・削除
z = {} z.add("Python") # セットに値を追加する z.remove("Python") # 同じ値をセットから削除する(同じ値がない場合はエラーが発生する) z.discard("Java") # 同じ値をセットから削除する(同じ値がない場合でもエラーにならない) z.clear() # セットを空にする a = z.pop() # 値を一つ取り出して削除する
セット内包表記
a = {num * 2 for num in range(1, 5)} # 値を評価したセットを生成する b = {num for num in range(1, 5) if num % 2 == 0} # 条件に一致した値でセットを生成する
// Javaにセット内包表記に相当する構文は存在しない // ただし、Stream APIを使用することで同様の処理をさせることはできる Set<Integer> a = Stream.of(1, 2, 3).map(num -> num * 2).collect(Collectors.toSet()); // 値を評価したセットを生成する Set<Integer> b = Stream.of(1, 2, 3).filter(num -> num % 2 == 0).collect(Collectors.toSet()); // 条件に一致した値でセットを生成する
集合演算
a = {1, 2, 3, 4} | {3, 4, 5, 6} # 和集合 {1, 2, 3, 4, 5, 6} b = {1, 2, 3, 4} & {3, 4, 5, 6} # 積集合 {3, 4} c = {1, 2, 3, 4} - {3, 4, 5, 6} # 差集合 {1, 2} d = {1, 2, 3, 4} ^ {3, 4, 5, 6} # 対象差集合 {1, 2, 5, 6}
// 集合演算の構文は存在しない
比較
a = {1, 2, 3} == {2, 3, 4} # セット内の値が一致しているときTrue b = {1, 2, 3} != {2, 3, 4} # セット内の値が一致していないときTrue c = {1, 2, 3}.isdisjoint({2, 3, 4}) # 共通の値が存在するときTrue d = {1, 2, 3} <= {1, 2, 3, 4} # サブセットの場合True issubset e = {1, 2, 3} >= {1, 2, 3, 4} # スーパーセットの場合True issuperset
Set<Integer> z1 = Stream.of(1, 2, 3).collect(Collectors.toSet()); Set<Integer> z2 = Stream.of(2, 3, 4).collect(Collectors.toSet()); boolean a = z1.equals(z2); boolean b = !z1.equals(z2); boolean c = z1.stream().anyMatch(num -> z2.contains(num)); // サブセットであるかを確認する構文やメソッドは存在しない // スーパーセットであるかを確認する構文やメソッドは存在しない
辞書
生成
a = {"python": 1, "java": 2, "ruby": 3} # 辞書を生成する b = dict([("python", 1), ("java", 2), ("ruby", 3)]) # タプルのリストから辞書を生成する c = dict(zip(["python", "java", "ruby"], [1, 2, 3])) # キーと値のリストから辞書を生成する d = dict.fromkeys(["python", "java", "ruby"], 0) # 初期値で辞書を生成する
// 初期値を指定してMapオブジェクトを生成できない Map<String, Integer> a = new HashMap<>(); // 空のマップを生成する
参照
z = {"python": 1, "java": 2, "ruby": 3} # 辞書を生成する a = z["python"] # キーを指定して値を参照する(キーがないとエラーになる) b = z.get("python") # キーを指定して値を参照する(キーがなくてもエラーにならない) c = "java" in z # 辞書にキーが存在するときTrueを返す d = z.keys() # すべてのキーの集合を返す e = z.values() # すべての値の集合を返す f = z.items() # すべての要素の集合を返す g = z.pop("java") # キーを指定して要素を取り出し、削除する
Map<String, Integer> z = new HashMap<>(); z.put("python", 1); z.put("java", 2); z.put("ruby", 3); int b = z.get("python"); // キーを指定して値を参照する(キーがなくてもエラーにならない) boolean c = z.containsKey("java"); // マップにキーが存在するときtrueを返す Set<String> d = z.keySet(); // すべてのキーのセットを返す Collection<Integer> e = z.values(); // すべての値のコレクションを返す Set<Map.Entry<String, Integer>> f = z.entrySet(); // すべての要素のセットを返す int g = z.remove("java"); // キーを指定して要素を取り出し、削除する
追加・更新・削除
z = {} z["python"] = 1 # キーを指定して値を追加する z["python"] = 2 # キーを指定して値を更新する z.setdefault("java", 10) # キーが存在しなければ値を追加する、存在する場合は更新しない z.update({"python": 1, "java": 11}) # 別の辞書で更新する del z["java"] # 要素を削除する z.clear() # すべての要素を削除する a = z.copy() # 辞書を複製する b = z.fromkeys(z, 0) # 同じキーを持つ辞書を生成する
Map<String, Integer> z = new HashMap<>(); z.put("python", 1); // キーを指定して値を追加する z.put("python", 2); // キーを指定して値を更新する z.putIfAbsent("java", 10); // キーが存在しなければ値を追加する、存在する場合は更新しない z.putAll(new HashMap<>()); // 別のマップで更新する z.remove("python"); // 要素を削除する z.clear(); // すべての要素を削除する Map<String, Integer> a = new HashMap<>(z); // マップを複製する Map<String, Integer> b = z.keySet().stream().collect(Collectors.toMap(key -> key, key -> 0)); // 同じキーを持つマップを生成する