java 如何通过用户输入设置枚举的值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16302376/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to set the value of an enum by user input
提问by ILikeTurtles
I am attempting to create a method by which I can return the value of an enum set by the users input. I decalred an enum, then I try to set the enum by the users input. I am unable to use my GetPlayerClass method to return the value of Player_Class. Can someone please tell me if this is the correct way to use an enum to set a value or is there a way I can allow the user to select from the enum list and let me get their choice.
我正在尝试创建一种方法,通过该方法我可以返回由用户输入设置的枚举值。我贴了一个枚举,然后我尝试通过用户输入设置枚举。我无法使用 GetPlayerClass 方法返回 Player_Class 的值。有人可以告诉我这是否是使用枚举设置值的正确方法,或者是否有一种方法可以让用户从枚举列表中进行选择并让我得到他们的选择。
My code is below.
我的代码如下。
TLDR: I am "enum dumb" and can't figure out how to set the value of a variable from an enum and then return that value later. Please view my code and let me know what I am doing wrong.
TLDR:我是“枚举笨蛋”,无法弄清楚如何从枚举设置变量的值,然后稍后返回该值。请查看我的代码,让我知道我做错了什么。
// The PCs base class
private enum Base_Class {
Barbarian, Bard, Cleric, Druid, Fighter, Monk,
Paladin, Ranger, Rogue, Sorcerer, Wizard
};
// Setting the base class
public void setBaseClass() {
do {
System.out.println("Available Classes: ");
System.out.println("Please select a cooresponding number for class.");
int i = 1;
for(Base_Class value: Base_Class.values()){
System.out.println(i+": "+value.name());
i++;
}
try {
Base_Class_Choice = user_input.nextInt();
switch(Base_Class_Choice) {
case 1:
Base_Class Player_Class;
Player_Class = Base_Class.Barbarian;
break;
case 2:
break;
default:
break;
}
} catch (Exception e) {
System.out.println("You must choose a valid class. Try numbers.");
user_input.next();
}
} while (Base_Class_Choice == 0);
}
/**
* Return my players class
* @return
*/
public String getPlayerClass() {
return Player_Class;
}
I updated the code below My try area now looks like so.
我更新了下面的代码我的尝试区域现在看起来像这样。
try {
Base_Class_Choice = user_input.nextInt();
Base_Class Player_Class = Base_Class.values()[Base_Class_Choice - 1];
} catch (Exception e) {
System.out.println("You must choose a valid class. Try numbers.");
user_input.next();
}
But the return for the Base_Class Player_Class does not work.
但是 Base_Class Player_Class 的返回不起作用。
public String getPlayerClass() {
return Player_Class;
}
When I try to return Player_Class it still fails out with the error cannot find symbol. What could I still be doing wrong?
当我尝试返回 Player_Class 时,它仍然失败并显示错误找不到符号。我还能做错什么?
UPDATE!!!! "ALL THE CODE!!!"
更新!!!!“所有代码!!!”
/*
*
*
*/
package rpgmanager;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
/**
*
* @author Aaron
*/
public class Character {
// The person playing the character
private String Player_Name;
// The PCs First Name
private String First_Name;
// The PCs Last Name
private String Last_Name;
// The PCs Race
private enum Race {
Dwarf, Halfling, Elf, Human, Gnome, HalfOrc, HalfElf
};
// The PCs base class
private enum Base_Class {
Barbarian, Bard, Cleric, Druid, Fighter, Monk,
Paladin, Ranger, Rogue, Sorcerer, Wizard
};
private Base_Class Player_Class;
// Base Class Choice for switch case
private int Base_Class_Choice = 0;
// The PCs Height
private int Height = 0;
// The PCs Weight
private int Weight = 0;
// The PCs Age
private int Age = 0;
// The PCs base level
private int Base_Level;
// Sets up the scanner for inputs
Scanner user_input = new Scanner(System.in);
// Create a Buffered reader for input
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
// This instantiates a new character
public Character() {
}
/**
* Sets the PCs first name
*/
public void setPlayerName() {
System.out.print("Players Name: ");
try {
Player_Name = reader.readLine();
} catch (IOException ioe) {
System.out.println("The Player Name input failed to set.");
System.out.println(ioe);
}
}
/**
* Sets the PCs first name
*/
public void setFirstName() {
System.out.print("First Name: ");
try {
First_Name = reader.readLine();
} catch (IOException ioe) {
System.out.println("The PCs First Name input failed to set.");
System.out.println(ioe);
}
}
/**
* Sets the PCs last name
*/
public void setLastName() {
System.out.print("Last Name: ");
try {
Last_Name = reader.readLine();
} catch (IOException ioe) {
System.out.println("The PCs Last Name input failed to set.");
System.out.println(ioe);
}
}
/**
* Sets the height of the PC
*/
public void setHeight() {
do {
System.out.print("Height (inches): ");
try {
Height = user_input.nextInt();
if(Height < 1) {
System.out.println("Not a valid number.");
}
} catch(Exception e) {
System.out.println("You must use a number greater than 0!");
user_input.next();
}
} while (Height < 1);
}
/**
* Sets the weight of the PC
*/
public void setWeight() {
do {
System.out.print("Weight (pounds): ");
try {
Weight = user_input.nextInt();
if (Weight < 1) {
System.out.println("Not a valid number.");
}
} catch (Exception e) {
System.out.println("You must use a number greater than 0!");
user_input.next();
}
} while (Weight < 1);
}
/**
* Sets the age of the PC
*/
public void setAge() {
do {
System.out.print("Age (whole years): ");
try {
Age = user_input.nextInt();
if (Age < 1) {
System.out.println("Not a valid number.");
}
} catch (Exception e) {
System.out.println("You must use a number greater than 0!");
user_input.next();
}
} while (Age < 1);
}
/**
* Sets the base level of the PC
*/
public void setBaseLevel() {
do {
System.out.print("Starting Level: ");
try {
Base_Level = user_input.nextInt();
if (Base_Level < 1 || Base_Level > 25) {
System.out.println("Not a valid number.");
}
} catch (Exception e) {
System.out.println("You must choose a valid level between 1 and 25!");
user_input.next();
}
} while (Base_Level < 1 || Base_Level > 25);
}
public void setBaseClass() {
do {
System.out.println("Available Classes: ");
System.out.println("Please select a cooresponding number for class.");
int i = 1;
for(Base_Class value: Base_Class.values()){
System.out.println(i+": "+value.name());
i++;
}
try {
Base_Class_Choice = user_input.nextInt();
Base_Class Player_Class = Base_Class.values()[Base_Class_Choice - 1];
} catch (Exception e) {
System.out.println("You must choose a valid class. Try numbers.");
user_input.next();
}
} while (Base_Class_Choice == 0);
}
/**
* Gets the PCs first name
* @return
*/
public String getFirstName() {
return First_Name;
}
/**
* Gets the PCs last name
* @return
*/
public String getLastName() {
return Last_Name;
}
/**
* Gets the PCs height
* @return
*/
public int getHeight() {
return Height;
}
/**
* Gets the PCs age
* @return
*/
public int getAge() {
return Age;
}
/**
* Gets the PCs base level (1-25)
* @return
*/
public int getBaseLevel() {
return Base_Level;
}
/**
* Gets the PCs player name
* @return
*/
public String getPlayerName() {
return Player_Name;
}
/**
*
* @return
*/
public Base_Class getPlayerClass() {
return Player_Class;
}
/**
* Creates a new character
*/
public void createCharacterNew() {
this.setPlayerName();
this.setFirstName();
this.setLastName();
this.setHeight();
this.setWeight();
this.setAge();
this.setBaseLevel();
this.setBaseClass();
}
}
回答by Brandon Buck
It's going to continue to fail as long as you are declaring and accessing that variable in different scopes (i.e. two functions). If you want to assign it in one scope, and access it in another you are going to need to make it a member variable of a wrapping class.
只要您在不同的范围(即两个函数)中声明和访问该变量,它就会继续失败。如果您想在一个范围内分配它,并在另一个范围内访问它,您将需要使其成为包装类的成员变量。
Your question is misleading, because you don't want to assign an enum the users input, you want to select the proper enum based on user input.
您的问题具有误导性,因为您不想为用户输入分配枚举,而是希望根据用户输入选择正确的枚举。
I offer you a simplified case of your original problem in ideone where you can see what I'm talking about in action.
我为您提供了 ideone 中原始问题的简化案例,您可以在其中看到我在说什么。
import java.util.Scanner;
class Player {
private BaseClass playerClass;
public void setPlayerClass() {
Scanner in = new Scanner(System.in);
StringBuilder output = new StringBuilder("Select a class:\n");
BaseClass[] classes = BaseClass.values();
for (int i = 0, len = classes.length; i < len; i++) {
output.append("\t").append(i + 1).append(": ")
.append(classes[i].name()).append("\n");
}
output.append(" >> ");
System.out.print(output.toString());
int playerChoice = in.nextInt();
in.close();
switch (playerChoice) {
case 1:
playerClass = BaseClass.Barbarian;
break;
case 2:
playerClass = BaseClass.Cleric;
break;
case 3:
playerClass = BaseClass.Mage;
break;
case 4:
playerClass = BaseClass.Fighter;
break;
}
}
public BaseClass getPlayerClass() {
return playerClass;
}
public static void main(String[] args) {
Player p = new Player();
p.setPlayerClass();
System.out.println("Player selected: " + p.getPlayerClass().name());
}
}
enum BaseClass {
Barbarian, Cleric, Mage, Fighter;
}
NOTE:To further clarify, you have to watch where you scope variables in Java. The scope the variable belongs to the block of code in which it defined. A block of code being code wrapped in {}
braces. Since you originally declared Player_Class
inside of a switch, it belonged to the scope of the switch and did not exist outside of it, hence why the method that accessed it didn't return what you wanted it to. When you moved the declaration of Player_Class
out of the switch, but still inside of setPlayerClass
all you did was scope it to the entire function setPlayerClass
but setPlayerClass
and getPlayerClass
do not share scope and therefore you were still not getting the result you were looking for.
注意:为了进一步澄清,您必须注意在 Java 中作用域变量的位置。变量属于它定义的代码块的范围。用{}
大括号括起来的代码块。由于您最初Player_Class
在 switch 内部声明,它属于 switch 的范围并且不存在于它之外,因此为什么访问它的方法没有返回你想要的。当你移动的声明Player_Class
里面出来的开关,但还是setPlayerClass
你所做的一切是它范围的全功能setPlayerClass
,但setPlayerClass
并getPlayerClass
没有共享的范围,因此,你仍然没有得到你正在寻找的结果。
In my above example I've solved this by using a private member variable on the Player
class called playerClass
that I can assign and return from multiple points within the class because the variable is scoped to the instance I created of the Player
class.
在我上面的例子中,我通过在Player
名为的类上使用私有成员变量解决了这个问题playerClass
,我可以从类中的多个点分配和返回,因为变量的范围是我创建的Player
类的实例。
回答by jtahlborn
this should work (no need for a switch block):
这应该可以工作(不需要开关块):
Player_Class = Base_Class.values()[Base_Class_Choice - 1];
回答by durron597
This is not how you use enum
s. Enums are fixed, stateless objects, which you would never instantiate (that is why their constructors are private, because the compiler does it for you.
这不是您使用enum
s 的方式。枚举是固定的、无状态的对象,您永远不会实例化(这就是为什么它们的构造函数是私有的,因为编译器会为您完成。
Also, on an aside - Use capital letters for class names, and lower case for fields and methods. Also, use camelCase, not underscore_case - that's how most all Java programmers do it and doing it that way will make it easier for you to read others code and for others to read your code.
另外,顺便说一句 - 类名使用大写字母,字段和方法使用小写字母。此外,使用驼峰式命名,而不是 underscore_case - 大多数 Java 程序员都是这样做的,这样做会使您更容易阅读其他人的代码,也让其他人更容易阅读您的代码。
I would put BaseClass into a separate file so you can use it everywhere. Then just use the convenient values()
array. Here is how I would do it:
我会将 BaseClass 放入一个单独的文件中,以便您可以在任何地方使用它。然后只需使用方便的values()
数组。这是我将如何做到的:
BaseClass.java
基类.java
public enum BaseClass {
BAR ("Barbarian"), BRD ("Bard"), CLR ("Cleric"), DRU ("Druid"),
FGT ("Fighter"), MON ("Monk"), PAL ("Paladin"), RAN ("Ranger"),
ROG ("Rogue"), SOR ("Sorceror"), WIZ ("Wizard");
private String fullName;
private BaseClass(String fullName) { this.fullName = fullName; }
public String getFullName() {
return fullName;
}
// Here you can add other useful methods
};
Player.java
播放器.java
// snip
public void setBaseClass() {
do {
System.out.println("Available Classes: ");
System.out.println("Please select a cooresponding number for class.");
int i = 1;
for(BaseClass value: BaseClass.values()){
System.out.println(i+": "+value.name());
i++;
}
try {
int baseClassChoice = user_input.nextInt();
if (i < 1 || i >= BaseClass.values()) {
System.out.println("That is not a valid choice. Please try again");
continue;
}
Player_Class = BaseClass.values()[i-1];
} catch (Exception e) {
System.out.println("You must choose a valid class. Try numbers.");
user_input.next();
}
} while (Base_Class_Choice == 0);
}
回答by Alper
You could use something similar to below sample code. it runs properly in my environment, you could try yourself.
您可以使用类似于以下示例代码的内容。它在我的环境中运行正常,您可以自己尝试。
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
enum BaseClass {
Barbarian(1), Bard(2), Cleric(3), Druid(4), Fighter(5), Monk(6), Paladin(7), Ranger(8), Rogue(9), Sorcerer(10), Wizard(11);
private int numericValue;
private static final Map<Integer, BaseClass> intToEnum = new HashMap<Integer, BaseClass>();
static {
for (BaseClass type : values()) {
intToEnum.put(type.getNumericValue(), type);
}
}
private BaseClass(int numericValue)
{
this.numericValue = numericValue;
}
public int getNumericValue()
{
return this.numericValue;
}
public static BaseClass fromInteger(int numericValue)
{
return intToEnum.get(numericValue);
}
};
public class Game {
public static void main(String[] args) throws IOException
{
Scanner input = new Scanner(System.in);
BaseClass choice;
do {
System.out.println("Available Classes: ");
System.out.println("Please select a cooresponding number for class.");
for (Base_Class value : Base_Class.values()) {
System.out.println(value.getNumericValue() + " : " + value);
}
choice = BaseClass.fromInteger(input.nextInt());
if (choice == null) {
System.out.println("Please select a valid class");
}
} while (choice == null);
System.out.println("Successfully chosen: " + choice);
input.close();
}
}