大変お世話になっております。
反逆する武士
uematu tubasaです。
初回投稿日時:2023年7月2日(令和5年7月2日)
Mathクラスのメソッド
Mathクラスのメソッドが試験において出題される。
java.lang.Mathは、数値の累乗や平方根といった基本的な数値処理をするためのクラスです。
累乗をするためには、Mathクラスのpowメソッドを使用、平方根(√)をするためには、sqrtメソッドを使用します。
2という数値を3乗した場合の記述方法⇒Math.pow(2, 3);
Comparatorメソッドの問題
何らかの要素を並べ替えることを簡単にするためのcompareメソッドになります。
java.util.ArrayListクラスなどのコレクションを扱うクラスは、Comparatorが戻す値によって、要素を入れ替えるのかを判断します。
1を返却された場合、第二引数を前にする(入れ替える)
-1を返却された場合、第一引数を前にする(入れ替えない)
0を返却された場合、並び順を変更しない(入れ替えない)
まずはこれを覚える必要です。
【問題】以下のプログラムを実行し、「3」「2」「1」と表示するためには3行目にどのようなコードを書けばいいのか。
public static void main(String[] args){
List<Integer> list = Array.asList(new Integer[] {1,2,3});
???
for(Integer num : list){
System.out.println(num);
}
}
【回答】list.sort( (a, b) -> -a.compareTo(b) );
【解説】
java.util.Listインターフェースが持つsortメソッドは、コレクション内の要素を順番に並べ替えるメソッドになります。
標準なリストの並べ替え順を「自然順」と言います。
基本的には、1が返却されて、入れ替えが発生したら、自然順になります。
問題においては、その自然順の逆、いわゆる降順を実現するため、compareToのメソッドの戻り値を反転させるため、-を付与します。
ArrayListのremove問題
【問題】以下のプログラムをコンパイルし、実行したときの結果はどうなりますか。
public static void main(String[] args){
ArrayList<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
for(String str : list){
if("B".equals(str)){
list.remove(str);
} else {
System.out.println(str);
}
}
}
【回答】「A」と表示される。
removeメソッドはリストから要素を削除するメソッドです。
リストから要素を削除した場合、後ろの要素が繰り上がります。
問題文においては、「A」「B」「C」の3つの文字列をリストに追加し、その後、拡張for文で1つずつ取り出しています。
リストの要素は追加された順番通りに並ぶため、最初に取り出されるのは「A」です。
拡張for文の内部に記述されているif文により、removeメソッドは「B」のときだけ実行される。
したがって、まずはコンソールに「A」が表示されます。
つぎに、「B」が削除され、Listの中身としては「C」が繰り上がります。
拡張for文としては、3つ目の要素が存在しないという判定になるので、処理が拡張for文から抜けます。
その結果、上記のソースコードをコンパイルして実行した場合「A」がコンソール出力されるだけとなります。
ArrayListのremoveで実行時に例外発生問題
【問題】以下のプログラムをコンパイルし、実行したときの結果はどうなりますか。
public static void main(String[] args){
ArrayList<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
for(String str : list){
if("C".equals(str)){
list.remove(str);
}
}
for(String str : list){
System.out.println(str);
}
}
【回答】実行時に例外がスローされる。
【解説】ArrayListはスレッドセーフなクラスではありません。
したがって、ArrayListをremoveした後に繰り返し処理で読み出すと、例外が発生します。
ConcurrentModificationExceptionの発生になります。
ちなみに、1つ目の拡張for文と2つ目の拡張for文が存在しますが、1つ目の拡張for文で例外発生します。
つまり、removeした後に、さらに読み出す対象が存在する場合は例外発生ということです。
固定長リストの問題
リストは要素を順番に並べて管理するデータ構造で、Javaではjava.util.Listインターフェースとその実装クラスを使って扱います。
代表例はjava.util.ArrayListクラスです。
このクラスは一般的に「動的配列」とも呼ばれます。
要素数を変えられない配列とは違い、要素数を動的に増やせることが特徴です。
反対に固定長のリストを作る方法が2つあります。
1、ArrayListのasListメソッドを使用し、配列からリストのインスタンスを生成する方法。
⇒例)Integer[] array = {1, 2, 3};
var list = Array.asList(array);
2、Listインターフェースのofメソッドを使用する方法。
⇒例)var list = List.of(1, 2, 3);
ちなみに、固定長リストに対して、addすると例外が発生してしまう。
UnsupportedOperationExceptionが発生することになる。
Mapの問題
【問題】以下のプログラムをコンパイルし、実行したときの結果はどうなりますか。
※Itemクラスのソースコードは省略。
public static void main(String[] args){
Map<Integer, Item> map = new HashMap<Integer, Item>();
map.put(1, new Item(1, "A"));
map.put(2, new Item(2, "A"));
map.put(3, new Item(3, "A"));
map.put(1, new Item(1, "A"));
map.put(null, new Item(0, "default"));
System.out.println(map.size());
}
【解説」コンソールに4が出力される。
Mapの特徴は、バリューの重複は許容し、キーの重複は許さないということです。
したがって、6行目は許容されません。
ちなみに7行目は許容されます。
Mapに格納される要素の数は4つになります。
その結果、コンソールに出力されるmap.size()は4です。
以上です。