トラック
/
Java
Java
/
演習
/
ログ、ログ、ログ!
ログ、ログ、ログ!

ログ、ログ、ログ!

学習演習

はじめに

列挙型

_列挙型_とは、変数があらかじめ定義された定数の集合のいずれかになることを可能にする、特別なデータ型です。 その変数は、あらかじめ定義された値のどれかと一致していなければなりません。 よくある例としては、方位(NORTH、SOUTH、EAST、WESTという値)や曜日などがあります。

定数なので、列挙型のフィールドの名前は大文字で書きます。

列挙型を定義する

Javaプログラミング言語では、enumキーワードを使って列挙型を定義します。 たとえば、曜日の列挙型は次のように書きます。

public enum DayOfWeek {
    SUNDAY,
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY
}

決まった定数の集合を表したいときはいつでも、列挙型を使うとよいでしょう。 太陽系の惑星のような自然な列挙型も含まれますし、コンパイル時にすべての値がわかっているデータの集合も含まれます。たとえば、メニューの選択肢やコマンドラインフラグなどです。

列挙型を使う

上で定義したDayOfWeek列挙型の使い方を、次のコードで見てみましょう。

public class Shop {
    public String getOpeningHours(DayOfWeek dayOfWeek) {
        switch (dayOfWeek) {
            case MONDAY:
            case TUESDAY:
            case WEDNESDAY:
            case THURSDAY:
            case FRIDAY:
                return "9am - 5pm";
            case SATURDAY:
                return "10am - 4pm"
            case SUNDAY:
                return "Closed.";
        }
    }
}
var shop = new Shop();
shop.getOpeningHours(DayOfWeek.WEDNESDAY);
// => "9am - 5pm"

メソッドとフィールドを追加する

Javaの列挙型は、他の言語の同等のものよりもはるかに強力です。 enum宣言は、クラス(_列挙型_と呼ばれます)を定義します。 列挙型のクラス本体には、メソッドやその他のフィールドを含めることができます。

public enum Rating {
    GREAT(5),
    GOOD(4),
    OK(3),
    BAD(2),
    TERRIBLE(1);

    private final int numberOfStars;

    Rating(int numberOfStars) {
        this.numberOfStars = numberOfStars;
    }

    public int getNumberOfStars() {
        return this.numberOfStars;
    }
}

Rating列挙型のメンバーに対してgetNumberOfStarsメソッドを呼び出します。

Rating.GOOD.getNumberOfStars();
// => 4

説明

この演習では、ログ行を処理します。

各ログ行は"[<LVL>]: <MESSAGE>"という形式の文字列です。

ログレベルには次のものがあります:

  • TRC(トレース)
  • DBG(デバッグ)
  • INF(情報)
  • WRN(警告)
  • ERR(エラー)
  • FTL(致命的)

タスクは3つあります。

1. ログレベルを解析する

上記のログレベルに対応する6つの要素を持つLogLevel列挙型を定義しましょう。

  • TRACE
  • DEBUG
  • INFO
  • WARNING
  • ERROR
  • FATAL

次に、ログ行を解析したログレベルを返すLogLine.getLogLevel()メソッドを実装しましょう:

var logLine = new LogLine("[INF]: File deleted");
logLine.getLogLevel();
// => LogLevel.INFO

2. 未知のログレベルに対応する

残念ながら、ときどき未知のログレベルを持つログ行があります。 こうしたログ行を問題なく処理できるようにするため、LogLevel列挙型にUNKNOWN要素を追加しましょう。これは、未知のログレベルを解析するときに返す必要があります:

var logLine = new LogLine("[XYZ]: Overly specific, out of context message");
logLine.getLogLevel();
// => LogLevel.UNKNOWN

3. ログ行を短い形式に変換する

ログ行のログレベルはかなり冗長です。 ログ行を保存するために必要なディスク容量を減らすため、"[<ENCODED_LEVEL>]:<MESSAGE>"という短い形式が考案されました。

エンコードされたログレベルは、ログレベルを数値に単純に対応付けたものです:

  • UNKNOWN - 0
  • TRACE - 1
  • DEBUG - 2
  • INFO - 4
  • WARNING - 5
  • ERROR - 6
  • FATAL - 42

短縮されたログ行の形式を出力するLogLine.getOutputForShortLog()メソッドを実装しましょう:

var logLine = new LogLine("[ERR]: Stack Overflow");
logLine.getOutputForShortLog();
// => "6:Stack Overflow"
GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Java Exercism

ログ、ログ、ログ!を始める準備はできましたか?

Exercismに登録すれば、26個のコンセプト158個の演習、そして本物の人間によるメンタリングとともに、Javaを学んでマスターできます。すべて無料です。