I have the following enum:
public enum Difficulty {
EASY(2), MEDUIM(3), HARD(5), EXTREME(8);
private int length;
Difficulty(int length) {
this.length = length;
}
public int length() {
return length;
}
}
I want to be able to reach the correct enum instance whether I know the number or the name.
For instance, if I have the int 3, I need a simple function that is able to return MEDIUM. And if I have the string extreme I need a simple function that is able to return 8.
By simple, I mean that I don't want to iterate each time or keep a static array inside the enum.
Answer must be in Java, Please. Thanks.
What edits do I need to make to the Difficulty enum structure?
public static Difficulty getByName(String name) {
return valueOf(name.toUpperCase());
}
public static Difficulty getByLength(int length) {
switch (length) {
case 2:
return EASY;
case 3:
return MEDIUM;
case 5:
return HARD;
case 8:
return EXTREME;
default:
throw new IllegalArgumentException("invalid length : " + length);
}
}
Related
I have these integers and this method which uses constructors but I am supposed to change this into an Enum since thise code is outdated. I do understand how Enums work in theory but no matter what I try to change I do it wrong.
public static final int CHILDRENS = 2;
public static final int REGULAR = 0;
public static final int NEW_RELEASE = 1;
private Price price;
public void setPriceCode(int priceCode) {
switch (priceCode) {
case REGULAR:
price = new RegularPrice();
break;
case CHILDRENS:
price = new ChildrensPrice();
break;
case NEW_RELEASE:
price = new NewReleasePrice();
break;
default:
throw new IllegalArgumentException("Incorrect Price Code");
}
}
I thaught that to change to enums I should first delete the given integers at the top and then add this before the method:
enum cases {
REGULAR, CHILDRENS, NEW_RELEASE;
}
And now I do not know how to change the method's code accordingly.
How do I give the cases the integers, should I not delete these: ?
public static final int CHILDRENS = 2;
How should I change my switch case accordingly?
Would really appreciate some help, I watched a bunch of videos on enums but the cases were very different.
Do it like this:
enum PriceCode {
REGULAR(0), // calls constructor with value 0
NEW_RELEASE(1), // calls constructor with value 1
CHILDREN(2) // calls constructor with value 2
;
private final int priceCode;
private PriceCode(int priceCode) {
this.priceCode = priceCode;
}
int value() {
return priceCode;
}
}
public class Main {
// Usage
public static void setPriceCode(PriceCode priceCode) {
System.out.println("The value of " + priceCode + " is " + priceCode.value());
switch (priceCode) {
case REGULAR:
// Do something
break;
case CHILDREN:
// Do something
break;
case NEW_RELEASE:
// Do something
break;
default:
throw new IllegalArgumentException("Incorrect Price Code");
}
}
public static void main(String[] args) {
// Set price code as CHILDREN
setPriceCode(PriceCode.CHILDREN);
// Another sample usage
System.out.println("Price code of NEW_RELEASE is " + PriceCode.NEW_RELEASE.value());
}
}
Output:
The value of CHILDREN is 2
Price code of NEW_RELEASE is 1
Learn more about enum and enum constructor at Java tutorial by Oracle.
Think of an enum as a class or interface, in other words it is a type. I recommend the following tutorial: Enum Types And according to java coding conventions, names of types should begin with a capital letter. Therefore, in the below code, I changed the name of the enum to Cases.
Hence the parameter to method setPriceCode should be Cases. The rest of the code remains the same.
enum Cases {
REGULAR, CHILDRENS, NEW_RELEASE;
}
private Price price;
public void setPriceCode(Cases priceCode) {
switch (priceCode) {
case REGULAR:
price = new RegularPrice();
break;
case CHILDRENS:
price = new ChildrensPrice();
break;
case NEW_RELEASE:
price = new NewReleasePrice();
break;
default:
throw new IllegalArgumentException("Incorrect Price Code");
}
}
Here is an example call to method setPriceCode()
setPriceCode(Cases.CHILDRENS);
I am making something right now that gives you an item based on a command and it's input.
If the command is
/item mythical destroyer or /item mythical 1 (an ID system)
it gives you a destroyer item (arbitrary, don't worry about the specifics).
Looking at other questions, they all have to do with enums, but what I am looking for is how to do it with integers and strings.
Here is what I am doing right now:
interface MythicalItem {
ItemStack getItem();
int getPrice();
void setPrice(int var1);
int getID();
}
class DestroyerMI implements MythicalItem {
private int price = 50;
int getID(){
return 1;
}
void setPrice(int var1){
this.price = var1;
}
int getPrice(){
return price;
}
Item getItem(){
Item item = new Item()
return item;
}
}
class MythicalUtil{
public static ItemStack parseItem(MythicalItem mythicalItem){
return mythicalItem.getItem();
}
public static int parseID(MythicalItem mythicalItem){
return mythicalItem.getID();
}
public static int parsePrice(MythicalItem mythicalItem){
return mythicalItem.getPrice();
}
}
My problem arises right here, and it doesn't seem like there is a way to get the mythical item by name/id without a giant switch or if/else, which I am trying to prevent.
// String[] args = {"mythical", "destroyer"};
if(args[0].equalsIgnoreCase("mythical")){
// I know it is supposed to be Integer.parseInt(args[1]), but dont worry about that please.
if(args[1].equals("1") || args[1].equalsIgnoreCase("destroyer")){
player.giveItem(MythicalUtil.parseItem(new DestroyerItem()));
}else if(args[1].equalsIgnoreCase("shooter"){
plaer.giveItem(MythicalUtil.parseItem(new ShooterItem()));
}else if(...
}
I want to make a method that can return the item to me without spaghettifying my code.
If you really need to do all of that on Strings and Integers and you don't want to refactor all the code you already have but that particular part only, you can try to use switch case
String appropriateNameForArg0 = args[0].toUpperCase();
String appropriateNameForArg1 = args[1].toUpperCase();
if (appropriateNameForArg0.equals("MYTHICAL")) {
switch (appropriateNameForArg1) {
case "1":
case "DESTROYER":
player.giveItem(MythicalUtil.parseItem(new DestroyerItem()));
break;
case "SHOOTER":
plaer.giveItem(MythicalUtil.parseItem(new ShooterItem()));
break;
case "...":
// some other action here
default:
// here you have a place for actions which will be triggered if appropriateNameForArg1 will not meet any of the defined cases
break;
}
}
So I am trying to get a random word from a list of words in a Class called Lexicon.
public abstract class Lexicon {
public String getWord(int index) {
switch (index) {
case 0: return "UNIVERSITY";
case 1: return "COMPUTER";
case 2: return "LAPTOP";
case 3: return "HEADPHONES";
case 4: return "FUZZY";
case 5: return "HOTEL";
case 6: return "KEYHOLE";
case 7: return "TELEPHONE";
case 8: return "PRINTER";
case 9: return "BUILDING";
default: return "Illegal index";
}
};
}
To a class called Game :
import java.util.Random;
public class Game {
private int MaxGuess;
private boolean GameOver;
private String RandomWord;
public Game(int maxGuess, boolean gameOver, Lexicon randomWord) {
super();
MaxGuess = maxGuess;
GameOver = gameOver;
Random rand = new Random();
int n = rand.nextInt(9);
RandomWord=getWord(n);
}
public void Result(boolean GameOver) {
if(GameOver) {
System.out.println("You have won the game!!");
}
else {
System.out.println("You Lost!!");
}
}
}
and I get an error that says Method getWord(int) is unidentified for type Game.
It must be something really simple but I cannot get myself to find the mistake. Been trying for like an hour.My java skills got rusty through out Summer. Any help would be appreciated.Thank you in advance.
Two problems are needed to be addressed,
The nextInt function will never get 0-9, but 0-8, please changed this line
int n = rand.nextInt(9);
to
int n = rand.nextInt(10);
The getWord() is not defined in Game Class. You should be calling from the Lexicon Class. And i recommend you to change it to static. which is changed from
public String getWord(int index) {
to
public static String getWord(int index) {
So you can call the function directly with
RandomWord = Lexicon.getWord(n);
In this way, you saved performance and also have the proper way to implement a function as static logic should always be implemented this way.
*Remark: not related to compiling or bugs, but for you variable naming:
private int MaxGuess;
private boolean GameOver;
private String RandomWord;
unless you should always begin with small letter following smallCamelToe convention, some examples are as follow:
//variable
private int maxGuess;
private boolean gameOver;
private String randomWord;
//constant variable
private final int MAX_GUESS = 1;
//static constant variable, usually be used when implementing constant files and import from other classes
public static final boolean GAME_OVER;
and it is ok to implement the following:
public Game(int maxGuess, boolean gameOver) {
super();
maxGuess = maxGuess; //you can use this.maxGuess if compile failed
gameOver = gameOver; //you can use this.gameOver if compile failed
Random rand = new Random();
RandomWord = Lexicon.getWord(rand.nextInt(9));
}
Because getWord() is defined in class Lexicon and not in class Game .
You need game to extend Lexicon if you wish it to inherit the functions
public class Game extends Lexicon {
...
}
Or use the Lexicon you have:
RandomWord=randomWord.getWord(n);
The function getWord is in a different class. You can either copy the method into the game class or try to call Lexicon.getWord() instead
Well, you should do RandomWord = randomWord.getWord(n), not just RandomWord=getWord(n).
In any case it is not clear to my why you do it in this way. The lexicon can be just a list of strings instead of a switch statements hidden inside a class (and an abstract one!)
I have a number of Java classes I need to convert to Swift code.
One of the classes has an advanced enum:
public enum Student {
STUDENT_ONE("Steve", "Jobs")
STUDENT_TWO("Tim", "Cook")
private String _firstName;
private String _lastName;
}
How can I replicate the same behavior in Swift?
After some thought, I agree with godmoney that aksh1t's solution is better that my solution using Strings.
Anyway, here is a more concise variant of aksh1t's solution, using only one computed property returning a tuple: (tested in Swift 2.0)
enum Student {
case STUDENT_ONE, STUDENT_TWO
typealias Details = (firstName: String, lastName: String)
var details : Details {
switch(self) {
case STUDENT_ONE : return ("Steve", "Jobs")
case STUDENT_TWO : return ("Tim", "Cook")
}
}
}
// Usage:
func test(sd: Student.Details) {
print(sd.firstName)
print(sd.lastName)
}
test(Student.STUDENT_ONE.details)
I was trying to do the same thing with converting Java code to Swift, and ended up doing something like this :
public enum Student {
case STUDENT_ONE
case STUDENT_TWO
var firstName: String {
get {
switch self {
case .STUDENT_ONE:
return "Steve"
case .STUDENT_TWO:
return "Tim"
}
}
}
var lastName: String {
get {
switch self {
case .STUDENT_ONE:
return "Jobs"
case .STUDENT_TWO:
return "Cook"
}
}
}
}
Now, this is really long and messy and I'm not really sure whether this is the right way to do it, but I couldn't find anything else that worked. I would love to know if there is some other better way to do it.
This is what I ended up doing - not sure about this at all:
struct Students {
enum Students {
case STUDENT_ONE(String, String)
case STUDENT_TWO(String, String)
}
let STUDENT_ONE = Students.STUDENT_ONE("Steve", "Jobs")
let STUDENT_TWO = Students.STUDENT_TWO("Steve", "Two")
}
Enums are not necessarily the best choice to represent this type of data. I choose structs and this works well, using the correct accessors:
public struct Student {
public let firstName : String
public let lastName : String
public static let STUDENT_ONE = Student(firstName: "Steve", lastName: "Jobs")
public static let STUDENT_TWO = Student(firstName: "Tim", lastName: "Cook")
}
Moved here from another question marked as a duplicate so the variable names don't match up exactly, however, the concepts all do.
The most obvious way would be:
public enum EnumWeapon {
case WOODEN_SWORD
case STONE_SWORD
case STEEL_SWORD
func getName() -> String {
switch self {
case WOODEN_SWORD: return "Wooden Sword"
case STONE_SWORD: return "Stone Sword"
case STEEL_SWORD: return "Steel Sword"
}
}
func getDamage() -> Int {
switch self {
case WOODEN_SWORD: return 4
case STONE_SWORD: return 6
case STEEL_SWORD: return 8
}
}
}
If you have a single value to associate with each enum case, you can use the raw value syntax, or just use it to simplify the enum case above:
public enum Weapon : Int {
case WOODEN_SWORD = 4
case STONE_SWORD = 6
case STEEL_SWORD = 8
func getDamage() -> Int {
return rawValue
}
func getName() -> String {
switch self {
case .WOODEN_SWORD: return "Wooden Sword"
case .STONE_SWORD: return "Stone Sword"
case .STEEL_SWORD: return "Steel Sword"
}
}
}
Obviously, if you don't need the name, you can omit the getName function. Likewise you can omit the getDamage function and just use weapon.rawValue
An even simpler way, and yet more analogous to the actual Java implementation, would be to use a struct instead of an enum, as:
public struct Weapon {
public let name : String
public let damage : Int
private init(name:String, damage:Int) {
self.name = name
self.damage = damage
}
public static let WOODEN_SWORD = Weapon(name: "Wooden Sword", damage: 4)
public static let STONE_SWORD = Weapon(name: "Stone Sword", damage: 6)
public static let STEEL_SWORD = Weapon(name: "Steel Sword", damage: 8)
}
and, be redefining operator ==, you can get equality comparisons:
func == (lhs:Weapon, rhs:Weapon) -> Bool {
return lhs.name == rhs.name && lhs.damage == rhs.damage
}
and, by redefining operator ~= you can get switch to work as expected:
func ~= (lhs:Weapon, rhs:Weapon) -> Bool {
return lhs == rhs
}
func test(sword:Weapon) {
switch sword {
case Weapon.STONE_SWORD: print("stone")
default: print("something else")
}
}
test(Weapon.STONE_SWORD)
A whole lot of options, mostly it just depends on what you're really trying to do and how much data you need to wrap in the enum.
This question already has answers here:
How to return multiple objects from a Java method?
(25 answers)
Closed 7 years ago.
I am using a simulator to play craps and I am trying to return two values from the same method (or rather I would like to).
When I wrote my return statement I simply tried putting "&" which compiled and runs properly; but I have no way of accessing the second returned value.
public static int crapsGame(){
int myPoint;
int gameStatus = rollagain;
int d1,d2;
int rolls=1;
d1 = rollDice();
d2 = rollDice();
switch ( d1+d2 ) {
case 7:
case 11:
gameStatus = win;
break;
case 2:
case 3:
case 12:
gameStatus = loss;
break;
default:
myPoint = d1+d2;
do {
d1=rollDice();
d2=rollDice();
rolls++;
if ( d1+d2 == myPoint )
gameStatus = win;
else if ( d1+d2 == 7 )
gameStatus = loss;
} while (gameStatus == rollagain);
} // end of switch
return gameStatus & rolls;
}
When I return the value as:
gameStatus=crapsGame();
It appropriately sets the varaible to win or lose but if I try something as simple as following that statement with:
rolls=crapsGame();
It is assigned the same value as gamestatus...a 0 or a 1 (win or lose).
Any way that I can access the second returned value? Or is there a completely different way to go about it?
Create your own value holder object to hold both values, then return it.
return new ValueHolder(gameStatus, rolls);
It's possible to return an array with multiple values, but that's cryptic and it does nothing for readability. It's much easier to understand what this means...
valueHolder.getGameStatus()
than what this means.
intArray[0]
returning gameStatus & rolls means "return the bitwise and of gameStatus and rolls" which probably is not what you want
you have some options here:
return an array
create a class that represents the response with a property for each value and return an instance
use one of the many java collections to return the values (probably lists or maps)
You can return an array of values or a Collection of values.
Is it possible to return more than one value from a method in Java?
No it is not. Java allows only one value to be returned. This restriction is hard-wired into the language.
However, there are a few approaches to deal with this restriction:
Write a light-weight "holder" class with fields for the multiple values you want to return, and create and return an instance of that class.
Return a Map containing the values. The problem with this (and the next) approach is that you are straying into an area that requires runtime type checking ... and that can lead to fragility.
Return an array containing the values. The array has to have a base type that will accommodate the types of all of the values.
If this is a method on an object, then add some fields on the same object and methods that allow the caller to pick up "auxiliary results" from the last call. (For example, the JDBC ResultSet class does this to allow a client to determine if the value just retrieved was a NULL.) The problem is that this makes the class non-reentrant at the instance level.
(You could even return extra results in statics, but it is a really bad idea. It makes the class non-reentrant across all instances, not to mention all of the other badnesses associated with misused statics.)
Of these, the first option is the cleanest. If you are worried about the overhead of creating holder instances, etc, you could consider reusing the instances; e.g. have the caller pass an existing "holder" to the called method into which the results should be placed.
The best practice for an OOP approach is to return an Object. An object that contains all the values you want.
Example:
class Main {
public static void main(String[] args) {
MyResponse response = requestResponse();
System.out.println( response.toString() );
}
private static MyResponse requestResponse() {
return new MyResponse( "this is first arg", "this is second arg" );
}
}
class MyResponse {
private String x, y;
public MyResponse( String x, String y ) {
this.x = x;
this.y = y;
}
#Override
public String toString() {
return "x: " + x + "\t y: " + y;
}
}
If you want an even more scalable approach then you have to use JSON responses. (let me know if you want an example with JSON too)
You can following ways to do this:
Use a Container class, for example
public class GameStatusAndRolls {
String gameStatus;
String rolls;
... // constructor and getter/setter
}
public static GameStatusAndRolls crapsGame(String gameStatus, String rolls) {
return new GameStatusAndRolls(gameStatus, rolls);
}
public static void main(String[] args) {
...
GameStatusAndRolls gameStatusAndRolls = crapsGame(gameStatus, rolls);
gameStatusAndRolls.getGameStatus();
Use List or an array, for example
public static List<Integer> crapsGame(String gameStatus, String rolls) {
return Arrays.asList(gameStatus, rolls);
}
private static final int GAME_STATUS = 0;
private static final int ROOLS = 0;
public static void main(String[] args) {
...
List<Integer> list = crapsGame(gameStatus, rolls);
... list.get(0)...list.get(GAME_STATUS);
... list.get(1)...list.get(ROOLS);
or
public static String[] crapsGame(String gameStatus, String rolls) {
return new String[] {gameStatus, rolls};
}
private static final int GAME_STATUS = 0;
private static final int ROOLS = 0;
public static void main(String[] args) {
...
String[] array = crapsGame(gameStatus, rolls);
... array[0]...array[GAME_STATUS];
... array[1]...array[ROOLS];
Use Map, for example
public static Map<String, String> crapsGame(String gameStatus, String rolls) {
Map<String, String> result = new HashMap<>(2);
result.put("gameStatus", gameStatus);
result.put("rolls", rolls);
return result;
}
public static void main(String[] args) {
...
Map map = crapsGame(gameStatus, rolls);
... map.get("gameStatus")...map.get("rolls");