1

これは単純化された例です。私はこの列挙型宣言を次のように持っています:

public enum ELogLevel {
    None,
    Debug,
    Info,
    Error
}

私は別のクラスにこのコードを持っています:

if ((CLog._logLevel == ELogLevel.Info) || (CLog._logLevel == ELogLevel.Debug) || (CLog._logLevel == ELogLevel.Error)) {
    System.out.println(formatMessage(message));
}

私の質問は、テストを短縮する方法があるかどうかです。理想的には、(これはPascal / Delphiから借用しています)の曲に何かをしたいと思います:

if (CLog._logLevel in [ELogLevel.Info, ELogLevel.Debug, ELogLevel.Error])

比較の長いリストの代わりに。Javaにはそのようなものがありますか、それともそれを達成する方法がありますか?私は簡単な例を使用しています。パターンがあるかどうかを調べて、さらに多くの要素の列挙値リストを使用してこれらのタイプのテストを実行できるようにすることを目的としています。

編集: EnumSetは私が欲しいものに最も近いもののようです。それを実装するナイーブな方法は、次のようなものを介して行われます。

if (EnumSet.of(ELogLevel.Info, ELogLevel.Debug, ELogLevel.Error).contains(CLog._logLevel))

しかし、ベンチマークでは、これは長いif / thenステートメントよりも2桁遅く実行されます。これは、EnumSetが実行されるたびにインスタンス化されるためだと思います。これは非常に頻繁に実行されるコードでのみ問題になりますが、それでも非常に小さな問題です。1億回以上の反復で、ボックスの7ミリ秒と450ミリ秒について話しているからです。いずれにせよ、ごくわずかな時間です。

非常に頻繁に実行されるコードについて私が決めたのは、静的変数でEnumSetを事前にインスタンス化し、そのインスタンスをループで使用することです。これにより、ランタイムが1億回の反復ではるかに快適な9ミリ秒に短縮されます。

勝者がいるようです!迅速な返信をありがとうございます。

4

4 に答える 4

5

必要なのは列挙型セットです

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/EnumSet.html

テストする要素をセットに入れてから、Setメソッドcontains()を使用します。

import java.util.EnumSet;


public class EnumSetExample
{
  enum Level { NONE, DEBUG, INFO, ERROR };

  public static void main(String[] args)
  {
    EnumSet<Level> subset = EnumSet.of(Level.DEBUG, Level.INFO);

    for(Level currentLevel : EnumSet.allOf(Level.class))
    {
      if (subset.contains(currentLevel))
      {
        System.out.println("we have " + currentLevel.toString());
      }
      else
      {
        System.out.println("we don't have " + currentLevel.toString());
      }
    }
  }

}
于 2012-08-10T03:38:52.450 に答える
2

Javaで簡潔にそれを行う方法はありません。最も近い方法は、値をセットにダンプして、contains()を呼び出すことです。あなたの場合、EnumSetがおそらく最も効率的です。ダブルブレースイディオムを使用してセットの初期化を少し短くすることができますが、これには、使用するたびに新しい内部クラスが作成されるという欠点があるため、メモリ使用量がわずかに増加します。

于 2012-08-10T03:39:14.007 に答える
1

一般に、ロギングレベルは整数として実装されます。

public static int LEVEL_NONE  = 0;
public static int LEVEL_DEBUG = 1;
public static int LEVEL_INFO  = 2;
public static int LEVEL_ERROR = 3;

次に、簡単な比較を使用して重大度をテストできます。

if (Clog._loglevel >= LEVEL_DEBUG) {
    // log
}
于 2012-08-10T03:39:57.093 に答える
1

必要なレベルのリストを使用できます。

List<ELogLevel> levels = Lists.newArrayList(ELogLevel.Info,
        ELogLevel.Debug, ELogLevel.Error);
if (levels.contains(CLog._logLevel)) {
    //
}
于 2012-08-10T03:40:34.210 に答える