Java Silver (11) 黒本 間違えた問題まとめ
Section 1
5
エントリポイント(mainメソッド)はpublicである必要がある
publicでなくてもいいのはそのメソッドを含んだクラス
8
起動パラメーターは、スペースのみ区切り文字になる
"a"b
は"
が無視されて単にab
と同じ
Section 2
3
数値リテラルにおいて、_
は基本どこでも使える
ただし、必ず数字と数字の間でないといけないので、先頭や末尾、.
, L
, F
, b
, x
の前後は無理
例えば0_123
は8進数のリテラルだが、数字と数字の間なので問題ない
5
変数名などの識別子で$
,_
以外の記号は基本使えない
基本的にUnicode文字なら使えるが、構文で使われる記号は使えないので
あと数字から始まるのはダメ
13
凡ミス、数えられなかったらしい
indexは、begin: inclusive, end: exclusiveの半開区間
endがinclusiveだとclosedとメソッド名などにつけて閉区間と明記する
14
String::replace
は全ての一致した文字列を置き換える
String::replaceAll
との違いは正規表現を使えるかどうか(~Allは使える)
17
String::concat
, StringBuilder::append
19
null + "a"
はぬるぽにならない
20
StringBuilder::capacity
は初期文字数 + 16
Javadocに明記してある
The initial capacity of the string builder is 16 plus the length of the string argument.
21
凡ミス、reverseを読み落としたらしい
Section 3
1
代入演算子は計算が終わってから値を返す…ように見える
実際は右側から処理されるからそうなるだけ
int a = 5;
int b = 5 + (a += 3); // かっこ必須
System.out.println(b); // 13
3
数値のダウンキャスト(?)はコンパイルエラーになる
ただし、int からでかつ、対象の型の範囲内なら問題ない
byte
: -128~127 = -2^7~2^7-1 (signed 8 bit)
short
: -32768~32767 = -2^15~2^15-1 (signed 16 bit)
long -> int, double -> float は範囲内でもダメということ
4
計算ミス…?
インクリメント演算子は、後置の場合値を返してから1増やし、前置の場合1増やしてから値を返す
演算子のある位置でインクリメントすると考えればよい
10
Object::equals
の引数はObject
!!!
14
String::intern
はコンスタントプールから返すメソッド
18
else if
は間で改行できない
改行すると、else
ブロックの中にif
があるのと同じになる
19
switch
文の条件に使えるのは、int
以下の整数型とそのラッパー、あとchar
とString
、Enum
long
は使えない、これはパフォーマンス的な理由だったはず
float
、double
は浮動小数点数で誤差があるので、boolean
はif使えばいいので使えない
20
case値に指定できるのは条件と同じかcompatibleな型、またfinal
である必要がある
effectively finalではダメ
Section 4
8
for文の更新文(最後のやつ)は,
で複数列挙できる
12
String[] arr = { "a", "b", "c" };
for (var s : arr) {
s = "";
}
System.out.println(Arrays.toString(arr));
// abc
拡張for文での変数は配列の参照先を持つだけで配列を直接変更できるわけではない
以下と同じ
for (var i = 0; i < arr.length; i++) {
var s = arr[i];
s = "";
}
内部的にIterator
が用いられているからだと思う
13
do-while文は最初に1度のみwhile文の中を実行しているだけ
14
問題文勘違いしただけ
16
ラベル結構色んなものにつけれるらしい
変数宣言以外大体つけれそう?
17
どうやら不等号の向きが読めないらしい
Section 5
2
int[] a;
int b[];
多次元配列の場合これらを混ぜて書ける
3
型を表す[]
に数は書けない
4
配列の生成について
int以下の整数型のみlength
に指定できる (char可, float, double, long不可)
負の数の場合、NegativeArraySizeException
型は次元が合っている必要がある(Object[]
の場合配列を含められるので適当でもコンパイルは通る)
var a[]
はダメ
5
配列の要素が初期化されてないからぬるぽ
7
new int[] {}
が基本で、{}
に省略できるのは宣言と同時のときだけ
またこの時要素数は指定できない
Section 6
15
到達不可能な文があるとコンパイルエラー
16
メソッド名と引数の型/順番が同じものをオーバーロードと呼ぶ
戻り値の型が違うだけだとコンパイルエラーになるしオーバーロードとは呼ばない
また、全く同じメソッドもオーバーロードとは呼ばない、そりゃそう
18
アクセス修飾子が違ってもオーバーロードではない
20
クラス名と同じメソッドを定義した場合、コンパイルエラーにはならず普通に動く
21
イニシャライザは、スーパーコンストラクタの後、コンストラクタの前に実行される
22
変数がstatic
なの気づかなかった…
27
protected
は他のパッケージから(継承してなければ)アクセスできない、当たり前
28
カプセル化はアクセッサーメソッドのアクセス修飾子関係ない
Section 7
Section 8
3
ラムダ式のスコープはそれを含むブロックと同じ
匿名クラスとは違うところ
4
effectively final でないローカル変数はラムダ式の中で使えない
Section 10
2
Comparator
について
compare(T o1, T o2)
は、o1 -> o2 の場合は負、o2 -> o1 の場合は正を返す
o1 - o2
を返すと覚えると楽
3
Comparable
のcompareTo(T o)
について
o1.compareTo(o2) == Comparator.naturalOrder().compare(o1, o2)
4
Character
にどんなメソッドがあるか覚える
10
原型(Raw type)でもダイヤモンド演算子を使える
11
List.remove(Object o)
はListに含まれる最初の同値の要素を削除する
これはList
インターフェースのメソッド契約に記載されているもの
Removes the first occurrence of the specified element from this list, if it is present (optional operation).
https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/util/List.html#remove(java.lang.Object)
12
拡張for文の中でListから削除した場合、後の要素が繰り上がる
13
拡張for文でListから要素を削除した後にアクセスするとConcurrentModificationException
を吐く
以下スタックトレース
Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
at io.github.risu729.test.Main.main(Main.java:13)
16
Arrays::compare
は辞書順、Arrays::mismatch
が返すindexの要素同士をcompare
する