APG4b Java版 第1章: 基本文法
1.00. はじめに
Javaとは
Java はコンパイル言語であり、C++ と並んで競技プログラミングで広く使われています。
メリット:
- コンパイル言語のため実行速度が速い (Python の数十倍)
- 型安全 (コンパイル時にエラーを検出できる)
int型は 32bit、long型は 64bit と明確な範囲をもつ- 標準ライブラリが充実している
デメリット:
- 静的型付けのため、コードが冗長になりやすい
- Python のような多倍長整数が標準では使えない (
BigIntegerクラスを使う必要がある) - コンパイルが必要なため、実行までの手順が多い
AtCoder での Java 環境
AtCoder では Java (OpenJDK 21) を選択して提出します。
Hello, world!
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) から始まります。この「おまじない」は毎回書く必要があります。
1.01. 出力とコメント
キーポイント
- 文字列や数値の出力には
System.out.println()を使う - 改行なし出力は
System.out.print() - 1行コメントは
//、複数行コメントは/* */
文字列の出力
public class Main {
public static void main(String[] args) {
System.out.println("Hello, world!");
}
}実行結果:
Hello, world!System.out.println() は括弧の中身を出力し、最後に改行を挿入します。文字列は " " で囲みます。
System.out.println("Javaだいすき");数値の出力
System.out.println(123);実行結果:
123複数の出力 (改行区切り)
System.out.println("Hello, world!");
System.out.println(123);実行結果:
Hello, world!
123改行なし出力
System.out.print("Hello, world! ");
System.out.println(123);実行結果:
Hello, world! 123System.out.print() は改行を挿入しません。
スペース区切りで複数値を出力
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 %d%n", 10, 20);実行結果:
10 20%n は改行を意味します。
コメント
1行コメント (//):
// 123
// 456
// と出力するプログラムです
System.out.println(123);
System.out.println(456);複数行コメント (/* */):
/*
* System.out.println() は受け取った要素を出力する
* 最後に改行が自動で挿入される
*/コメントアウト
// System.out.println(123);
System.out.println(456);実行結果:
456注意事項
- 全角文字はコメントや文字列の中だけ使用する (変数名などには使えない)
- 文末には必ず
;(セミコロン) をつける
練習問題
EX1. コードテストと出力の練習
1.02. プログラムの書き方とエラー
キーポイント
- Java はコンパイル言語: ソースコード → コンパイル → 実行の順で動作する
- エラーには「コンパイルエラー」と「実行時エラー」がある
- エラーメッセージをよく読んで原因を特定する
Java の基本構造
public class Main {
public static void main(String[] args) {
// ここに処理を書く
}
}AtCoder では常にこの形式でプログラムを書きます。
エラーの種類
コンパイルエラー (Compile Error): 文法が間違っているときに発生します。実行前に検出されます。
// セミコロンを忘れた例
System.out.println("Hello") // エラー: ';' expected実行時エラー (Runtime Error): 実行中に発生するエラーです。
int[] a = {1, 2, 3};
System.out.println(a[5]); // ArrayIndexOutOfBoundsException論理エラー: 文法は正しいが、意図した動作と異なる場合です。コンパイラでは検出できません。
練習問題
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 |
加算・減算・乗算
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
}
}除算
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 の // は負の無限大方向への切り捨て (-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 に変換)整数のべき乗を求める場合は自前で関数を書くこともあります:
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 ← 符号が異なる!)注意: Java の % は被除数の符号に依存します。Python と挙動が異なります。
負の数で Python と同じ結果を得たい場合:
int result = (((-11) % 5) + 5) % 5; // 4演算子の優先順位
| 優先度 | 演算子 |
|---|---|
| 高 | *, /, % |
| 低 | +, - |
System.out.println(3 + 4 * 5); // 23
System.out.println(4 * (1 + 2)); // 12
System.out.println(3 * 5 / 2); // 7 (左から順に計算)ゼロ除算に注意
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億まで) - 複合代入演算子 (
+=,-=など) が使える
主な型
| 型 | 意味 | 範囲 |
|---|---|---|
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); // 20int x = 3;
long y = -7300000000L; // long リテラルは末尾に L をつける
double z = -7.3;
String s = "ABC";変数の上書き
int x = 3;
System.out.println(x); // 3
x = 10;
System.out.println(x); // 10式の代入
int x = 3;
int y = x; // y は 3
int z = x * 10 + 2; // z は 32
System.out.println(y); // 3
System.out.println(z); // 32重要: = は代入であり、等号ではありません。
int と long の使い分け
競技プログラミングでは int のオーバーフローに注意が必要です。
int a = 2000000000;
int b = 2000000000;
System.out.println(a + b); // -294967296 (オーバーフロー!)
long la = 2000000000L;
long lb = 2000000000L;
System.out.println(la + lb); // 4000000000 (正しい)迷ったら long を使うのが安全です。
double の精度
System.out.println(100.0 / 3.0); // 33.333333333333336
System.out.println(0.1 + 0.2); // 0.30000000000000004浮動小数点は誤差があります。整数問題では long を使うべきです。
型変換 (キャスト)
int a = 7;
double b = (double) a / 2; // 3.5
int c = (int) b; // 3 (小数点以下切り捨て)
System.out.println(b); // 3.5
System.out.println(c); // 3複合代入演算子
| 演算子 | 例 | 等価な式 |
|---|---|---|
+= | 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; // 7
x *= 3; // 21
x /= 2; // 10
x %= 3; // 1
x -= 1; // 0
System.out.println(x); // 0インクリメント・デクリメント
int x = 5;
x++; // x = x + 1 と同じ → 6
x--; // x = x - 1 と同じ → 5String と数値の変換
// String → int
String s = "123";
int n = Integer.parseInt(s);
// int → String
int m = 456;
String t = String.valueOf(m); // または Integer.toString(m)練習問題
EX4. ◯年は何秒?
1.05. 入力
キーポイント
Scannerクラスを使って入力を受け取るsc.nextInt()で整数、sc.nextDouble()で浮動小数点、sc.next()で文字列 (スペース区切り)sc.nextLine()で1行全体を読み込む
基本的な入力
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
System.out.println(s);
System.out.println(s);
System.out.println(s);
}
}入力: Javaだいすき出力:
Javaだいすき
Javaだいすき
Javaだいすき整数の入力
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
浮動小数点の入力
double a = sc.nextDouble();
System.out.println(a * 10);入力: 3.14出力: 31.400000000000002
複数行の入力
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
スペース区切りの入力
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() はスペースや改行をスキップして次の整数を読みます。
高速入力 (BufferedReader)
大量の入力を処理する場合は 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);
}
}練習問題
EX5. A足すB問題
1.06. if文・比較演算子・論理演算子
キーポイント
if/else if/elseで条件分岐- 比較演算子:
==,!=,>,<,>=,<= - 論理演算子:
!(否定),&&(AND),||(OR) - Python の
and/or/notはそれぞれ&&/||/!に対応 - 連鎖比較
0 <= x <= 100はできない →0 <= x && x <= 100と書く
比較演算子
| 演算子 | 意味 |
|---|---|
x == y | 等しい |
x != y | 等しくない |
x > y | より大きい |
x < y | より小さい |
x >= y | 以上 |
x <= y | 以下 |
論理演算子
| 演算子 | 意味 | Pythonの対応 |
|---|---|---|
!条件式 | 否定 | not |
条件式1 && 条件式2 | 両方が真 | and |
条件式1 || 条件式2 | 少なくとも一方が真 | or |
基本的な 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 より小さい");
}
System.out.println("終了");
}
}複数の 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("終了");
}
}論理演算子の使用例
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 節
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 より小さくない");
}
}
}else 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 より小さい");
} 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 でもない");
}
}
}ネストした 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 の倍数でもない");
}
}
}
}範囲チェック (連鎖比較の代替)
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 以下ではありません");
}
}
}練習問題
EX6. 電卓をつくろう
1.07. 論理式の値と boolean 型
キーポイント
- 条件式の評価結果は
boolean型 (true/false) - Python の
True/Falseに対応するが、truthy/falsy の概念はない - 数値の
0はfalseに変換できない (コンパイルエラーになる) 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
}
}条件式の結果を変数に格納できます:
public class Main {
public static void main(String[] args) {
int x = 5;
boolean a = (0 <= x); // true
boolean b = (x <= 10); // true
boolean c = a && b; // true
System.out.println(a + " " + b + " " + c); // true true true
}
}boolean 型
boolean 型は true と false の2値だけをとります。
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": が使えますが、Java では boolean 値のみ使えます:
// コンパイルエラー
if (10) { ... } // エラー: int を boolean として使えない
if ("hello") { ... } // エラー
// 正しい書き方
if (10 != 0) { ... }
if (!str.isEmpty()) { ... }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(isEitherZero);
}
}練習問題
EX7. boolean値パズル
1.08. while 文
キーポイント
while (条件式) { 処理 }で繰り返し処理- カウンタ変数を使った
while (i < N)パターンが基本 - Python と構文がほぼ同じ (インデントの代わりに
{}を使う)
基本構文
while (条件式) {
処理
}推奨のカウンタパターン:
int i = 0;
while (i < N) {
処理
i++;
}無限ループ
while (true) {
System.out.println("Hello");
System.out.println("AtCoder");
}実行するとプログラムが終了しないまま動き続けます。
カウントアップ
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実践例: 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;
int i = 0;
while (i < N) {
int x = sc.nextInt();
s += x;
i++;
}
System.out.println(s);
}
}入力:
3
1
10
100出力: 111
2ずつ増やすループ
int i = 0;
while (i < 10) {
System.out.println(i);
i += 2;
}実行結果:
0
2
4
6
8逆順ループ
int i = 5;
while (i >= 0) {
System.out.println(i);
i--;
}実行結果:
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 文の基本
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
}
}実行結果:
0
1
2
3
4range(0, 5) の代わりに i = 0; i < 5; i++ を使います。
while との比較
// while 版
int j = 0;
while (j < 3) {
System.out.println("Hello while: " + j);
j++;
}
// for 版 (同じ意味)
for (int i = 0; i < 3; i++) {
System.out.println("Hello for: " + i);
}range(a, b) の代わり
// Python: for i in range(2, 5):
for (int i = 2; i < 5; i++) {
System.out.println(i);
}実行結果:
2
3
4break
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
ぬける
終了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
終了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で配列の長さを取得 (listの場合はlist.size())- 配列の入力:
forループでsc.nextInt()を繰り返す
配列の基本
// 固定長配列の宣言
int[] a = {3, 1, 4, 1, 5};
System.out.println(a.length); // 5
System.out.println(a[0]); // 3
System.out.println(a[2]); // 4
// 要素の変更
a[2] = 7;
System.out.println(a[2]); // 7サイズ指定で配列を作成 (0で初期化)
int N = 5;
int[] a = new int[N]; // {0, 0, 0, 0, 0}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 : 5拡張 for 文 (foreach)
int[] a = {3, 1, 4, 1, 5};
for (int x : a) {
System.out.println(x);
}実行結果:
3
1
4
1
5入力から配列を作成
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];
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();
}
}例題: 数学と英語のテストの合計点
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
70ArrayList (可変長リスト)
配列はサイズが固定ですが、ArrayList は要素を動的に追加できます。
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
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 の主な操作
| 操作 | メソッド | 計算量 |
|---|---|---|
| 末尾に追加 | 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]);
}練習問題
EX10. 平均との差
1.11. 文字列
キーポイント
- Java の
Stringは不変 (immutable): 作成後に変更できない - 文字へのアクセスは
s.charAt(i)(Python のs[i]) - 文字列の長さは
s.length()(配列のa.lengthと違い括弧が必要) - 文字列の連結は
+演算子またはStringBuilder - 文字列の比較は
==ではなく.equals()を使う
文字列の作成
String a = "ABCDEFG";
String b = "AtCoder";エスケープシーケンス
| 記法 | 意味 |
|---|---|
\n | 改行 |
\" | ダブルクォート |
\' | シングルクォート |
\\ | バックスラッシュ |
\t | タブ |
主な操作
String s = "Hello, AtCoder!";
System.out.println(s.length()); // 15
System.out.println(s.charAt(0)); // H
System.out.println(s.charAt(7)); // A
System.out.println(s.indexOf("At")); // 7
System.out.println(s.contains("At")); // true
System.out.println(s.substring(7)); // AtCoder!
System.out.println(s.substring(7, 14)); // AtCoder
System.out.println(s.replace("At", "My")); // Hello, MyCoder!
System.out.println(s.toUpperCase()); // HELLO, ATCODER!
System.out.println(s.toLowerCase()); // hello, atcoder!文字の処理
String s = "AtCoder";
for (int i = 0; i < s.length(); i++) {
System.out.println(s.charAt(i));
}または拡張 for 文:
for (char c : s.toCharArray()) {
System.out.println(c);
}文字列の連結
String s = "Hello";
String t = "World";
System.out.println(s + ", " + t + "!"); // Hello, World!
// 数値との連結
int n = 42;
System.out.println("Answer: " + n); // Answer: 42文字列の比較
注意: == は参照の比較になるため、文字列の内容比較には .equals() を使います。
String a = "Hello";
String b = "Hello";
System.out.println(a.equals(b)); // true (正しい比較)
System.out.println(a == b); // true (偶然一致することもあるが信頼できない)
// Scanner で読んだ場合
Scanner sc = new Scanner(System.in);
String s = sc.next();
if (s.equals("Yes")) {
System.out.println("一致!");
}文字列の分割
String s = "10 20 30";
String[] parts = s.split(" ");
for (String p : parts) {
System.out.println(p);
}
// 出力: 10, 20, 30 (各行)
// 整数として処理
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 c = 'A';
int code = (int) c; // 65 (ASCII コード)
char d = (char)(code + 1); // 'B'
System.out.println(d);
// 'a'〜'z' のオフセット
char ch = 'c';
int offset = ch - '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 クラス
System.out.println(Math.abs(-3)); // 3 (絶対値)
System.out.println(Math.abs(5)); // 5
System.out.println(Math.min(3, 7)); // 3 (最小値)
System.out.println(Math.max(3, 7)); // 7 (最大値)
System.out.println(Math.pow(3, 4)); // 81.0 (3^4)
System.out.println((long)Math.pow(3, 4)); // 81
// 剰余を使ったべき乗 (ModPow)
// 大きな数のべき乗余は自前で実装が必要複数値の最小・最大
// 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 = Arrays.stream(a).max().getAsInt(); // 3
int minVal = Arrays.stream(a).min().getAsInt(); // -5
// または手動
int mx = a[0];
for (int x : a) mx = Math.max(mx, x);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]
// 二分探索 (ソート済み配列に対して)
int idx = Arrays.binarySearch(a, 3); // 2Collections クラス (ArrayList 向け)
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);
System.out.println(list); // [1, 1, 3, 4, 5]
Collections.reverse(list);
System.out.println(list); // [5, 4, 3, 1, 1]インデックスと値を一緒に処理
Python の enumerate() の代わりにインデックス付きループを使います:
int[] a = {10, 30, 20, 50, 40};
for (int i = 0; i < a.length; i++) {
System.out.println(i + " " + a[i]);
}練習問題
EX12. Find the Fastest Runner
1.13. 関数 (メソッド)
キーポイント
- Java では関数を「メソッド」と呼ぶ
- AtCoder では
staticメソッドとして定義する - 戻り値の型を明示的に宣言する (
voidは戻り値なし) - Java にはグローバル変数の概念があるが、
staticフィールドとして定義する - スコープ (変数の有効範囲) は
{}のブロック単位
基本的なメソッド定義
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 が出力される
}
}注意: メソッドは main メソッドと同じクラス内に定義します。定義の順序は問いません (main の後でも前でも OK)。
引数をとるメソッド
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
}
}戻り値があるメソッド
public class Main {
static int addOne(int a) {
return a + 1;
}
public static void main(String[] args) {
int two = addOne(1);
System.out.println(two); // 2
System.out.println(addOne(1) + 1); // 3
}
}return の特性
return はメソッドをその場で終了させます:
static int myMin(int a, int b) {
if (a < b) {
return a;
} else {
return b;
}
}早期リターン:
static void printIfSeven(int a) {
if (a == 7) {
System.out.println("a is 7");
return; // ここでメソッド終了
}
System.out.println("a is not 7");
}スコープ (変数の有効範囲)
メソッド内で宣言した変数はそのメソッド内でのみ有効です:
public class Main {
static int addOne(int a) {
int result = a + 1;
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 フィールド (グローバル変数に相当)
static void updateA(int val) {
a = val; // 直接変更できる (global 宣言不要)
}
public static void main(String[] args) {
System.out.println(a); // 0
updateA(1);
System.out.println(a); // 1
}
}配列を引数に渡す
Java では配列はメソッドに参照渡しされます (Python のリストと同じ挙動):
public class Main {
static void addToArray(int[] arr, int val) {
arr[0] += val; // 元の配列が変更される
}
public static void main(String[] args) {
int[] a = {1, 2, 3};
addToArray(a, 10);
System.out.println(a[0]); // 11
}
}メソッドのオーバーロード
同名で引数の型・数が異なるメソッドを複数定義できます (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); // 3
func(1, 10); // 33
}
}再帰メソッド
メソッドが自分自身を呼び出すことができます (詳細は第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)); // 120
}
}練習問題
EX13. 三人兄弟へのプレゼント