SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

クラスを難しく感じるのはなぜ? 例題で学ぶオブジェクト指向

クラスを理解するための例題(2)

例題3:クラスを使うことが有用なケース

 では次の要件を考えてみましょう。

例題3

 クラスの学級委員であるpaiza君は、クラスのみんなに次のような形式でアカウントの情報を送ってもらうよう依頼しました。

名前 年齢 誕生日 出身地

 この情報を扱いやすくするために、年齢が昇順になるようにデータを並び替えることにしました。

 クラスメートの情報が与えられるので、並び替えた後のデータを出力してください。

 入力値は以下のように与えられます。

N
n_1 o_1 b_1 s_1
...
n_N o_N b_N s_N
  • 1行目では、paiza君のクラスの人数Nが与えられます。
  • 続くN行のうちi行目(1 ≦ i ≦ N)では、i番の生徒の名前・年齢・誕生日・出身地を表す整数・文字列n_i ,o_i ,b_i , s_iが順に半角スペース区切りで与えられます。

 また条件は以下のようになっています。

  • 1 ≦ N ≦ 10
  • n_i , b_i (1 ≦ i ≦ N)は1文字以上20文字以下の文字列
  • b_i (1 ≦ i ≦ N)MM/DD形式の文字列(例:1月2日→01/02、12月31日→12/31)
  • 1 ≦ o_i ≦ 100
  • o_i (1 ≦ i ≦ N)は重複することがないことが保証されている。

 期待される出力は以下の形です。

n_1 o_1 b_1 s_1
...
n_N o_N b_N s_N

 各クラスメートの情報を年齢が昇順になるように整列したのち、入力と同様の形式で出力してください。

 この問題の場合、このままの実装方法だと少し困難ですね。

 現状だと、生徒の属性がそれぞれ個別のリストに保存されており、各生徒はそのインデックスで表現されていたため、あるリストを並べ替えてしまった場合、その他のリストがその順序を追従せねばなりません。不可能ではないと思いますが、それぞれの属性をバラバラに保存しておくのは少し問題がありそうです。生徒のデータは生徒ひとりを表すデータ構造にまとめたほうが楽に扱えそうですね。

 では生徒ひとりを表すStudentクラスを作って使ってみましょう。

import java.util.*;
import java.util.stream.*;

public class Main {
    public static void main(String[] args) {

        var sc = new Scanner(System.in);

        IntStream
            .range(0, sc.nextInt())
            .mapToObj(i -> new Student(sc.next(), sc.nextInt(), sc.next(), sc.next()))
            .sorted(Comparator.comparing(Student::getOld))
            .forEach(System.out::println);
    }

    static class Student {

        private String nickname;
        private int old;
        private String birth;
        private String state;

        Student(String nickname, int old, String birth, String state) {
            this.nickname = nickname;
            this.old = old;
            this.birth = birth;
            this.state = state;
        }

        int getOld() {
            return old;
        }

        @Override
        public String toString() {
            return nickname + " " + old + " " + birth + " " + state;
        }
    }
}

 と、このようになります。今回使用しないメソッドについては省略してしまいましたが、いかがでしょうか。入力値を基にStudentインスタンスを作成し、getOldメソッドの結果をもって昇順に並び替え、それらを順番に出力しています。クラスを作成し、それを使用することで比較的理解しやすいコードになったのではないでしょうか。

おわりに

 クラスを自由に作り、使えるようになると、よりわかりやすいコードが記述できるようになります。

 paizaラーニングでは、設計や実装経験の場数を補うため、クラス・構造体を利用すべき場面や処理について理解を深めることを目的としたクラス・構造体メニューという問題集を作成しました。このクラス・構造体メニューの対象者は、クラスの概念・関連する文法は理解していて、小規模なプログラムは書けるようになってきた人や、重めのシミュレーション問題を解けるようになりたい人です。適切なアクセス制限、段階的にクラス・構造体を拡張させていく実装経験を積むことができるような構成になっており、アクセス制限、オーバーロード、継承、などについて実装経験を通じて理解を深めていくことができます。

 この問題集は大きく3つのセクションに分かれています。各セクションは、1つの「ボス問題」といくつかの「準備問題」によって構成されています。

 1つ目のセクションでは「構造体」を、 2つ目のセクションでは「クラス」を扱います。3つ目は、1つ目と2つ目のセクションで学んだことをもとにクラス・構造体の実践問題を解くセクションとなっています。

 クラス・構造体の理解を深めるには、できるだけ多くの問題に触れ、しっかりとした知識を得る必要があります。じっくりと時間をかけて、順番に取り組んでいただけたら嬉しいです。

 解説や解答コード例も参考にぜひ何度もチャレンジして力をつけていってくださいね。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
特集記事連載記事一覧

もっと読む

この記事の著者

長谷 康司(paiza株式会社)(ナガタニ コウジ)

 paizaラーニング部 企画開発グループ グループ長 金融系SIer、チームラボ株式会社での開発エンジニアを経て、学校法人・専門学校HAL東京の講師として3年間Java/PHPなどについて講義を行う。その後ZOZOテクノロジーズの前身である株式会社スタートトゥデイ工務店にて再度開発エンジニアとして...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/14759 2021/09/06 11:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー