如果我有一个对象
public class Genre {
private int id;
private int name;
}
并且id和名称已经提前确定,例如
if (id == 1)
name = "action";
else if (id == 2)
name = "horror";
我的问题是如何很好地创建这两种方法
Genre.getName(1); // return "action";
Genre.getId("action"); // return 1;
我想也许我可以使用枚举,比如
public enum Genre {
ACTION(1), HORROR(2);
private final int id;
private final String name;
private Genre(int id) {
this.id = id;
this.name = getName(id);
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public static String getName(int i) {
switch(i) {
case 1 : return "action";
case 2: return "horror";
default :
return null;
}
}
}
但是这样,我不知道如何
Genre.getId("action"); // return 1;
我害怕我不正确地使用枚举。
你能给我一些建议吗?谢谢!
---
首先,我想要做的是在我的情况下,我想使用id或名称来查找名称或ID,如
int id = 1;
Genre.getName(id); // return "action"
或
String name = "action";
Genre.getId(name); // return 1
现在感谢所有的建议,我意识到我想要做的是
int id = 1;
Genre.getGenre(id); // return Genre that id = 1 and the name = "action"
或
String name = "action";
Genre.getGenre(name); // return Genre that id = 1 and the name = "action"
答案 0 :(得分:3)
如果你坚持使用枚举,你可以使用现有的枚举设施。下面的解决方案假定枚举名称和序号可用于代替您的姓名和ID字段:
public enum Genre {
// ordinal 0, name = "ACTION"
ACTION,
// ordinal 1, name = "HORROR"
HORROR;
}
public static void main(String[] args) {
int horrorOrdinal = 1;
Genre horrorGenre = Genre.values()[horrorOrdinal];
String horrorName = horrorGenre.name();
String actionName = "ACTION";
Genre actionGenre = Genre.valueOf(actionName);
int actionOrdinal = actionGenre.ordinal();
System.out.println(String.format("%s=%s %s=%s", horrorName, horrorOrdinal, actionName, actionOrdinal));
}
输出:
HORROR=1 ACTION=0
另一种合适的方法是使用地图进行查找,例如MichałŠrajer建议:
private static Map<Integer, String> genres = new HashMap<Integer, String>();
public static void main(String[] args) {
initGenres();
int horrorOrdinal = 2;
String horrorName = genres.get(horrorOrdinal);
String actionName = "action";
int actionOrdinal = getGenreIdByName(actionName);
System.out.println(String.format("%s=%s %s=%s", horrorName, horrorOrdinal, actionName, actionOrdinal));
}
private static void initGenres() {
genres.put(1, "action");
genres.put(2, "horror");
}
private static int getGenreIdByName(String genreName) {
for (Entry<Integer, String> entry : genres.entrySet()) {
if (entry.getValue().equals(genreName)) {
return entry.getKey();
}
}
throw new IllegalArgumentException("Genre not found: " + genreName);
}
输出:
horror=2 action=1
设计考虑因素:
在这个例子中,我选择对id-&gt; name使用(快速)地图查找,并编写了一个单独的方法(getGenreIdByName)来执行反向查找name-&gt; id。您可以反转它,或使用第二个映射来快速进行两次查找(代价是需要维护额外的映射)。
我选择在地图中存储ID和名称。您也可以使用Genre类本身作为地图值。这将允许您稍后轻松添加额外的字段(如“描述”)。
如果您需要用不同语言表示类型,可以使用ResourceBundles来本地化输出。在类路径根目录中创建语言文件。
在文件genres_nl.properties中:
horror=heel eng
action=actie
文件名中的_nl后缀表示语言。
然后在你的代码中,在initGenres中:
ResourceBundle genreNames = ResourceBundle.getBundle("genres", new Locale("nl");
获得流派名称时:
String horrorName = genreNames.getString(genres.get(horrorOrdinal));
请注意,如果找不到捆绑包,getString可能会抛出运行时异常MissingResourceException。为避免这种情况,请确保创建一个没有后缀的“默认”包(因此在本例中为名为“genres.properties”的文件),如果找不到所使用的Locale的包,则会自动使用该包。
答案 1 :(得分:2)
尝试valueOf(...)
方法:
void String getId(String name) {
//names are upper case, so account for that
//handling non-existent names is an excersize for you
valueOf(name.toUpperCase()).getId();
}
请注意,有更好的方法(如Thilo建议),但如果您只有字符串,则可以使用它。
编辑:另一个注意事项:
在getName(int i)
方法中,您可能希望返回ACTION.name()
等,以便更安全地重构并使用正确的案例。
答案 2 :(得分:2)
您可以通过调用Genre.ACTION.getId();
来获取其ID答案 3 :(得分:1)
这应该这样做:
Genre.ACTION.getId()
如果你需要在运行时这样做:
Genre.valueOf("ACTION").getId()
答案 4 :(得分:1)
ACTION(1, "action"), HORROR(2, "horror");
是一种简单的方法。
但如果你需要更频繁地做,我会建议你创建自己的课程并使用MAP<-"-,-"->
作为micheal说。
编辑:----
正如你所说,很少会改变使用这种方式 - &gt;
public enum Genre {
ACTION(0, "action"), HORROR(1, "horror"), ROMANCE(2, "romance"), COMEDY(5, "comedy");
public final int id;
public final String name;
private Genre(int id, String name) {
this.id = id;
this.name = name;
};
public final static int length = Genre.values().length;
public static String[] getGenre() {
String[] genreList = new String[length];
int i = 0;
for (Genre attribute : Genre.values()) {
genreList[i++] = attribute.toString();
}
return genreList;
}
@Override
public String toString() {
return this.name;
}
}
请记住将其用作Genre.HORROR.id
另请注意,根据您的要求,使用这种方式最佳。
答案 5 :(得分:0)
为什么不使用带有id和String的枚举构造函数:
public enum Genre {
ACTION(1, "action"), HORROR(2, "horror");
}
答案 6 :(得分:0)
public enum Genre {
ACTION(1, "action"), HORROR(2, "horror");
private final int id;
private final String name;
private Genre(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}
答案 7 :(得分:0)
如果您需要按名称访问特定元素,则需要这样做:
Genre.valueOf("ACTION").getId()
但是,如果您需要经常这样做,并且以更动态的方式,我建议创建常规类,并将所有数据保存在某个Map<String, Movie>
容器中。