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

您可以使用enum或声明在启动时初始化的 Country 的单个静态实例,例如:

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 回答
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);
    }
}

这样,当您第一次构造国家对象时,它只被调用一次。

另请注意,您不需要if声明:contains返回布尔值,因此您可以直接返回。

编辑:刚刚注意到你的第二个代码段。Countries不要每次都创建一个新对象,只需创建一次,然后持久化它。

或者,您可以将此设为静态 ( private static Set...,static {而不是public Countries() {and public static boolean...)

然后你就像调用它Countries.isCountryPresent(SomeCountry);而不实例化一个新对象。

于 2013-01-17T22:32:23.670 回答