1

私には、私を混乱させる基本的な問題があるように思えます。

現在、次の悪い設計があります(私には悪い設計のようです)。次のようなutilクラスがあります。

public class Countries 
{
    public boolean isCountryPresent ( String c )
    {
        //public static final http://en.wikipedia.org/wiki/ISO_3166-1 
        Set<String> myStrings = new HashSet<String>();
        myStrings.add("us"); // Afghanistan
        myStrings.add("af"); // Afghanistan
        myStrings.add("dz"); // Algeria
        myStrings.add("ao"); // Angola
        myStrings.add("az"); // Azerbiajan
        ...


    if ( myStrings.contains(c))
        return true;
    else
        return false;
}

そして、次のようにアイテムの存在を確認します。

Countries co = new Countries ( );
boolean isPresent = co.isCountryPresent( countryISOCode );

しかし、毎回オブジェクトをインスタンス化するとリソースが無駄になると思いますよね? 国データを複数回コンパイルする必要がなく、変更されないことを考えると、これを行うためのより効率的な方法はありますか?

4

3 に答える 3

2

私は通常次のようなことをします:

public class Countries 
{
     private static Set<String> myStrings = null
     public static boolean isCountryPresent ( String c )
     {
        if (myStrings == null) {
            myStrings = initializeSet();
        }

        if ( myStrings.contains(c))
            return true;
        else
            return false;
    }
    private static Set<String> initializeSet() 
    {
        //public static final http://en.wikipedia.org/wiki/ISO_3166-1 
        Set<String> countrySet = new HashSet<String>();
        myStrings.add("us"); // Afghanistan
        myStrings.add("af"); // Afghanistan
        myStrings.add("dz"); // Algeria
        myStrings.add("ao"); // Angola
        myStrings.add("az"); // Azerbiajan
        ...
        return countrySet;
    }
}

このようにして、メソッドが最初に呼び出されたときにセットを初期化しますが、それ以降のすべての呼び出しでは、古い初期化がキャッシュされます。

コンストラクターで宣言することもできますが、私は遅延読み込みアプローチに傾倒する傾向があるため、アプリケーションは起動時にこれらすべてのものが読み込まれるのを待つのではなく、実際に必要なときにオンデマンドで読み込まれます。

また、コメントで述べたように、コード全体で常に同じオブジェクトを再利用している場合を除いて、これはおそらくすべて静的である必要があります。そうでない場合は、インスタンス化する新しいオブジェクトCountriesごとに再実行されます。Countries

于 2013-01-17T22:32:11.127 に答える
1

最も簡単な遷移は、セットをクラス変数に移動し、コンストラクターでインスタンス化することです。

public class Countries 
{
    private Set<String myStrings = new HashSet<String();

    public Countries() {
        //public static final http://en.wikipedia.org/wiki/ISO_3166-1 
        Set<String> myStrings = new HashSet<String>();
        myStrings.add("us"); // Afghanistan
        myStrings.add("af"); // Afghanistan
        myStrings.add("dz"); // Algeria
        myStrings.add("ao"); // Angola
        myStrings.add("az"); // Azerbiajan
        ...
    }

    public boolean isCountryPresent ( String c )
    {
        return myStrings.contains(c);
    }
}

そうすれば、Countriesオブジェクトを最初に作成したときに、一度だけ呼び出されます。

ifまた、ステートメントは必要ないことに注意してくださいcontains。ブール値を返すので、そのまま返すことができます。

編集:2番目のコードセグメントに気づきました。Countries毎回新しいオブジェクトを作成する代わりに、一度作成して永続化します。

または、これを静的にすることもできます(andprivate static Set...static {代わりに)public Countries() {public static boolean...

Countries.isCountryPresent(SomeCountry);次に、新しいオブジェクトをインスタンス化せずに、のように呼び出します。

于 2013-01-17T22:32:23.670 に答える
1

enum起動時に初期化される Countries の単一の静的インスタンスを使用または宣言できます。次に例を示します。

class Countries {
  public final static Countries instance = new Countries();

  private Set<String> myStrings;
  private Countries() {
    myStrings = new HashSet<String>();
    myStrings.add("us");
    ..
  }
}
于 2013-01-17T22:30:14.623 に答える