戦国IT - 情報処理技術者試験の過去問対策サイト
ブログお知らせお問い合わせ料金プラン

基本情報技術者 2016年 春期 午後 問11


次のJavaプログラムの説明及びプログラムを読んで、設問1,2に答えよ。

〔プログラムの説明〕  “すべきこと”(以下、ToDoという)を管理するプログラムである。 (1) クラスToDoはToDoを表すクラスであり、コンストラクタで主題、期限、重要度を指定する。期限は、年月日を表す8桁又は年月日時分を表す12桁の数字から成る文字列(以下、日時という)であり、例えば、2016年4月16日を表す文字列は“20160416”、2016年4月16日午後1時0分を表す文字列は“201604161300”である。ここで、日時に誤りはないものとする。  主題、期限、重要度を取得する各メソッドと、状態を設定及び取得するメソッド、ToDoを識別するフィールドidをもつ。  列挙PriorityはToDoの重要度を表す列挙であり、重要度が低い順にLOW、MIDDLE、HIGHである。  列挙StateはToDoの状態を表す列挙であり、NOT_YET_STARTEDは未着手、STARTEDは着手済み、DONEは完了を表す。 (2) クラスToDoListはToDoのリストを保持するクラスである。  リスト中に、フィールドidの値が同じToDoを複数個含まないことを保証する。  ToDoを追加するメソッドaddと、ToDoの更新を行うメソッドupdate、条件に合うToDoのリストを返すメソッドselectをもつ。  メソッドaddの引数に、既にリストに保持されているToDoを指定したとき、及びメソッドupdateの引数に、リストにないToDoを指定したときは何もしない。  メソッドselectの引数には、条件を0個以上指定できる。条件を指定したときは、全ての条件に合致するToDoから成るリストを返す。条件を指定しないときは、保持する全てのToDoから成るリストを返す。 (3) インタフェースConditionは、ToDoを選択する際の条件を表すクラスが実装するインタフェースである。メソッドtestは条件に合致するときにtrueを返す。 (4) クラスToDoListTesterは、テスト用のクラスである。
基本情報技術者試験(平成28年 午後 問11 プログラム1)
基本情報技術者試験(平成28年 午後 問11 プログラム2)
基本情報技術者試験(平成28年 午後 問11 プログラム3)
基本情報技術者試験(平成28年 午後 問11 プログラム4)

設問1:

問題文を見る
 プログラム中のに入れる正しい答えを、解答群の中から選べ。   aに関する解答群  ア:((ToDo) o).id.equals(id)  イ:(ToDo) o.id.equals(id)  ウ:id.equals(id)  エ:o.id.equals(id)   bに関する解答群  ア:!todoList.contains(todo)  イ:!todoList.isEmpty()  ウ:todoList.contains(todo)  エ:todoList.isEmpty()   cに関する解答群  ア:!= -1  イ:< todoList.size()  ウ:== -1  エ:>= todoList.size()   dに関する解答群  ア:boolean selected = false  イ:boolean selected = true  ウ:int selected = 0  エ:int selected = todoList.size()   eに関する解答群  ア:+=  イ:=  ウ:==  エ:|=

模範解答

a:ア、b:ア、c:ア、d:イ、e:イ

解説

解答の導き方

この問題では、ToDoを「どのToDoか」を見分ける方法と、条件に合うToDoを選ぶ方法を考えます。特に、リスト内での検索には、ToDoのidが使われます。
a:ToDoが同じかどうかの判定
プログラムの説明では、ToDoを識別するフィールドとしてidをもつとあります。したがって、主題や期限などが同じかではなく、idが同じかどうかで同じToDoと判定する必要があります。
equalsの引数oは、どの種類のデータも受け取れる型です。そのため、まずoがToDoであることを確かめてから、ToDoに変換してidを比較します。該当する形は ((ToDo) o).id.equals(id) です。
ここでは、&&の左側がfalseなら右側を評価しません。したがって、oがToDoでない場合に、ToDoへの変換やidの参照を行わずに済みます。
b:既にリストにあるToDoを追加しない
プログラムの説明には、リスト中にidが同じToDoを複数個含まないとあります。
リストのcontainsは、指定したToDoと同じものがリストにあるかを調べます。この判定には、先ほどのequalsが使われます。ですから、まだリストにない場合だけ追加すればよく、条件は !todoList.contains(todo) です。!は「〜ではない」という意味です。
追加時にはnew ToDo(todo)でコピーを作っていますが、コピー用のコンストラクタは元のToDoと同じidを引き継ぎます。そのため、コピーしても同じToDoとして判定できます。
c:リストにあるToDoだけを更新する
indexOfは、指定したToDoがリストの何番目にあるかを返します。見つからない場合は-1を返します。
そのため、更新してよいのは、検索結果が-1ではない場合です。条件は != -1 です。見つからないToDoを更新しようとすると、リストの存在しない位置を置き換えることになってしまいます。
d:条件が0個のときも全て選ぶ
selectでは、渡された条件を全て満たすToDoを選びます。ところが、条件が0個のときは、プログラムの説明どおり保持する全てのToDoを返さなければなりません。
そこで、条件の確認を始める時点では「選択できる」としておきます。条件が0個なら、その値を変える処理がないため、全てのToDoが選ばれます。したがって、dには boolean selected = true が入ります。
e:条件の判定結果をselectedに入れる
条件を1つずつ確認するときは、条件の判定結果をselectedに代入します。条件を満たせばtrue、満たさなければfalseになります。
falseになった場合は、直後のif文でループを抜けます。したがって、次の条件によって結果が上書きされることはありません。eに入るのは、値を代入する = です。
プログラム4の実行結果を確かめる
list.select()は条件を指定していないので、リスト内の全てのToDoを返します。返されたToDoはコピーですが、元と同じidをもっています。各コピーの状態をSTARTEDに変更してupdateすると、idによってリスト内の対応するToDoが見つかり、変更後のToDoに置き換わります。
一方、PC購入のToDoは新しいidをもつため、リスト内にはありません。indexOfの結果は-1となり、updateでは何も行われません。
最後のselectでは、次の2つの条件を同時に満たすToDoを選びます。
  • 期限が20160501より前であること
  • 重要度がHIGHであること
期限の文字列は年、月、日の順に並んでいるため、この問題の比較では、20160501より前の日付を文字列の比較で判定できます。条件に合うのは、メール送信と報告書作成です。状態はいずれも、それまでの更新でSTARTEDになっています。

誤りやすいポイント

  • equalsで主題や期限を比べるのではなく、ToDoを識別するidを比べます。
  • containsは、単に同じ実体があるかだけでなく、equalsによる判定で同じToDoがあるかを調べます。
  • indexOfで見つからないときの値は-1です。リストの要素数と比較するのではなく、-1かどうかを確認します。
  • selectedをfalseで初期化すると、条件が0個の場合に全てのToDoを選べません。
  • eの位置では、条件判定の結果を代入します。==は値の比較なので、ここでは使いません。
  • updateに指定したToDoがリストにない場合は、追加ではなく何もしません。

FAQ

Q: 条件が複数あるとき、なぜselectedに条件の判定結果を代入するだけでよいのですか?
A: 条件を満たさなかった時点でループを抜けるからです。そこまでの条件を全て満たした場合だけ次の条件へ進み、どれか1つでも満たさなければ選ばれない仕組みです。
Q: selectで返したToDoの状態を変えただけでは、リストの中身も変わりますか?
A: このプログラムでは、selectの結果にToDoのコピーを追加しています。そのため、返されたコピーの状態を変更しただけでは、リスト内のToDoは変わりません。変更を反映するには、updateを呼び出します。
Q: 期限を文字列のまま比較できるのはなぜですか?
A: この問題では、年月日が年、月、日の順に並ぶ形式です。そのため、期限の文字列を順に比較すると、日付の前後関係を判定できます。

関連キーワード: equalsメソッド、リスト検索、可変長引数、論理積、文字列比較

解説を読んでも分からないところは、AIに質問できます。 この問題の本文と解説をふまえて答えます。

この設問をAIに質問する

クイズモードで開きます(AIへの質問は無料の会員登録で使えます)

 プログラム4の実行結果を図1に示す。に入れる正しい答えを、解答群の中から選べ。
基本情報技術者試験(平成28年 午後 問11 図1)
f, gに関する解答群  ア:主題: PC購入, 期限: 20160531, 優先度: HIGH  イ:主題: 会議室予約, 期限: 201605301200, 優先度: HIGH  ウ:主題: チケット購入, 期限: 20160430, 優先度: MIDDLE  エ:主題: 報告書作成, 期限: 20160428, 優先度: HIGH  オ:主題: ホテル予約, 期限: 20160420, 優先度: LOW  カ:主題: メール送信, 期限: 201604181500, 優先度: HIGH

模範解答

f:カ、g:エ

解説

解答の導き方

  1. まず、リストに入るToDoを確認します。
    プログラムでは、最初に「メール送信」「ホテル予約」「チケット購入」「報告書作成」「会議室予約」の5件を追加しています。
    その後に「PC購入」を引数にしてupdateを呼び出していますが、updateは新しいToDoを追加するメソッドではありません。リスト内に同じidのToDoがある場合に、その内容を更新します。「PC購入」は新しく作られたToDoなので、リスト内のToDoとidが一致せず、更新されません。したがって、この時点でもリストは最初の5件のままです。
  2. 次に、5件の状態がどうなるかを追います。
    引数を指定しないselect()は、リストに保持している全てのToDoを返します。ただし、返されるのはリスト内のToDoそのものではなくコピーです。
    ループ内では、そのコピーの状態をSTARTEDに変更し、続けてupdateを呼び出しています。コピーは元のToDoと同じidを持つので、updateによってリスト内の該当するToDoも更新されます。この処理を5件全てに行うため、リスト内の5件の状態はすべてSTARTEDになります。
  3. 最後に、condition1とcondition2の両方を満たすToDoを探します。
    問題文では、条件を複数指定した場合、「全ての条件に合致するToDo」を返すと説明されています。
    • condition1は、期限が「20160501」より前であることを調べます。
    • condition2は、重要度がHIGHであることを調べます。
    期限は年、月、日、必要に応じて時分の順に並んでいます。そのため、この問題では期限の文字列を比較することで、日付の前後を判定できます。
    主題期限期限が「20160501」より前か重要度がHIGHか両方に合致するか
    メール送信201604181500はいはいはい
    ホテル予約20160420はいいいえいいえ
    チケット購入20160430はいいいえいいえ
    報告書作成20160428はいはいはい
    会議室予約201605301200いいえはいいいえ
    条件を両方満たすのは「メール送信」と「報告書作成」です。選択結果はリストに入っている順に処理されるため、図1の上段のfは「メール送信」に当たるカ、下段のgは「報告書作成」に当たるエです。

誤りやすいポイント

  • updateを、リストにないToDoも追加するメソッドだと考えないようにします。「PC購入」はリストに追加されません。
  • select()が返すToDoはコピーです。コピーの状態を変更しただけではリスト内の状態は変わらず、updateを呼び出して反映する必要があります。
  • condition1とcondition2は、どちらか一方を満たせばよいのではありません。両方を満たすToDoだけが選ばれます。
  • 条件に合うToDoを期限順に並べ替える処理はありません。表示される順番は、リストに追加された順です。

FAQ

Q: 「メール送信」の期限は12桁ですが、「20160501」と比較できますか?
A: 比較できます。「メール送信」の期限は「201604」から始まり、「201605」より前の日付です。そのため、期限の条件を満たします。
Q: select()で取得したToDoの状態を変えた後、なぜupdateが必要なのですか?
A: select()が返すのは、リスト内のToDoのコピーだからです。コピーで行った変更をリストに反映するために、updateを呼び出します。
Q: 重要度がHIGHなら、期限に関係なく表示されますか?
A: いいえ。期限の条件と重要度の条件の両方を満たす必要があります。「会議室予約」は重要度がHIGHですが、期限が「20160501」より後なので選ばれません。

関連キーワード: equalsメソッド、リスト検索、オブジェクトのコピー、文字列比較、論理積

解説を読んでも分からないところは、AIに質問できます。 この問題の本文と解説をふまえて答えます。

この設問をAIに質問する

クイズモードで開きます(AIへの質問は無料の会員登録で使えます)

戦国ITクイズ機能

\ せっかくなら /

基本情報技術者を
クイズ形式で学習しませんか?

クイズ画面へ遷移する→

すぐに利用可能!

©︎2026 情報処理技術者試験対策アプリ

このサイトについてブログプライバシーポリシー利用規約特商法表記開発者について