这是一个好习惯吗? (Class 个字段)

Is this a good practice? (Class fields)

我需要定义相对较多的类别(开始时大约 30 个,我们会添加更多)。考虑这段代码:

public class Category {

    public static final Category DRESS = new Category("Dress");
    public static final Category SKIRT = new Category("Skirt");
    ...

    private static final List<Category> CATEGORIES = Arrays.aslist(DRESS, SKIRT, ...);

    private String name;

    public Category(String name) {
         this.name = name;
    }

    //Some static public method to iterate over categories
   ... 

我需要声明类别,还需要一种迭代它们的方法。我放弃反射,因为我认为这不是一个很好的做法。

声明相同 class 的大名称静态最终字段并将它们放在列表中是否是一种好做法?作为替代方案,我考虑过用 Map<Integer, Category> 代替列表,并且字段是可以标识每个类别的整数,因此您可以通过将它们放入地图中来获取类别。这在时间和 space 性能方面会更好吗?

PS:这是一个 android 项目,如果它改变了什么

对于小列表,使用ListMap都可以。

但是对于大列表,您可能希望将它们存储在数据库中。

另外 ArrayList of String 将比使用 ArrayList of Category

稍微有效

我会说使用 List 就足够了。

You should consider a Map only if you have to look up a particular Category very frequently via some key property (like an int your case).

如果 Category class 中没有属性或方法,请考虑将它们替换为 Strings

如果新的 Categories 是在运行时创建的,并且您想保留它们,请考虑使用数据库或文件来保存类别。

Edit: Answering the question in the comment

这取决于 Category class。如果它的唯一目的是枚举所有类别并且 class 本身没有任何其他实例方法或属性,那么就 space 复杂度而言 Integer 和你的 Category class 类似(因为在 Map 整数中将装箱在 Integer class 对象中)

我仍然建议您使用一个名为 Category 的 class 和一个列表,如果目的只是使用 Category 的特定实例迭代它们 and/or class 在您的应用程序的其他地方,例如。 Category.SOME_CATEGORY.

下面的例子是一个很好的用例

someMethod(Category category) {
    // do something
}

对比

someMethod(int category) {
   // before doing anything
   // lookup this category by an int key
   // in the the Map<Integer, Category>
}

后者的问题在于您可以传递任何 int,它可能是也可能不是类别的有效键。使用 class 可以提供一些额外的编译时间检查。尽管您也可以始终使用 int def。但我要再次重申,这一切都归结为 Category class 是否具有任何实例方法或属性。

Consider this code:

public class Category {

    public static final Category DRESS = new Category("Dress");
    public static final Category SKIRT = new Category("Skirt");

是的,这就是枚举在后台所做的,所以

public enum Category {
    DRESS("Dress"),
    SKIRT("Skirt"),
    ...;

    private String name;

    private Category(String name) {
         this.name = name;
    }

    // Category.values() returns the elements as an array

您应该使用 enum 而不是使用 new Category("Dress"); 创建对象,因为创建对象比使用 enum 昂贵。 Java 枚举的实现更像 类,因此您可以无缝更改代码:

public enum Category {
  DRESS("Dress"), SKIRT("Skirt");

  private final String name;

  Category(String name) { 
    this.name = name; 
  }

  public String getName() { 
    return name; 
  }
}

注:
枚举类型的构造函数必须是包私有或私有访问。它会自动创建在枚举主体开头定义的常量。您不能自己调用​​枚举构造函数。

Enum Types

阅读有关枚举的更多信息