サンプルコード(printf)
Printf.java
import java.util.Date;
class Printf {
public static void main(String[] args) {
// 九九の表を表示
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= 9; j++) {
//
System.out.printf("%3d", i * j);
}
System.out.println();
}
System.out.println();
Date date = new Date();
// 最小桁幅が3桁の10進整数
System.out.printf("your balance: $%3d\n", 1);
// ,(カンマ)区切りの10進整数
System.out.printf("your deposit: ¥%,d\n", 1234567);
// 最小桁幅が7桁,小数点第2位までの小数
System.out.printf("your BMI: %7.2f\n", 19.37593);
// 足りない桁を"0"で埋めた, 最小桁幅が5桁の10進整数
System.out.printf("%05d\n", 351);
// 現在の日付
System.out.printf("Today is %tF.\n", date);
}
}
実行結果
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
your balance: $ 1
your deposit: ¥1,234,567
your BMI: 19.38
00351
Today is 2021-06-25.
printf()メソッド
参考1: Format String Syntax
参考2: 日付の表示
PrintStream
クラスで定義される、出力フォーマット
を指定して出力ストリーム
に文字列を書き込む(=コンソール
に出力する)メソッド。
出力フォーマット
は以下のように記述する。なお、ここではオプション
は[...]
で表すこととする。
%[値に挿入される記号(フラグ)][最小桁幅]変換文字
また、出力する際に改行を行う場合は、出力フォーマット
の末尾に改行文字\n
を挿入する。
定義
PrintStream PrintStream.printf(String format, Object args)
// パラメータ
// format: 「出力フォーマット」を表す文字列
// args: 参照する値
サンプルコード(キャスト演算子)
Cast.java
import java.util.Scanner;
class Cast {
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
System.out.print("int x: "); int x = stdIn.nextInt();
System.out.print("int y: "); int y = stdIn.nextInt();
// 右辺はint型同士の演算 -> 結果はint型
double ave = (x + y) / 2;
System.out.println("average without casting: " + ave);
// 右辺はint型とdouble型の演算 -> 暗黙的な二項数値昇格(=型変換)によって結果がdouble型に変換
ave = (x + y) / 2.0;
System.out.println("average with implicitl binary numerical promotion: " + ave);
// 右辺はdouble型にキャストされたint型同士の演算 -> 結果はdouble型
ave = (double) (x + y) / 2;
System.out.println("average with cast operator: " + ave);
}
}
実行結果
int x: 7
int y: 8
average without casting: 7.0
average with implicitl binary numerical promotion: 7.5
average with cast operator: 7.5
二項数値昇格
表現範囲の異なる型同士の演算時に暗黙的に行われる、表現範囲の狭い型の拡大変換
。
キャスト演算子
(<T>)
で表される、演算結果を指定した型
に変換する演算子。
サンプルコード(丸め誤差への対策)
CalcError.java
class CalcError {
public static void main(String[] args) {
float sum = 0.0F;
// float型による加算
for (float x = 0.0F;x <= 1.0F; x += 0.001F) {
sum += x;
}
System.out.println("addition with float: " + sum);
sum = 0.0F;
// int型による加算
for (int y = 0; y <= 1000; y++) {
float z = (float) y / 1000;
sum += z;
}
System.out.println("addition with int: " + sum);
}
}
実行結果
addition with float: 500.49667
addition with int: 500.49997 // <- int型を利用した方が誤差が小さい
拡張表記(escape sequence)
拡張表記 | 内容 | Unicode拡張表記 |
---|---|---|
\b |
後退(backspace) | \u0008 |
\f |
書式送り(form feed) | \u000c |
\n |
改行(new line) | \u000a |
\r |
復帰(carriage return) | \u000d |
\t |
水平タブ(horizontal tab) | \u0009 |
\<記号> |
エスケープ文字(escape) | |
\o |
8進数(octal) | |
\h |
16進数(hexadecimal) |
サンプルコード(拡張for文, for-in文)
AdvancedFor.java
class AdvancedFor {
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5};
int sum = 0;
// for-in文
// -> iはint型配列aの各構成要素の値
for (int i : a) {
sum += i;
}
System.out.println("sum is " + sum + ".");
}
}
サンプルコード(スコープ)
Scope.java
class Scope {
// フィールド
static int x = 700;
// フィールドxを出力するメソッド
static void printX() {
System.out.println("field x: " + x);
}
public static void main(String[] args) {
// フィールドxの出力
System.out.println("field x: " + x);
// 局所変数x
// <- フィールドと有効範囲(=スコープ)が異なるため同名での宣言が可能
int x = 800;
// 局所変数xの出力
System.out.println("local variable x: " + x);
// Scopeクラスのフィールドxの明示的出力
System.out.println("field in class Scope x: " + Scope.x);
// フィールドxの出力
printX();
}
}
実行結果
field x: 700
local variable x: 800
field in class Scope x: 700
field x: 700
サンプルコード(ビット演算)
Bits.java
import java.util.Scanner;
class Bits {
// int型のビット構成を出力するメソッド
static void printBits(int x) {
for (int i = 31; i >= 0; i--) {
// 大きい位のビットから、1とのビット論理積を求める
System.out.print( ((x >>> i & 1) == 1) ? '1' : '0' );
}
}
// int型のビット構成に含まれる、"1"であるビットの総数を返却するメソッド
// <- 複数のアルゴリズムが存在
static int count1InBits(int x) {
// "1"であるビットの総数
int count = 0;
while (x != 0) {
// 1とのビット論理積が1である場合の処理
if ( (x & 1) == 1 ) count++;
// 計算後は1ビット右方向に論理シフトしたものを再代入
// ⇔ x = x >>> 1
x >>>= 1;
}
// カウントした総数を返却
return count;
}
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
System.out.print("int: "); int x = stdIn.nextInt();
System.out.print("bit: ");
printBits(x);
System.out.println( "\n1 in bit: " + count1InBits(x) );
}
}
実行結果
int: 93
bit: 00000000000000000000000001011101
1 in bit: 5
ビット計算で用いられる論理演算子
記号 | 名称 | 内容 |
---|---|---|
& |
ビット論理積演算子(bitwise and operator) | AND |
| | ビット論理和演算子(bitwise or operator) | OR |
^ |
ビット排他的論理和演算子(bitwise exclusive or operator) |
EOR (XOR ) |
~ |
ビット補数演算子(bitwise complement operator) | - |
シフト演算子(shift operator)
利用例 | 内容 |
---|---|
x << n |
左方向へn ビットシフト |
x >> n |
右方向へn ビット算術シフト
|
x >>> n |
右方向へn ビット論理シフト
|
算術シフトと論理シフト
算術シフト(arithmetic shift)
は最上位ビットを符号ビット
とする。
論理シフト(logical shift)
は全ビットを値
とする。
サンプルコード(アクセス修飾子と静的/動的メソッド)
Accessibility.java
import java.util.Scanner;
// publicなクラスはファイル名と同名でなければならないため、publicキーワードは付与しない
class Day {
// 外部クラスに公開しないprivateなフィールド
// <- <Dayオブジェクト>.<フィールド>でのアクセス不可
// => アクセサ(ゲッタ/セッタ)を用いてフィールドにアクセスしなければならない
private int year;
private int month;
private int date;
// クラスコンストラクタ
// -> コンストラクタは通常外部クラスから利用するためpublicキーワードを付与
public Day(int year, int month, int date) {
// this参照によってフィールドと同名な仮引数を区別
this.year = year;
this.month = month;
this.date = date;
}
// ゲッタ(=アクセサ)
// <- privateなフィールドを外部クラスから間接的に参照
public int getYear() { return year; }
public int getMonth() { return month; }
public int getDate() { return date; }
// セッタ(=アクセサ)
// <- privateなフィールドを外部クラスから間接的に設定
public void setYear(int year) { this.year = year; }
public void setMonth(int month) { this.month = month; }
public void setDate(int date) { this.date = date; }
// 外部クラスから利用可能(public)な静的メソッド(=クラスメソッド)
// -> 「クラス」が所有するメソッド
// => 引数によって結果は異なるが、インスタンスによって結果が異なることはない
public static boolean isLeap(int y) {
return y % 4 == 0 && y % 100 != 0 || y % 400 == 0;
}
// 外部クラスから利用可能(public)な動的メソッド(=インスタンスメソッド)
// -> 「インスタンス(=オブジェクト)」が所有するメソッド
// => インスタンスがもつフィールドの値を利用するため、インスタンスによって結果が異なる
public boolean isLeap() {
// 同名であるクラスメソッドisLeap(y:)を利用
return isLeap(year);
}
// ツェラーの公式を用いた曜日を算出する動的メソッド(=インスタンスメソッド)
public int dayOfWeek() {
int y = year;
int m = month;
if (m == 1 || m == 2) {
y--;
m += 12;
}
return (y + y / 4 - y / 100 + y / 400 + (13 * m + 8) / 5 + date) % 7;
}
}
// publicなクラスはファイル名と同名でなければならないため、publicキーワードは付与しない
class DayComparator {
// 外部クラスに公開しないprivateな静的メソッド(=クラスメソッド)
// -> プログラムの中でDayComparatorインスタンス(=オブジェクト)は生成されないため、 静的メソッドで宣言
private static boolean compRef(Day d1, Day d2) {
// 「参照先」が同じであればtrueを返却
return (d1 == d2);
}
// 外部クラスに公開しないprivateな静的メソッド(=クラスメソッド)
// -> プログラムの中でDayComparatorインスタンス(=オブジェクト)は生成されないため、 静的メソッドで宣言
private static boolean compVal(Day d1, Day d2) {
// 「値」が同じであればtrueを返却
return d1.getYear() == d2.getYear() &&
d1.getMonth() == d2.getMonth() &&
d1.getDate() == d2.getDate();
}
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
// privateキーワードを付与すると"only final is permitted"とエラーが出力
// <- main()メソッド内で宣言される局所変数(=ローカル変数)であり、そもそもprivate/publicの概念がないため
// 局所変数に付与できるキーワードは"final"のみ
int y, m, d;
System.out.println("Day A: ");
System.out.print("Year: "); y = stdIn.nextInt();
System.out.print("Month: "); m = stdIn.nextInt();
System.out.print("Date: "); d = stdIn.nextInt();
Day dayA = new Day(y, m, d);
System.out.println("Day B: ");
System.out.print("Year: "); y = stdIn.nextInt();
System.out.print("Month: "); m = stdIn.nextInt();
System.out.print("Date: "); d = stdIn.nextInt();
Day dayB = new Day(y, m, d);
// 静的メソッド(=クラスメソッド)の呼び出し
// -> "<クラス名>.~" で呼び出す
System.out.println("Day B is " + (Day.isLeap(y) ? "" : "not ") + "leap year.");
// 動的メソッド(=インスタンスメソッド)の呼び出し
// -> "<クラス型変数(=インスタンス)名>.~" で呼び出す
System.out.println("Day B is " + (dayB.isLeap() ? "" : "not ") + "leap year.");
if ( compRef(dayA, dayB) ) {
System.out.println("Reference is the same.");
}
else {
System.out.println("Reference is different.");
}
if ( compVal(dayA, dayB) ) {
System.out.println("Value is the same.");
}
else {
System.out.println("Value is different.");
}
}
}
実行結果
Day A:
Year: 2021
Month: 6
Date: 25
Day B:
Year: 2021
Month: 6
Date: 25
Day B is not leap year.
Day B is not leap year.
Reference is different.
Value is the same.
アクセス修飾子
修飾子 | 同一クラス | 同一パッケージ | サブクラス | すべて |
---|---|---|---|---|
public (公開) |
o | o | o | o |
protected (限定公開) |
o | o | o | x |
(なし) (デフォルト) |
o | o | x | x |
private (非公開) |
o | x | x | x |
動的メソッドと静的メソッド
static
キーワードを付与しない動的メソッド
は、個々のインスタンス
によって結果が異なる処理。
static
キーワードを付与する静的メソッド
は、個々のインスタンス
によらない結果をもたらす処理またはクラス全体に関係する処理。
なお、static
キーワードはシグネチャ
に該当するため、同名での宣言が可能。
動的メソッドと静的メソッド
// 外部クラスから利用可能(public)な静的メソッド(=クラスメソッド)
// -> 「クラス」が所有するメソッド
// => 引数によって結果は異なるが、インスタンスによって結果が異なることはない
public static boolean isLeap(int y) {
return y % 4 == 0 && y % 100 != 0 || y % 400 == 0;
}
// 外部クラスから利用可能(public)な動的メソッド(=インスタンスメソッド)
// -> 「インスタンス(=オブジェクト)」が所有するメソッド
// => インスタンスがもつフィールドの値を利用するため、インスタンスによって結果が異なる
public boolean isLeap() {
// 同名であるクラスメソッドisLeap(y:)を利用
return isLeap(year);
}
// 静的メソッド(=クラスメソッド)の呼び出し
// -> "<クラス名>.~" で呼び出す
System.out.println("Day B is " + (Day.isLeap(y) ? "" : "not ") + "leap year.");
// 動的メソッド(=インスタンスメソッド)の呼び出し
// -> "<クラス型変数(=インスタンス)名>.~" で呼び出す
System.out.println("Day B is " + (dayB.isLeap() ? "" : "not ") + "leap year.");
用語集
用語 | 内容 |
---|---|
ビット(bit) |
binary digit (2進数字)の略称。0 と1 で表現される。 |
2進整数リテラル(binary integer literal) | 冒頭に0b または0B を付与して表現する2進整数。 |
8進整数リテラル(octal integer literal) | 冒頭に0 を付与して2桁以上で表現する8進整数。 |
16進整数リテラル(hexadecimal integer literal) | 冒頭に0x 付与して表現する16進整数。 |
縮小変換(narrowing primitive conversion) | 明示的に行う必要のある、表現範囲の狭い型への変換。 |
拡大変換(widening primitive conversion) | 暗黙的に行われる、表現範囲の広い型への変換。 |
FP厳密(FP-strict) | 演算結果が実行環境に依存しないようにすること。クラス やメソッド にstrictfp キーワードを付与する。※通常の計算では基本的に不要 |
書式送り |
改ページ し、次のページの先頭に移動すること。 |
ガーベジコレクション(garbage collection) | 参照先がnull であるオブジェクトを自動的に解放し、利用可能領域を拡げること。 |
フィールド(field) | クラス内で利用可能な変数。 |
局所変数(local variable) |
ローカル変数 。メソッド内で利用可能な変数。 |
シグネチャ(signature) |
識別子 、仮引数 の個数、仮引数 の型の3つの組み合わせ。 |
カプセル化(encapsulation) | 非公開であるフィールド とフィールド の値を利用するメソッド を連携させること。 |
ユーティリティクラス(utility class) |
クラスメソッド とクラス変数 のみを提供するクラス。 |