APG4b Java版 第1章: 基本文法
1.00. はじめに
Java とは
Java はコンパイル言語であり、C++ と並んで競技プログラミングで広く使われています。
Java のメリット:
- コンパイル言語のため実行速度が速い (Python の数十倍)
- 型安全 (コンパイル時にエラーを検出できる)
int型は 32bit、long型は 64bit と明確な範囲をもつ- 標準ライブラリが充実している
Java のデメリット:
- 静的型付けのため、コードが冗長になりやすい
- Python のような多倍長整数が標準では使えない (
BigIntegerクラスを使う必要がある) - コンパイルが必要なため、実行までの手順が多い
AtCoder での Java 環境
AtCoder では Java (OpenJDK 21) を選択して提出します。
Hello, world!
Java で最初に書くプログラムは次のようになります。
public class Main {
public static void main(String[] args) {
System.out.println("Hello, world!");
}
}実行結果:
Hello, world!Java のプログラムは必ず public class Main と public static void main(String[] args) から始まります。この部分は「おまじない」として毎回書く必要があります。実際に処理を書く部分は main メソッドの { と } の間です。
この教材全体を通して、コードは基本的にこの形式で書きます。省略している場合でも、実際には public class Main { public static void main(String[] args) { ... } } の中に書くことを忘れないでください。
1.01. 出力とコメント
キーポイント
- 文字列や数値の出力には
System.out.println()を使う - 改行なし出力は
System.out.print() - 1行コメントは
//、複数行コメントは/* */
文字列の出力
System.out.println() は括弧の中の内容を出力し、最後に改行を挿入します。文字列 (テキスト) を出力するときは " (ダブルクォート) で囲みます。
public class Main {
public static void main(String[] args) {
System.out.println("Hello, world!");
}
}実行結果:
Hello, world!別の文字列を出力したい場合も同様です。
System.out.println("Javaだいすき");実行結果:
Javaだいすき数値の出力
文字列だけでなく、数値をそのまま渡すこともできます。
System.out.println(123);実行結果:
123数値は " で囲まなくてよいことに注意してください。
複数の出力 (改行区切り)
System.out.println() を複数回呼び出すと、それぞれ改行されて出力されます。
System.out.println("Hello, world!");
System.out.println(123);実行結果:
Hello, world!
1231行目に "Hello, world!"、2行目に 123 が出力されます。
改行なし出力
System.out.print() は末尾に改行を挿入しません。
System.out.print("Hello, world! ");
System.out.println(123);実行結果:
Hello, world! 1231つ目の print() は改行なしで "Hello, world! " を出力し、2つ目の println() が 123 を出力してから改行します。結果として同じ行に並んで表示されます。
スペース区切りで複数値を出力
+ 演算子で文字列を連結して出力することができます。
System.out.println("Hello, world! " + 123);実行結果:
Hello, world! 123変数を使って複数の値をスペース区切りで出力する例:
int a = 10, b = 20;
System.out.println(a + " " + b);実行結果:
10 20printf による書式付き出力
System.out.printf() を使うと書式を指定して出力できます。%d は整数、%n は改行を意味します。
System.out.printf("%d %d%n", 10, 20);実行結果:
10 20書式付き出力の詳細は第3章で説明します。
コメント
プログラム中にメモや説明を書きたいときは「コメント」を使います。コメントはプログラムの実行には影響しません。
1行コメント (//):
// から行末までがコメントになります。
// 123
// 456
// と出力するプログラムです
System.out.println(123);
System.out.println(456);実行結果:
123
456// 以降の部分はコメントなので、実行されるのは System.out.println(123) と System.out.println(456) の2行だけです。
複数行コメント (/* */):
/* から */ までが複数行のコメントになります。
/*
* System.out.println() は受け取った要素を出力する
* 最後に改行が自動で挿入される
*/
System.out.println("こんにちは");コメントアウト
一時的にコードを実行しないようにするために、コードをコメントにすることを「コメントアウト」といいます。
// System.out.println(123);
System.out.println(456);実行結果:
4561行目はコメントアウトされているので実行されず、456 だけが出力されます。
注意事項
- 全角文字 (日本語など) はコメントや文字列の中だけ使用する。変数名や演算子には使えない
- 文末には必ず
;(セミコロン) をつける。忘れるとコンパイルエラーになる
練習問題
EX1. コードテストと出力の練習
1.02. プログラムの書き方とエラー
キーポイント
- Java はコンパイル言語: ソースコード → コンパイル → 実行の順で動作する
- エラーには「コンパイルエラー」と「実行時エラー」がある
- エラーメッセージをよく読んで原因を特定する
Java の基本構造
Java のプログラムは必ず以下の形式から始まります。
public class Main {
public static void main(String[] args) {
// ここに処理を書く
}
}public class Main: プログラムのクラス名を定義します。AtCoder では常にMainという名前を使いますpublic static void main(String[] args): プログラムの実行開始地点 (エントリーポイント) です{と}で囲まれた部分がそれぞれのブロックです
AtCoder では常にこの形式でプログラムを書きます。慣れてくれば自然に書けるようになります。
エラーの種類
プログラムを書いていると必ずエラーが発生します。エラーには主に2種類あります。
コンパイルエラー (Compile Error):
文法が間違っているときに発生します。実行する前にコンパイルの段階で検出されます。エラーメッセージには行番号と原因が表示されます。
// セミコロンを忘れた例
System.out.println("Hello") // ← ; がない → エラーこのような場合、error: ';' expected (「;」が期待されます) というメッセージが表示されます。
実行時エラー (Runtime Error):
文法は正しいが、実行中に問題が発生するエラーです。例えば、存在しない配列の要素にアクセスしようとした場合などです。
int[] a = {1, 2, 3};
System.out.println(a[5]); // ArrayIndexOutOfBoundsException (インデックスが範囲外)この例では配列 a の長さは3ですが、インデックス5番の要素にアクセスしようとしているため、実行時エラーが発生します。
論理エラー:
文法は正しく実行もできるが、意図した動作と異なる結果になるエラーです。コンパイラでは検出できないため、自分でテストして見つける必要があります。
エラーの対処法
- エラーメッセージの行番号を確認する
- その行とその周辺のコードを確認する
- 多くの場合、セミコロン忘れ、括弧の対応ミス、タイプミスが原因
練習問題
EX2. プログラムの書き方の練習
1.03. 四則演算と優先順位
キーポイント
- Java の
/は整数同士なら整数除算 (小数点以下切り捨て) - Python の
//は存在しない %の挙動が Python と異なる (負の数の場合)- べき乗は
Math.pow()を使う
演算子一覧
| 演算子 | 意味 | 例 |
|---|---|---|
+ | 加算 | 7 + 2 = 9 |
- | 減算 | 7 - 2 = 5 |
* | 乗算 | 7 * 2 = 14 |
/ | 除算 (整数同士なら整数除算) | 7 / 2 = 3 |
% | 剰余 | 7 % 2 = 1 |
Math.pow(a, b) | べき乗 | Math.pow(7, 2) = 49.0 |
加算・減算・乗算
Python とほぼ同じように書けます。
public class Main {
public static void main(String[] args) {
System.out.println(7 + 2); // 9
System.out.println(7 - 2); // 5
System.out.println(7 * 2); // 14
}
}実行結果:
9
5
14除算
Java の / は 整数同士の場合、小数点以下を切り捨てます。これは Python の // (切り捨て除算) に対応しますが、負の数の場合に挙動が異なる点に注意が必要です。
System.out.println(7 / 2); // 3 (整数除算: 小数点以下を切り捨て)
System.out.println(7.0 / 2); // 3.5 (どちらかが小数なら浮動小数点除算)
System.out.println(-7 / 2); // -3 (0方向への切り捨て ← Pythonとは異なる!)Pythonとの違い:
- Python の
//は「負の無限大方向への切り捨て」:-7 // 2 = -4 - Java の
/は「0方向への切り捨て」:-7 / 2 = -3
べき乗
Java にはべき乗演算子 (**) がないため、Math.pow() を使います。戻り値は double (浮動小数点数) であることに注意してください。
System.out.println(Math.pow(7, 2)); // 49.0
System.out.println((int)Math.pow(7, 2)); // 49 (int に変換)整数のべき乗を求める場合は、for ループで掛け算を繰り返す方法もあります:
long power = 1;
for (int i = 0; i < 2; i++) power *= 7;
System.out.println(power); // 49剰余
% 演算子は割り算の余りを求めます。
System.out.println(7 % 2); // 1
System.out.println(-11 % 5); // -1 (Pythonでは 4 ← 符号が異なる!)Pythonとの違い:
- Python の
%は常に非負の値を返す:-11 % 5 = 4 - Java の
%は被除数 (割られる数) の符号に依存する:-11 % 5 = -1
負の数で Python と同じ結果を得たい場合は Math.floorMod() を使います:
System.out.println(Math.floorMod(-11, 5)); // 4 (Pythonの % と同じ)
// または
int result = (((-11) % 5) + 5) % 5; // 4演算子の優先順位
算数と同じく、*、/、% は +、- より先に計算されます。
| 優先度 | 演算子 |
|---|---|
| 高 | *, /, % |
| 低 | +, - |
System.out.println(3 + 4 * 5); // 23 (4*5=20 を先に計算)
System.out.println(4 * (1 + 2)); // 12 (括弧の中を先に計算)
System.out.println(3 * 5 / 2); // 7 (左から順に: 15/2=7)ゼロ除算に注意
0で割ると実行時エラーが発生します。
System.out.println(3 / 0); // ArithmeticException (実行時エラー)
System.out.println(3 % 0); // ArithmeticException (実行時エラー)
System.out.println(3.0 / 0); // Infinity (浮動小数点では例外が発生しない)練習問題
EX3. 計算問題
1.04. 変数と型
キーポイント
- Java は静的型付け言語。変数を宣言するときに型を指定する
- 主な型:
int(32bit整数)、long(64bit整数)、double(浮動小数点)、String(文字列)、boolean(真偽値) - 大きな整数には
longを使う (intは約21億まで) - 複合代入演算子 (
+=,-=など) が使える
変数とは
変数とは、値を格納する「箱」のようなものです。変数を使うことで、値に名前をつけて管理できます。
Python では型を指定せずに変数を作れましたが、Java では変数を宣言するときに型を指定する必要があります。
主な型
| 型 | 意味 | 範囲 |
|---|---|---|
int | 32bit 整数 | 約 -21億 〜 +21億 |
long | 64bit 整数 | 約 -922京 〜 +922京 |
double | 64bit 浮動小数点 | 有効桁数 約15桁 |
String | 文字列 | 制限なし |
boolean | 真偽値 | true / false |
char | 1文字 | Unicode 文字 |
変数の宣言と代入
変数を使うには「型 変数名 = 値;」という形で宣言します。
int name = 10;
System.out.println(name); // 10
System.out.println(name + 2); // 12
System.out.println(name * 2); // 20実行結果:
10
12
20name という変数に 10 を代入し、その後で name を使って計算しています。name + 2 は 10 + 2 = 12 と評価されます。
複数の変数を宣言する例:
int x = 3;
long y = -7300000000L; // long リテラルは末尾に L をつける
double z = -7.3;
String s = "ABC";
boolean flag = true;long 型の定数には末尾に L を付けます。付けないと int として扱われ、int の範囲を超えるとコンパイルエラーになります。
変数の上書き
= を使って変数の値を変更できます。
int x = 3;
System.out.println(x); // 3
x = 10;
System.out.println(x); // 10実行結果:
3
10最初に x = 3 と宣言し、その後 x = 10 で値を上書きしています。
式の代入
変数の値を別の変数に代入したり、計算式を代入することもできます。
int x = 3;
int y = x; // y は x の値 (3) が代入される
int z = x * 10 + 2; // z は 3 * 10 + 2 = 32 が代入される
System.out.println(y); // 3
System.out.println(z); // 32重要: Java の = は「等しい」ではなく「右辺の値を左辺に代入する」という意味です。x = 10 は「x と 10 が等しい」ではなく「x に 10 を代入する」という意味です。
int と long の使い分け
int 型は約21億 (2^31 - 1 = 2,147,483,647) までの値しか格納できません。競技プログラミングではこの上限を超えることが多いため、注意が必要です。
int a = 2000000000;
int b = 2000000000;
System.out.println(a + b); // -294967296 (オーバーフロー!)
long la = 2000000000L;
long lb = 2000000000L;
System.out.println(la + lb); // 4000000000 (正しい)int + int の計算結果が int の範囲を超えると「オーバーフロー」が発生し、意図しない値になります。迷ったら long を使うのが安全です。
double の精度
double は浮動小数点数を扱いますが、すべての実数を正確に表現することはできません。
System.out.println(100.0 / 3.0); // 33.333333333333336
System.out.println(0.1 + 0.2); // 0.30000000000000004整数値を扱う問題では double を使わず long を使うようにしましょう。
型変換 (キャスト)
ある型の値を別の型に変換することを「キャスト」といいます。(型) を前に付けることで変換できます。
int a = 7;
double b = (double) a / 2; // int を double に変換してから割る → 3.5
int c = (int) b; // double を int に変換 (小数点以下切り捨て) → 3
System.out.println(b); // 3.5
System.out.println(c); // 3int a を (double) a とすることで double として扱い、7.0 / 2 = 3.5 という計算ができます。
複合代入演算子
変数を使って計算した結果を同じ変数に代入するパターンが頻繁に出てきます。このために「複合代入演算子」が用意されています。
| 演算子 | 例 | 等価な式 |
|---|---|---|
+= | x += 3 | x = x + 3 |
-= | x -= 3 | x = x - 3 |
*= | x *= 3 | x = x * 3 |
/= | x /= 3 | x = x / 3 |
%= | x %= 3 | x = x % 3 |
int x = 2;
x += 5; // x = 2 + 5 = 7
x *= 3; // x = 7 * 3 = 21
x /= 2; // x = 21 / 2 = 10 (整数除算)
x %= 3; // x = 10 % 3 = 1
x -= 1; // x = 1 - 1 = 0
System.out.println(x); // 0インクリメント・デクリメント
変数を 1 増やす・減らす操作は頻繁に行うため、専用の演算子があります。
int x = 5;
x++; // x = x + 1 と同じ → 6
x--; // x = x - 1 と同じ → 5
System.out.println(x); // 5String と数値の変換
文字列と数値を相互に変換する方法です。
// String → int
String s = "123";
int n = Integer.parseInt(s); // 123
// int → String
int m = 456;
String t = String.valueOf(m); // "456"
// または
String u = Integer.toString(m); // "456"練習問題
EX4. ◯年は何秒?
1.05. 入力
キーポイント
Scannerクラスを使って入力を受け取るsc.nextInt()で整数、sc.nextDouble()で浮動小数点、sc.next()で文字列 (スペース区切り)sc.nextLine()で1行全体を読み込む
Scanner の基本
競技プログラミングでは、プログラムに外部からデータを渡す「入力」が必要です。Java では Scanner クラスを使って標準入力からデータを読み込みます。
Scanner を使うには最初に import java.util.Scanner; と書く必要があります。
文字列の入力:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine(); // 1行全体を文字列として読み込む
System.out.println(s);
System.out.println(s);
System.out.println(s);
}
}入力: Javaだいすき出力:
Javaだいすき
Javaだいすき
JavaだいすきScanner sc = new Scanner(System.in); で入力を読み込む準備をします。sc.nextLine() で1行を文字列として読み込み、変数 s に代入します。同じ変数を3回出力しているので、同じ文字列が3行表示されます。
整数の入力
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = sc.nextInt(); // 整数を読み込む
System.out.println(a * 10);
}
}入力: 5出力: 50
sc.nextInt() は入力から整数を1つ読み込みます。読み込んだ値を変数 a に代入し、a * 10 を計算して出力しています。
浮動小数点の入力
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
double a = sc.nextDouble();
System.out.println(a * 10);
}
}入力: 3.14出力: 31.400000000000002
浮動小数点の誤差により、出力が 31.4 にはならないことがあります。
複数の値の入力
sc.next() はスペースや改行で区切られた次のトークン (単語) を読み込みます。sc.nextInt() も同様にスペースや改行をスキップして次の整数を読みます。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.next(); // スペースや改行で区切られた次の文字列
int a = sc.nextInt(); // 次の整数
System.out.println(s + " " + a * 10);
}
}入力:
Hello
5出力: Hello 50
スペース区切りで複数の整数を入力
1行にスペース区切りで複数の整数が並んでいる場合も、nextInt() を繰り返し呼ぶだけで読み込めます。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
int b = sc.nextInt();
int c = sc.nextInt();
System.out.println(a * 10);
System.out.println(b * 100);
System.out.println(c * 1000);
}
}入力: 10 20 30出力:
100
2000
30000nextInt() はスペースや改行を自動的にスキップして次の整数を読み込みます。そのため、値が1行に並んでいても複数行に分かれていても同じコードで読み込むことができます。
高速入力 (BufferedReader)
Scanner は便利ですが、大量の入力を処理する場合は遅くなることがあります。その場合は BufferedReader を使います。
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
System.out.println(a + b);
}
}最初のうちは Scanner を使えば十分です。TLE (実行時間制限超過) が起きた場合に BufferedReader への切り替えを検討してください。
練習問題
EX5. A足すB問題
1.06. if文・比較演算子・論理演算子
キーポイント
if/else if/elseで条件分岐- 比較演算子:
==,!=,>,<,>=,<= - 論理演算子:
!(否定),&&(AND),||(OR) - Python の
and/or/notはそれぞれ&&/||/!に対応 - 連鎖比較
0 <= x <= 100はできない →0 <= x && x <= 100と書く
条件分岐とは
「指定した条件に当てはまるときだけ処理をする」というのが条件分岐です。Java では if 文を使います。
比較演算子
比較演算子は2つの値を比較し、結果を true または false で返します。
| 演算子 | 意味 |
|---|---|
x == y | x と y が等しい |
x != y | x と y が等しくない |
x > y | x は y より大きい |
x < y | x は y より小さい |
x >= y | x は y 以上 |
x <= y | x は y 以下 |
論理演算子
複数の条件を組み合わせるときに使います。
| 演算子 | 意味 | Python の対応 |
|---|---|---|
!条件式 | 否定 (条件が true なら false、false なら true) | not |
条件式1 && 条件式2 | 両方が true のとき true | and |
条件式1 || 条件式2 | 少なくとも一方が true のとき true | or |
基本的な if 文
if (条件式) { 処理 } の形で書きます。条件式が true のときだけ {} 内の処理が実行されます。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
if (x < 10) {
System.out.println("x は 10 より小さい");
}
System.out.println("終了");
}
}入力が 5 のとき:
x は 10 より小さい
終了入力が 15 のとき:
終了入力が 5 のとき 5 < 10 は true なので if 内の処理が実行されます。入力が 15 のとき 15 < 10 は false なので if 内の処理はスキップされます。
複数の if 文
複数の if 文を並べることで、複数の条件を独立してチェックできます。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
if (x < 10) {
System.out.println("x は 10 より小さい");
}
if (x >= 20) {
System.out.println("x は 20 以上");
}
if (x == 5) {
System.out.println("x は 5");
}
if (x != 100) {
System.out.println("x は 100 ではない");
}
System.out.println("終了");
}
}入力が 5 のとき:
x は 10 より小さい
x は 5
x は 100 ではない
終了4つの if 文がそれぞれ独立してチェックされるため、複数の条件を同時に満たす場合は複数のメッセージが出力されます。
論理演算子の使用例
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
int y = sc.nextInt();
if (!(x == y)) {
System.out.println("x と y は等しくない");
}
if (x == 10 && y == 10) {
System.out.println("x と y は両方とも 10");
}
if (x == 0 || y == 0) {
System.out.println("x か y の少なくともどちらかは 0");
}
System.out.println("終了");
}
}else 節
「条件が true のときは処理A、そうでなければ処理B」というパターンには else を使います。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
if (x < 10) {
System.out.println("x は 10 より小さい");
} else {
System.out.println("x は 10 より小さくない");
}
}
}if の条件が false のとき、else 内の処理が実行されます。
else if チェーン
複数の条件を順番にチェックするには else if を使います。上から順にチェックして、最初に true になった条件のブロックだけが実行されます。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
if (x < 10) {
System.out.println("x は 10 より小さい");
} else if (x > 20) {
System.out.println("x は 10 より小さくなくて、20 より大きい");
} else if (x == 15) {
System.out.println("x は 10 以上 20 以下で、15 である");
} else {
System.out.println("x は 10 以上 20 以下で、15 でもない");
}
}
}入力が 5 → 最初の if が true → "x は 10 より小さい" を出力
入力が 25 → 最初の if は false、次の else if が true → "x は 10 より小さくなくて、20 より大きい" を出力
入力が 15 → 最初と2番目は false、3番目の else if が true → "x は 10 以上 20 以下で、15 である" を出力
ネストした if 文
if 文の中にさらに if 文を書くことができます。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
if (x % 2 == 0) {
if (x % 3 == 0) {
System.out.println("x は 2 の倍数でも 3 の倍数でもある");
} else {
System.out.println("x は 2 の倍数ではあるが 3 の倍数ではない");
}
} else {
if (x % 3 == 0) {
System.out.println("x は 2 の倍数ではないが 3 の倍数ではある");
} else {
System.out.println("x は 2 の倍数でも 3 の倍数でもない");
}
}
}
}x = 6 のとき: 6 % 2 == 0 が true → 内側の if で 6 % 3 == 0 が true → 「2の倍数でも3の倍数でもある」
範囲チェック (連鎖比較の代替)
Python では 0 <= x <= 100 と書けますが、Java ではこの書き方はできません。&& を使って書きます。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
if (0 <= x && x <= 100) {
System.out.println("x は 0 以上 100 以下です");
} else {
System.out.println("x は 0 以上 100 以下ではありません");
}
}
}0 <= x && x <= 100 は「x が 0 以上」かつ「x が 100 以下」という2つの条件を && で結んでいます。
練習問題
EX6. 電卓をつくろう
1.07. 論理式の値と boolean 型
キーポイント
- 条件式の評価結果は
boolean型 (true/false) - Python の
True/Falseに対応するが、truthy/falsy の概念はない - 数値の
0はfalseに変換できない (コンパイルエラーになる) boolean変数は&&、||、!で操作できる
boolean 型とは
boolean (ブーリアン) 型は true (真) か false (偽) の2つの値だけをとるデータ型です。比較演算子や論理演算子の結果がこの型になります。
Python の True/False に対応しますが、Java には Python のような「truthy/falsy」の概念がありません。数値の 0 を if の条件に使うとコンパイルエラーになります。
条件式の評価結果
条件式を書くと、その評価結果は boolean 型の値になります。
public class Main {
public static void main(String[] args) {
int x = 0;
System.out.println(x == 0); // true
System.out.println(x >= 1); // false
}
}実行結果:
true
falsex == 0 は「x は 0 と等しいか?」という条件式で、x = 0 のとき true を返します。
boolean 変数
条件式の結果を boolean 型の変数に格納できます。
public class Main {
public static void main(String[] args) {
int x = 5;
boolean a = (0 <= x); // 0 <= 5 → true
boolean b = (x <= 10); // 5 <= 10 → true
boolean c = a && b; // true && true → true
System.out.println(a + " " + b + " " + c); // true true true
}
}実行結果:
true true truea と b をそれぞれ別の boolean 変数に格納し、c = a && b でその AND をとっています。
boolean 型を if 文で使う
boolean 型の変数を直接 if の条件に使えます。
public class Main {
public static void main(String[] args) {
if (true) {
System.out.println("条件を満たした");
}
if (false) {
System.out.println("表示されない");
} else {
System.out.println("条件を満たさなかった");
}
}
}実行結果:
条件を満たした
条件を満たさなかったPython との違い: truthy/falsy がない
Python では if 10: や if "hello": のように、0以外の数値や空でない文字列が true として扱われます (truthy/falsy)。しかし Java では boolean 値のみが使えます。
// コンパイルエラーになる例
// if (10) { } // エラー: int を boolean として使えない
// if ("hello") { } // エラー
// 正しい書き方
if (10 != 0) { System.out.println("0でない"); }
String str = "hello";
if (!str.isEmpty()) { System.out.println("空でない"); }boolean 変数の実用例
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
int y = sc.nextInt();
boolean isEqual = (x == y);
boolean isBothPositive = (x > 0) && (y > 0);
boolean isEitherZero = (x == 0) || (y == 0);
System.out.println("等しい: " + isEqual);
System.out.println("両方正: " + isBothPositive);
System.out.println("どちらか0: " + isEitherZero);
}
}練習問題
EX7. boolean値パズル
1.08. while 文
キーポイント
while (条件式) { 処理 }で繰り返し処理- 条件式が
trueである間、処理を繰り返し続ける - カウンタ変数を使った
while (i < N)パターンが基本 - Python と構文がほぼ同じ (インデントの代わりに
{}を使う)
while 文とは
「条件が成立している間、処理を繰り返す」というのが while 文です。同じ処理を何度も繰り返すことを「ループ」といいます。
基本構文
while (条件式) {
処理
}while の丸括弧内の条件式が true の間、{} 内の処理が繰り返されます。処理が終わるたびに条件式が再評価されます。
カウンタ変数を使った基本パターン:
int i = 0;
while (i < N) {
// 繰り返したい処理
i++; // カウンタを増やす (忘れると無限ループになる)
}無限ループ
条件式に true を書くと、永遠にループします。break 文で抜けない限り終了しません。
while (true) {
System.out.println("Hello");
System.out.println("AtCoder");
}このプログラムを実行するとプログラムが終了しないまま動き続けます。
カウントアップ
i を 0 から始めて 1 ずつ増やしながら N 回処理するパターンです。
public class Main {
public static void main(String[] args) {
int i = 0;
while (i < 5) {
System.out.println("Hello");
i++;
}
}
}実行結果:
Hello
Hello
Hello
Hello
Helloこのプログラムの流れ:
i = 0→0 < 5はtrue→"Hello"を出力 →iを 1 にi = 1→1 < 5はtrue→"Hello"を出力 →iを 2 にi = 2→2 < 5はtrue→"Hello"を出力 →iを 3 にi = 3→3 < 5はtrue→"Hello"を出力 →iを 4 にi = 4→4 < 5はtrue→"Hello"を出力 →iを 5 にi = 5→5 < 5はfalse→ ループ終了
実践例: N個の整数の合計
N 個の整数を入力から読み込み、合計を計算するプログラムです。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt(); // 個数を読み込む
int s = 0; // 合計 (最初は0)
int i = 0;
while (i < N) {
int x = sc.nextInt(); // 値を1つ読み込む
s += x; // 合計に加える
i++;
}
System.out.println(s);
}
}入力:
3
1
10
100出力: 111
N = 3 のとき: 1回目で s = 0 + 1 = 1、2回目で s = 1 + 10 = 11、3回目で s = 11 + 100 = 111
2ずつ増やすループ
ループの増分は1に限りません。
int i = 0;
while (i < 10) {
System.out.println(i);
i += 2; // 2ずつ増やす
}実行結果:
0
2
4
6
8逆順ループ
大きい値から小さい値に向かってカウントダウンすることもできます。
int i = 5;
while (i >= 0) {
System.out.println(i);
i--; // 1ずつ減らす
}実行結果:
5
4
3
2
1
0練習問題
EX8. たくさんのA足すB問題
1.09. for 文・break・continue
キーポイント
for (初期化; 条件式; 更新) { 処理 }が基本構文- N回繰り返すなら
for (int i = 0; i < N; i++) breakでループを抜けるcontinueで残りの処理をスキップして次のループへ- Python の
for x in range(N)はfor (int i = 0; i < N; i++)に対応
for 文とは
while 文でカウンタ変数を使うパターンをより簡潔に書けるのが for 文です。
while 文:
int i = 0; // 初期化
while (i < 5) { // 条件式
処理
i++; // 更新
}for 文 (同じ意味):
for (int i = 0; i < 5; i++) {
処理
}for (初期化; 条件式; 更新) という形で、while 文の3つの要素をまとめて書けます。
for 文の基本
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
}
}実行結果:
0
1
2
3
4i は 0 から始まり、i < 5 が true の間ループし、各繰り返しの最後に i++ が実行されます。したがって i は 0, 1, 2, 3, 4 と変化し、i = 5 になったときループが終了します。
Python の for i in range(5): と対応します。
range(a, b) の代わり
Python の for i in range(2, 5): は i が 2, 3, 4 と変化します。Java では:
for (int i = 2; i < 5; i++) {
System.out.println(i);
}実行結果:
2
3
4break
break は現在のループを即座に終了します。
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
if (i == 3) {
System.out.println("ぬける");
break; // ループを終了
}
System.out.println(i);
}
System.out.println("終了");
}
}実行結果:
0
1
2
ぬける
終了i = 3 のとき if (i == 3) が true になり、"ぬける" を出力してから break でループを終了します。i = 3, 4 のときの処理はスキップされます。
continue
continue はそのイテレーションの残りの処理をスキップして、次のイテレーションに進みます。
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
if (i == 3) {
System.out.println("とばす");
continue; // 残りをスキップして次のループへ
}
System.out.println(i);
}
System.out.println("終了");
}
}実行結果:
0
1
2
とばす
4
終了i = 3 のとき continue が実行され、その後の System.out.println(i) はスキップされます。ただしループ自体は続き、i = 4 の処理が実行されます。break との違いに注意してください。
2ずつ増やすループ
Python の for i in range(0, 10, 2): は:
for (int i = 0; i < 10; i += 2) {
System.out.println(i);
}実行結果:
0
2
4
6
8逆順ループ
Python の for i in range(5, -1, -1): は:
for (int i = 5; i >= 0; i--) {
System.out.println(i);
}実行結果:
5
4
3
2
1
0練習問題
EX9. 電卓をつくろう2
1.10. 配列 (リスト)
キーポイント
- Java の配列は宣言時にサイズが固定される:
int[] a = new int[N] - 可変長のリストには
ArrayList<Integer>を使う - インデックスは 0 から始まる
a.lengthで配列の長さを取得 (ArrayList の場合はlist.size())- 配列の入力:
forループでsc.nextInt()を繰り返す
配列とは
複数の値をまとめて扱いたいときに使うのが「配列」です。Python の「リスト」に対応しますが、Java の配列はサイズが固定されているという違いがあります。
配列の基本
初期値を指定して配列を作成する方法:
int[] a = {3, 1, 4, 1, 5}; // 5要素の配列
System.out.println(a.length); // 5 (要素数)
System.out.println(a[0]); // 3 (インデックス0の要素)
System.out.println(a[2]); // 4 (インデックス2の要素)
// 要素の変更
a[2] = 7;
System.out.println(a[2]); // 7実行結果:
5
3
4
7インデックスは 0 から始まります。a[0] が最初の要素、a[4] が最後の要素です。
サイズ指定で配列を作成
要素数だけ決めて、後から値を入れることもできます。整数型の配列は自動的に 0 で初期化されます。
int N = 5;
int[] a = new int[N]; // 要素が {0, 0, 0, 0, 0} の配列が作られるfor ループで配列を処理
インデックス付きの for ループで全要素を処理できます。
int[] a = {3, 1, 4, 1, 5};
for (int i = 0; i < a.length; i++) {
System.out.println(i + " : " + a[i]);
}実行結果:
0 : 3
1 : 1
2 : 4
3 : 1
4 : 5a.length は配列の要素数を返します。i は 0, 1, 2, 3, 4 と変化し、各インデックスの要素を表示しています。
拡張 for 文 (foreach)
値だけを順番に処理したい場合は「拡張 for 文」が使えます。Python の for x in a: に対応します。
int[] a = {3, 1, 4, 1, 5};
for (int x : a) {
System.out.println(x);
}実行結果:
3
1
4
1
5for (int x : a) は「配列 a の各要素を x として順番に処理する」という意味です。
入力から配列を作成
N 個の整数を読み込んで配列に格納するパターンは非常によく使います。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt(); // 要素数を読み込む
int[] a = new int[N]; // N要素の配列を作成
for (int i = 0; i < N; i++) {
a[i] = sc.nextInt(); // 各要素を読み込む
}
// スペース区切りで出力
for (int i = 0; i < N; i++) {
if (i > 0) System.out.print(" ");
System.out.print(a[i]);
}
System.out.println();
}
}例題: 数学と英語のテストの合計点
N 人の数学 (M[i]) と英語 (E[i]) の点数が与えられ、各人の合計点を出力する問題です。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int[] M = new int[N];
int[] E = new int[N];
for (int i = 0; i < N; i++) M[i] = sc.nextInt();
for (int i = 0; i < N; i++) E[i] = sc.nextInt();
for (int i = 0; i < N; i++) {
System.out.println(M[i] + E[i]);
}
}
}入力:
3
20 100 30
100 5 40出力:
120
105
70まず N = 3 を読み込み、M[] に 20, 100, 30、E[] に 100, 5, 40 を格納します。その後 M[0]+E[0]=120, M[1]+E[1]=105, M[2]+E[2]=70 を出力します。
ArrayList (可変長リスト)
Java の通常の配列はサイズが固定ですが、ArrayList を使うと要素を動的に追加・削除できます。Python のリストに近い挙動です。
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(1); // [1]
list.add(2); // [1, 2]
list.add(3); // [1, 2, 3]
System.out.println(list.size()); // 3 (要素数)
System.out.println(list.get(0)); // 1 (0番目の要素)
list.set(1, 20); // インデックス1の要素を20に変更
System.out.println(list.get(1)); // 20
list.remove(list.size() - 1); // 末尾の要素を削除
System.out.println(list); // [1, 20]
}
}ArrayList<Integer> の <Integer> は「整数を格納する ArrayList」という意味です。プリミティブ型 (int) ではなくラッパー型 (Integer) を使う点に注意してください。
ArrayList の主な操作
| 操作 | メソッド | 計算量 |
|---|---|---|
| 末尾に追加 | list.add(x) | O(1) |
| インデックスで取得 | list.get(i) | O(1) |
| インデックスで変更 | list.set(i, x) | O(1) |
| 末尾を削除 | list.remove(list.size()-1) | O(1) |
| 途中に挿入 | list.add(i, x) | O(N) |
| 途中を削除 | list.remove(i) | O(N) |
| サイズ取得 | list.size() | O(1) |
| 要素を検索 | list.contains(x) | O(N) |
配列を逆順に出力
int[] a = {3, 1, 4, 1, 5};
for (int i = a.length - 1; i >= 0; i--) {
System.out.println(a[i]);
}実行結果:
5
1
4
1
3a.length - 1 は最後のインデックス (= 4) です。そこから 0 まで 1 ずつ減らしながら逆順に出力します。
練習問題
EX10. 平均との差
1.11. 文字列
キーポイント
- Java の
Stringは不変 (immutable): 作成後に変更できない - 文字へのアクセスは
s.charAt(i)(Python のs[i]) - 文字列の長さは
s.length()(配列のa.lengthと違い括弧が必要) - 文字列の連結は
+演算子またはStringBuilder - 文字列の比較は
==ではなく.equals()を使う
文字列の基本
Java の文字列は String 型で表します。" (ダブルクォート) で囲みます。
String a = "ABCDEFG";
String b = "AtCoder";エスケープシーケンス
特殊な文字を文字列の中で表現するときは「エスケープシーケンス」を使います。
| 記法 | 意味 |
|---|---|
\n | 改行 |
\" | ダブルクォート |
\' | シングルクォート |
\\ | バックスラッシュ |
\t | タブ |
System.out.println("Hello\nWorld"); // 改行して World を出力
System.out.println("She said \"Hi\""); // ダブルクォートを出力実行結果:
Hello
World
She said "Hi"主な文字列操作
String s = "Hello, AtCoder!";
System.out.println(s.length()); // 15 (文字数)
System.out.println(s.charAt(0)); // H (0番目の文字)
System.out.println(s.charAt(7)); // A (7番目の文字)
System.out.println(s.indexOf("At")); // 7 (最初に出現する位置)
System.out.println(s.contains("At")); // true (含まれるかどうか)
System.out.println(s.substring(7)); // AtCoder! (7文字目以降)
System.out.println(s.substring(7, 14)); // AtCoder (7〜13文字目)
System.out.println(s.replace("At", "My")); // Hello, MyCoder!
System.out.println(s.toUpperCase()); // HELLO, ATCODER!
System.out.println(s.toLowerCase()); // hello, atcoder!注意: 配列の長さは a.length (括弧なし)、文字列の長さは s.length() (括弧あり) です。紛らわしいので注意してください。
文字列の文字を1つずつ処理
インデックスを使ったループで各文字を取り出せます。
String s = "AtCoder";
for (int i = 0; i < s.length(); i++) {
System.out.println(s.charAt(i));
}拡張 for 文を使う場合は toCharArray() で char の配列に変換します:
for (char c : s.toCharArray()) {
System.out.println(c);
}実行結果:
A
t
C
o
d
e
r文字列の連結
+ 演算子で文字列を連結できます。数値も自動的に文字列に変換されます。
String s = "Hello";
String t = "World";
System.out.println(s + ", " + t + "!"); // Hello, World!
int n = 42;
System.out.println("Answer: " + n); // Answer: 42文字列の比較 (重要)
Java では文字列の比較に == を使ってはいけません。 == はオブジェクトの参照 (メモリアドレス) を比較するため、内容が同じでも false になる場合があります。文字列の内容を比較するには .equals() メソッドを使います。
String a = new String("Hello");
String b = new String("Hello");
System.out.println(a == b); // false (参照が異なる場合)
System.out.println(a.equals(b)); // true (内容が等しい)
// Scanner で読んだ文字列との比較
Scanner sc = new Scanner(System.in);
String s = sc.next();
if (s.equals("Yes")) {
System.out.println("一致!");
}これは競技プログラミングでよくある間違いです。必ず .equals() を使ってください。
文字列の分割
split() メソッドで文字列を区切り文字で分割できます。
String s = "10 20 30";
String[] parts = s.split(" "); // スペースで分割
for (String p : parts) {
System.out.println(p);
}実行結果:
10
20
30整数として処理する場合は Integer.parseInt() で変換します:
for (String p : parts) {
int val = Integer.parseInt(p);
System.out.println(val * 2);
}StringBuilder (効率的な文字列変更)
ループの中で文字列を繰り返し変更・連結する場合、String の + 演算子を使うと非効率です (毎回新しいオブジェクトが作られるため)。StringBuilder を使うと効率的に変更できます。
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(", ");
sb.append("AtCoder");
sb.append("!");
System.out.println(sb.toString()); // Hello, AtCoder!
// 文字の変更
sb.setCharAt(0, 'h');
System.out.println(sb.toString()); // hello, AtCoder!char 型と int の変換
char 型 (1文字) と int 型 (ASCII コード) は相互に変換できます。
char c = 'A';
int code = (int) c; // 65 (A の ASCII コード)
char d = (char)(code + 1); // 'B' (B の ASCII コード = 66)
System.out.println(d); // B
// 文字と 'a' の差でアルファベットのオフセットを求める
char ch = 'c';
int offset = ch - 'a'; // 2 (c は a から 2 番目)文字列と数値の変換
// String → int
int n = Integer.parseInt("123"); // 123
// String → long
long m = Long.parseLong("123456789012");
// String → double
double d = Double.parseDouble("3.14");
// int → String
String s = String.valueOf(123); // "123"
String t = Integer.toString(123); // "123"練習問題
EX11. 文字列の処理
1.12. 組み込み関数 (Math クラス・Arrays クラス)
キーポイント
- Java では多くの関数が
Mathクラスのメソッドとして提供される - 配列の操作には
Arraysクラス、コレクションの操作にはCollectionsクラス import java.util.*で多くのユーティリティが使える
Math クラス
Math クラスは java.lang パッケージに含まれているため、import なしで使えます。
// 絶対値
System.out.println(Math.abs(-3)); // 3
System.out.println(Math.abs(5)); // 5
// 最小値・最大値 (2値の比較)
System.out.println(Math.min(3, 7)); // 3
System.out.println(Math.max(3, 7)); // 7
// べき乗 (戻り値は double)
System.out.println(Math.pow(3, 4)); // 81.0
System.out.println((long)Math.pow(3, 4)); // 81 (long に変換)
// 平方根
System.out.println(Math.sqrt(16)); // 4.0
// 切り上げ・切り捨て・四捨五入
System.out.println(Math.ceil(3.2)); // 4.0 (切り上げ)
System.out.println(Math.floor(3.8)); // 3.0 (切り捨て)
System.out.println(Math.round(3.5)); // 4 (四捨五入)複数値の最小・最大
Math.min() と Math.max() は2つの値を比較します。3つ以上の場合は入れ子にします。
int a = 1, b = -5, c = 3;
int minVal = Math.min(a, Math.min(b, c)); // -5
int maxVal = Math.max(a, Math.max(b, c)); // 3配列の合計・最大値・最小値
Java 標準には配列の合計を求める sum() 関数がないため、手動でループして計算します。
import java.util.Arrays;
int[] a = {1, 3, -5, 2};
// 合計 (ループで足す)
int sum = 0;
for (int x : a) sum += x;
System.out.println(sum); // 1
// 最大値 (手動)
int maxVal = a[0];
for (int x : a) maxVal = Math.max(maxVal, x);
System.out.println(maxVal); // 3
// Stream API を使う方法 (参考)
int maxStream = Arrays.stream(a).max().getAsInt(); // 3
int minStream = Arrays.stream(a).min().getAsInt(); // -5Arrays クラス
Arrays クラスは配列を操作するための便利なメソッドを提供します。使うには import java.util.Arrays; が必要です。
import java.util.Arrays;
int[] a = {3, 1, 4, 1, 5};
// ソート (元の配列を昇順に変更する)
Arrays.sort(a);
System.out.println(Arrays.toString(a)); // [1, 1, 3, 4, 5]
// 配列の内容を文字列で表示 (デバッグに便利)
System.out.println(Arrays.toString(a)); // [1, 1, 3, 4, 5]
// 配列のコピー
int[] b = Arrays.copyOf(a, a.length); // 配列全体をコピー
int[] c = Arrays.copyOfRange(a, 1, 3); // インデックス1から2まで (2未満) をコピー
// 二分探索 (ソート済み配列に対して)
int idx = Arrays.binarySearch(a, 3); // 3 の位置を返すCollections クラス (ArrayList 向け)
ArrayList などのコレクションを操作するには Collections クラスを使います。
import java.util.*;
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(3, 1, 4, 1, 5));
System.out.println(Collections.min(list)); // 1 (最小値)
System.out.println(Collections.max(list)); // 5 (最大値)
Collections.sort(list); // 昇順ソート (in-place)
System.out.println(list); // [1, 1, 3, 4, 5]
Collections.reverse(list); // 逆順に並べ替え (in-place)
System.out.println(list); // [5, 4, 3, 1, 1]インデックスと値を一緒に処理
Python の enumerate() の代わりに、インデックス付きの for ループを使います。
int[] a = {10, 30, 20, 50, 40};
for (int i = 0; i < a.length; i++) {
System.out.println(i + " " + a[i]);
}実行結果:
0 10
1 30
2 20
3 50
4 40練習問題
EX12. Find the Fastest Runner
1.13. 関数 (メソッド)
キーポイント
- Java では関数を「メソッド」と呼ぶ
- AtCoder では
staticメソッドとして定義する - 戻り値の型を明示的に宣言する (
voidは戻り値なし) - Java にはグローバル変数の概念があるが、
staticフィールドとして定義する - スコープ (変数の有効範囲) は
{}のブロック単位
メソッドとは
同じ処理を何度も書かなくても済むように、処理をまとめて名前をつけたものを「メソッド」(Python では「関数」と呼ぶ) といいます。
Java のメソッドは main メソッドと同じクラス内に static を付けて定義します。定義する順序は問いません (main の前でも後でも OK)。
基本的なメソッド定義 (戻り値なし)
public class Main {
// 戻り値なしのメソッド
static void printNumbers() {
System.out.println(1);
System.out.println(2);
System.out.println(3);
}
public static void main(String[] args) {
printNumbers(); // 1, 2, 3 が出力される
printNumbers(); // もう一度呼び出せる
}
}実行結果:
1
2
3
1
2
3static void printNumbers() は「引数なし、戻り値なしのメソッド」です。void は「戻り値がない」ことを意味します。
引数をとるメソッド
引数 (パラメータ) を受け取るメソッドの書き方。引数の型と名前を指定します。
public class Main {
static void addAndPrint(int a, int b) {
System.out.println(a + b);
}
public static void main(String[] args) {
addAndPrint(1, 2); // 3
addAndPrint(10, 20); // 30
}
}実行結果:
3
30addAndPrint(1, 2) と呼ぶと、メソッド内の a = 1、b = 2 となり、1 + 2 = 3 が出力されます。
戻り値があるメソッド
計算結果を返すメソッドには戻り値の型を指定し、return で値を返します。
public class Main {
static int addOne(int a) {
return a + 1; // 計算結果を返す
}
public static void main(String[] args) {
int two = addOne(1); // 2 が返ってくる
System.out.println(two); // 2
System.out.println(addOne(1) + 1); // addOne(1)=2、2+1=3
}
}実行結果:
2
3addOne(1) は 1 + 1 = 2 を計算して返します。この戻り値を変数に格納したり、さらに計算に使ったりできます。
return の特性
return はメソッドをその場で終了させます。return 以降のコードは実行されません。
static int myMin(int a, int b) {
if (a < b) {
return a; // a が小さければ a を返してメソッド終了
}
return b; // そうでなければ b を返す
}早期リターン (早めに return する) のパターン:
static void printIfSeven(int a) {
if (a == 7) {
System.out.println("a is 7");
return; // ここでメソッド終了
}
// a が 7 でないときだけここに到達する
System.out.println("a is not 7");
}スコープ (変数の有効範囲)
変数は宣言された {} ブロックの中でのみ有効です。これを「スコープ」といいます。
public class Main {
static int addOne(int a) {
int result = a + 1; // result は addOne の中でのみ有効
return result;
}
public static void main(String[] args) {
System.out.println(addOne(1)); // 2
// System.out.println(result); // コンパイルエラー: result はここでは見えない
}
}static フィールド (グローバル変数に相当)
Python の global 変数に相当するものは、Java では static フィールド (クラス変数) として定義します。
public class Main {
static int a = 0; // クラスレベルで定義 = どのメソッドからでもアクセスできる
static void updateA(int val) {
a = val; // Python と違い、global 宣言は不要
}
public static void main(String[] args) {
System.out.println(a); // 0
updateA(1);
System.out.println(a); // 1
}
}Python では global a と宣言する必要がありましたが、Java の static フィールドはその宣言が不要です。
配列を引数に渡す
Java では配列はメソッドに参照渡しされます。つまり、メソッド内で配列の要素を変更すると、元の配列も変更されます (Python のリストと同じ挙動)。
public class Main {
static void addToArray(int[] arr, int val) {
arr[0] += val; // arr は元の配列と同じものを指している
}
public static void main(String[] args) {
int[] a = {1, 2, 3};
addToArray(a, 10);
System.out.println(a[0]); // 11 (元の配列が変更されている)
}
}メソッドのオーバーロード
Java では同じ名前のメソッドを、引数の型・数が異なる形で複数定義できます。これを「オーバーロード」といい、Python のデフォルト引数の代替として使えます。
public class Main {
static void func(int a) {
System.out.println(a * 3);
}
static void func(int a, int start) {
System.out.println((a + start) * 3);
}
public static void main(String[] args) {
func(1); // 1 * 3 = 3
func(1, 10); // (1 + 10) * 3 = 33
}
}実行結果:
3
33Python の def func(a, start=0): に相当します。
再帰メソッド
メソッドが自分自身を呼び出すことを「再帰呼び出し」といいます。詳細は第2章で説明しますが、ここでは例だけ示します。
public class Main {
static int factorial(int n) {
if (n == 0) return 1;
return n * factorial(n - 1); // 自分自身を呼び出す
}
public static void main(String[] args) {
System.out.println(factorial(5)); // 5! = 120
}
}練習問題
EX13. 三人兄弟へのプレゼント