This is the question given:
This is my attempt:
class SerialPublication {
public enum Frequency {DAILY, WEEKLY, MONTHLY, QUARTERLY, YEARLY, UNDEFINED}
protected Frequency frequency;
public SerialPublication(){
frequency = Frequency.UNDEFINED;
}
public SerialPublication(String freq){
setFrequency(freq);
}
public void setFrequency(Frequency freq){
this.frequency = freq;
}
public Frequency getFrequency(){
return frequency;
}
}
This is my error message:
We are told not to add the first "public" in the class declaration because of the way the website works.
I'm not very familiar with the syntax behind enumerators (and I'm quite new to java too) so I'm not entirely sure what I'm doing wrong. Any help would be appreciated.
you forgot the type Frequency in this method setFrequency here:
public void setFrequency(freq){
frequency = Frequency.freq;
}
it must be:
public void setFrequency( Frequency freq){
this.frequency = freq;
}
You will also need to build the enum from any given String. See the inner enum class fromString(String aFrequency). As a bonus, the examply also shows you can add extra information to an enum.
public class SerialPublication {
public enum Frequency {
//Can add extra information to enums
DAILY("Daily"),
WEEKLY("Weekly"),
MONTHLY("Monthly"),
QUARTERLY("Quarterly"),
YEARLY("Yearly"),
UNDEFINED("Undefined");
private final String frequency;
Frequency(String frequency) {
this.frequency = frequency;
}
public String getFrequency() {
return frequency;
}
/**
* Builds an enum from a given frequency string
* #param aFrequency
* #return
*/
public static Frequency fromString(String aFrequency) {
for (Frequency frequency : Frequency.values()) {
if(frequency.getFrequency().toLowerCase().equals(aFrequency.toLowerCase())) {
return frequency;
}
}
return Frequency.UNDEFINED; //Could send null back
}
}
private Frequency frequency;
public SerialPublication(){
frequency = Frequency.UNDEFINED;
}
public SerialPublication(String freq){
this.setFrequency(freq);
}
/**
* Sets the frequence based on a String. This handles invalid input by assuming nonsense equals undefined
* #param frequency
*/
public void setFrequency(String frequency){
this.setFrequency(Frequency.fromString(frequency));
}
/**
* Sets the frequency based on the Frequency Enum.
* #param frequency
*/
public void setFrequency(Frequency frequency) {
this.frequency = frequency;
}
public Frequency getFrequency(){
return frequency;
}
public static void main(String[] args) {
SerialPublication publication = new SerialPublication();
System.out.println(publication.getFrequency());
publication.setFrequency("monthly");
System.out.println(publication.getFrequency());
publication.setFrequency(Frequency.QUARTERLY);
System.out.println(publication.getFrequency());
publication.setFrequency("cows are great");
System.out.println(publication.getFrequency());
}
}
Related
I have this enum:
public enum Digits {
ZERO(0);
private final int number;
private Digits(int number) {
this.number = number;
}
public int getValue(){
return number;
}
}
And I would like to make setter in another class which can me offer following feature:
- I will give it integer value (in this case, 0) and that setter will set enum ZERO to my local variable of type Digits
Is that possible?
Many thanks!
It is possible, but not by invoking the enum's constructor, as it's available only within the enum itself.
What you can do is add a static method in your enum that retrieves the correct instance based on a given value, e.g. ZERO if the given value is 0.
Then you'd invoke that method in your other class when given the int argument.
Self contained example
public class Main {
static enum Numbers {
// various instances associated with integers or not
ZERO(0),ONE(1),FORTY_TWO(42), DEFAULT;
// int value
private int value;
// empty constructor for default value
Numbers() {}
// constructor with value
Numbers(int value) {
this.value = value;
}
// getter for value
public int getValue() {
return value;
}
// utility method to retrieve instance by int value
public static Numbers forValue(int value) {
// iterating values
for (Numbers n: values()) {
// matches argument
if (n.getValue() == value) return n;
}
// no match, returning DEFAULT
return DEFAULT;
}
}
public static void main(String[] args) throws Exception {
System.out.println(Numbers.forValue(42));
System.out.println(Numbers.forValue(10));
}
}
Output
FORTY_TWO
DEFAULT
You can do it like this:
private Digits digit;
public void setDigit(int number) {
for (Digits value : Digits.values()) {
if(value.getValue() == number) {
digit = value;
}
}
}
Here is the example how to achieve what you want
public enum Digit {
ONE(1),
TWO(2),
THREE(3);
private static final Map<Integer, Digit> mappingMap = new HashMap<Integer, Digit>();
static {
for (Digit m : Digit.values()) {
mappingMap.put(m.getValue(), m);
}
}
private final int digit;
Digit(int aDigit) {
digit = aDigit;
}
public int getValue() {
return digit;
}
public static Digit getByDigit(int aDigit) {
return mappingMap.get(aDigit);
}
}
This approach has better performance than iterating over all constants for large enums.
I have a few classes that I need to be generic. I have the following class DataSet that I want to be able to generate an average and maximum of any sort of Objects passed into class that implements my measurable interface or my Measurer interface.
When I go to test my code, I get the error that my type is not within bounds. Any ideas? When I exclude the Measurer from the DataSet, the test compiles. I am not sure if I made the DataSet correctly Generic.
DataSet.java
public class DataSet<T extends Measurable<Double> & Measurer<Double>>//
{
/**
Constructs an empty data set.
*/
public DataSet()
{
this.sum = 0;
this.count = 0;
this.maximum = null;
}
/**
Adds a data value to the data set.
#param x a data value
*/
public void add(T x)
{
sum = sum + x.getMeasure();
if (count == 0 || maximum.getMeasure() < x.getMeasure())
maximum = x;
count++;
}
/**
Gets the average of the added data.
#return the average or 0 if no data has been added
*/
public double getAverage()
{
if (count == 0) return 0;
else return sum / count;
}
/**
Gets the largest of the added data.
#return the maximum or 0 if no data has been added
*/
public T getMaximum()
{
return maximum;
}
private double sum;
private T maximum;
private int count;
}
DataSetTest.java
import java.awt.Rectangle;
public class DataSetTest
{
public static void main(String[] args)
{
DataSet<BankAccount<Double>> ds1 = new DataSet<>();
BankAccount<Double> ba1 = new BankAccount<>(100.00);
BankAccount<Double> ba2 = new BankAccount<>(300.00);
}
}
BankAccount.java
public class BankAccount<T> implements Measurable<T>
{
public BankAccount()
{
balance = null;
}
public BankAccount(T balance)
{
this.balance = balance;
}
public T getMeasure()
{
return balance;
}
private T balance;
}
Measurable.java
/**
Describes any class whose objects can be measured.
*/
public interface Measurable <T>
{
/**
Computes the measure of the object.
#return the measure
*/
T getMeasure();
}
Measurer.java
/**
Describes any class whose objects need a measurer.
*/
public interface Measurer <T>
{
/**
Computes the measurer of the object.
#return the measurer
*/
T getMeasurer(T anObject);
}
rectangleShape.java
import java.awt.Rectangle;
/**
Concrete Class RectangleMeasurer
#param Takes object as parameter. Overloads measurer class.
#return Returns the area of a object passed in.
*/
public class rectangleShape<T> implements Measurer<T>{
public T getMeasurer(T anObject)
{
Rectangle aRectangle = (Rectangle) anObject;
Double area = aRectangle.getWidth() * aRectangle.getHeight();
//#SuppressWarnings("unchecked")
a = (T)area;
return a;
}
private T a;
}
The type bounds <T extends Measurable<Double> & Measurer<Double>> imply the parameter extends Measurable AND Measurer, but you want that to be OR. You can't do that with generic parameter syntax.
You can however have overloaded methods in DataSet.
public add(Measurable<Double> m) {
//...
}
public add(Measurer<Double> m) {
//...
}
Or you can do runtime type checking, although that is not the most advisable.
public add(Object o) {
if (o instanceof Measurable) {
//...
} else if (o instanceof Measurer) {
//...
}
}
Basically, your use case does not require a type parameter on the class. You are trying to make the problem fit your solution rather than the other way around.
I have a table and want to save the status using a enum. I created a enum as below
/**
* Enumeration for Status
*
*
* Current defined values are :
* <ul>
* <li>ACTIVE = 1</li>
* <li>INACTIVE = 2</li>
* </ul>
*/
public enum Status {
/**
* ACTIVE (Ordinal 1).
*/
ACTIVE(1),
/**
* INACTIVE (Ordinal 2).
*/
INACTIVE(2),
private int value;
private Status(int value) {
this.value = value;
}
public static void main (String ars[]){
for (Status str : Status.values()) {
System.out.println("====str==========="+str.name() +"::::::: "+str.ordinal());
}
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
How to I get the ordinal value from 1. My output is like this
====str===========ACTIVE::::::: 0
====str===========INACTIVE::::::: 1
Actually i have mapped this enum to my Entity and i have used it as below
#Column(name = "STATUS",nullable=false)
#Enumerated(EnumType.ORDINAL)
private Status status;
How to i save the Active status as 1 ... ?
You could override the toString() method of your enum or provide a getter.
public enum Status {
/**
* ACTIVE (Ordinal 1).
*/
ACTIVE(1),
/**
* INACTIVE (Ordinal 2).
*/
INACTIVE(2); // Note the semicolon
private final int value;
private Status(int value) {
this.value = value;
}
public int getValue() {
return value;
}
// OR
#Override
public String toString() {
return String.valueOf(value);
}
}
Then you can call
System.out.println(ACTIVE); // toString is called
or
System.out.println(ACTIVE.getValue());
Use getValue() instead of ordinal()? ordinal() doesn't magically know to call your method, it just returns the ordinal.
print str.getValue().
ordinal gives you default values.
Main question:
Each flight has a number (this must start with letters EI and be followed by 3 digits), a day of the week the flight travels, a destination and the number of seats booked. Each flight will also have the standard responsibilities and the ability to calculate and return the number of free seats on a flight (assume each flight has a maximum of 10). You should use your imaginations to create one other flight responsibility that you think would be useful (this could also involve the creation of one or more new data items to support the responsibility).
This is what i have done so far:
public class Flight{
private String flightNo;
private date day;
private String
private int numberOfBookedSeats;
private int freeSeats=0;
private int passengerMeals;
private int mealsNeeded=0;
public Flight(){
}
public Flight(String flightNo, date day,String destination,int numberOfBookedSeats,int passengerMeals ){
this.flightNo= flightNo;
this.day = day;
this.destination= destination;
this.numeberOfSeats= numberOfSeats;
this.passengerMeals= passengerMeals;
}
public void setFlightNo(filghtNo f){
flightNo= f;
}
public String getFlightNo() {
return flightNo;
}
public void setDay(Day d) {
day= d;
}
public int getDay(){
return day;
}
public void setDestination(destination ds) {
destination = ds;
}
public int getDestination(){
return destination;
}
public void setNumeberOfSeats(numberOfSeats s){
numberOfSeats= s;
}
public int getNumeberOfSeats(){
return numeberOfSeats;
}
public void setPassengerMeals( passengerMeals pm){
passengerMeals= pm;
}
public int getPassengerMeals(){
return passengerMeals;
}
public int calculateFreeSeats(){
int maxSeatsNumbers = 10;
freeSeats = maxSeatsNumbers - numberOfBookedSeats;
return freeSeats;
}
public int calculateMealsNeeded(){
int staffMeals=5;
passengerMeals= numberOfBookedSeats;
mealsNeeded= staffMeals + passengerMeals;
return mealsNeeded;
}
}
Anint is not the correct class to store the flight number as, as it does not allow for the prefix characters or for the width to be specified. You could store it as a String, which would allow the prefix, and then do some validation and possibly padding to the numeric part, but what I would do is create a new type to represent the flight number.
This encapsulates the logic used to generate the flight number from the prefix String & int, making it more maintainable as the validation logic is just in one place, and it makes the code more understandable as your Flight class no longer has to contain logic to do with generating String flight numbers. It's a lot more clear in use, as well, because if you have a private final FlightNumber flightNumber member, you can use it in a String with something like "The flight number is " + flightNumber;.
See the following for what this type could look like:
Note this particular implementation uses Guava's Strings class - if you're not using this already it's probably not worth importing it just for this, so implement an equivalent yourself using String.format("%03d", ...) or similar, but if you've got Guava I think it looks cleaner.
import com.google.common.base.Strings;
public class FlightNumber {
private final String prefix;
private final int flightId;
public FlightNumber(String prefix, int flightId) {
if (flightId < 0 || flightId > 999) {
throw new IllegalArgumentException("Invalid Flight ID [" + flightId + "]");
}
this.prefix = prefix;
this.flightId = flightId;
}
#Override
public String toString() {
return prefix + Strings.padStart(String.valueOf(flightId), 3, '0');
}
}
If you wanted to extend this in the future, and your code suited this kind of design, you could then do something like the following:
public class AerLingusFlightNumber extends FlightNumber {
public AerLingusFlightNumber(int flightId) {
super("EI", flightId);
}
}
And:
public class BritishAirwaysFlightNumber extends FlightNumber {
public BritishAirwaysFlightNumber(int flightId) {
super("BA", flightId);
}
}
You should only create one public Constructor due to a Flight must have a FlightNumber (must be a String).
Also I would check at the body of the constructor the following:
if (!flightNumber.matchs("^EI\d{3}$")) {
throw new IllegalArgumentException("Invalid Flight number format.");
}
flightNo = flightNumber;
If you want your fight number to be alpha numeric then int is not the correct data type, you should use String and for validating that you could use the String method matches in conjunction with a regular expression.
Here is something you could start with:
class AirLine {
List<Flight> flights = new ArrayList<>();
public void addFlight(String flightNumber) {
flights.add(new Flight(flightNumber));
}
public List<Flight> getFlights() {
return flights;
}
}
class Flight {
String flightNumber;
public Flight(String flightNumber) {
setFlightNumber(flightNumber);
}
public String getFlightNumber() {
return flightNumber;
}
public void setFlightNumber(String flightNumber) {
if(flightNumber == null || ! flightNumber.matches("EI\\d{3}")) {
throw new IllegalArgumentException("invalid flight number: "
+ flightNumber);
}
this.flightNumber = flightNumber;
}
}
This question already has answers here:
Convert from enum ordinal to enum type
(15 answers)
Closed 7 years ago.
I've read a lot about how obtain the corresponding name of an enum from its value using java, but no example seems to work for me! What is wrong?
public class Extensions {
public enum RelationActiveEnum
{
Invited(0),
Active(1),
Suspended(2);
private final int value;
private RelationActiveEnum(final int value) {
this.value = value;
}
}
}
and in another class I use:
int dbValue = supp.ACTIVE;
Extensions.RelationActiveEnum enumValue(dbValue);
String stringName = enumValue.toString(); //Visible
// OR
int dbValuee = supp.ACTIVE;
String stringValue = Enum.GetName(typeof(RelationActiveEnum), dbValue);
I should work, right? but it doesn't!!!! it tells me that dbValue cannote be cast to RelationActiveEnum...
Say we have:
public enum MyEnum {
Test1, Test2, Test3
}
To get the name of a enum variable use name():
MyEnum e = MyEnum.Test1;
String name = e.name(); // Returns "Test1"
To get the enum from a (string) name, use valueOf():
String name = "Test1";
MyEnum e = Enum.valueOf(MyEnum.class, name);
If you require integer values to match enum fields, extend the enum class:
public enum MyEnum {
Test1(1), Test2(2), Test3(3);
public final int value;
MyEnum(final int value) {
this.value = value;
}
}
Now you can use:
MyEnum e = MyEnum.Test1;
int value = e.value; // = 1
And lookup the enum using the integer value:
MyEnum getValue(int value) {
for(MyEnum e: MyEnum.values()) {
if(e.value == value) {
return e;
}
}
return null;// not found
}
Since your 'value' also happens to match with ordinals you could just do:
public enum RelationActiveEnum {
Invited,
Active,
Suspended;
private final int value;
private RelationActiveEnum() {
this.value = ordinal();
}
}
And getting a enum from the value:
int value = 1;
RelationActiveEnum enumInstance = RelationActiveEnum.values()[value];
I guess an static method would be a good place to put this:
public enum RelationActiveEnum {
public static RelationActiveEnum fromValue(int value)
throws IllegalArgumentException {
try {
return RelationActiveEnum.values()[value]
} catch(ArrayIndexOutOfBoundsException e) {
throw new IllegalArgumentException("Unknown enum value :"+ value);
}
}
}
Obviously this all falls apart if your 'value' isn't the same value as the enum ordinal.
You could create a lookup method. Not the most efficient (depending on the enum's size) but it works.
public static String getNameByCode(int code){
for(RelationActiveEnum e : RelationActiveEnum.values()){
if(code == e.value) return e.name();
}
return null;
}
And call it like this:
RelationActiveEnum.getNameByCode(3);
What you can do is
RelationActiveEnum ae = Enum.valueOf(RelationActiveEnum.class,
RelationActiveEnum.ACTIVE.name();
or
RelationActiveEnum ae = RelationActiveEnum.valueOf(
RelationActiveEnum.ACTIVE.name();
or
// not recommended as the ordinal might not match the value
RelationActiveEnum ae = RelationActiveEnum.values()[
RelationActiveEnum.ACTIVE.value];
By if you want to lookup by a field of an enum you need to construct a collection such as a List, an array or a Map.
public enum RelationActiveEnum {
Invited(0),
Active(1),
Suspended(2);
private final int code;
private RelationActiveEnum(final int code) {
this.code = code;
}
private static final Map<Integer, RelationActiveEnum> BY_CODE_MAP = new LinkedHashMap<>();
static {
for (RelationActiveEnum rae : RelationActiveEnum.values()) {
BY_CODE_MAP.put(rae.code, rae);
}
}
public static RelationActiveEnum forCode(int code) {
return BY_CODE_MAP.get(code);
}
}
allows you to write
String name = RelationActiveEnum.forCode(RelationActiveEnum.ACTIVE.code).name();
In my case value was not an integer but a String.
getNameByCode method can be added to the enum to get name of a String value-
enum CODE {
SUCCESS("SCS"), DELETE("DEL");
private String status;
/**
* #return the status
*/
public String getStatus() {
return status;
}
/**
* #param status
* the status to set
*/
public void setStatus(String status) {
this.status = status;
}
private CODE(String status) {
this.status = status;
}
public static String getNameByCode(String code) {
for (int i = 0; i < CODE.values().length; i++) {
if (code.equals(CODE.values()[i].status))
return CODE.values()[i].name();
}
return null;
}
If you want something more efficient in runtime condition, you can have a map that contains every possible choice of the enum by their value. But it'll be juste slower at initialisation of the JVM.
import java.util.HashMap;
import java.util.Map;
/**
* Example of enum with a getter that need a value in parameter, and that return the Choice/Instance
* of the enum which has the same value.
* The value of each choice can be random.
*/
public enum MyEnum {
/** a random choice */
Choice1(4),
/** a nother one */
Choice2(2),
/** another one again */
Choice3(9);
/** a map that contains every choices of the enum ordered by their value. */
private static final Map<Integer, MyEnum> MY_MAP = new HashMap<Integer, MyEnum>();
static {
// populating the map
for (MyEnum myEnum : values()) {
MY_MAP.put(myEnum.getValue(), myEnum);
}
}
/** the value of the choice */
private int value;
/**
* constructor
* #param value the value
*/
private MyEnum(int value) {
this.value = value;
}
/**
* getter of the value
* #return int
*/
public int getValue() {
return value;
}
/**
* Return one of the choice of the enum by its value.
* May return null if there is no choice for this value.
* #param value value
* #return MyEnum
*/
public static MyEnum getByValue(int value) {
return MY_MAP.get(value);
}
/**
* {#inheritDoc}
* #see java.lang.Enum#toString()
*/
public String toString() {
return name() + "=" + value;
}
/**
* Exemple of how to use this class.
* #param args args
*/
public static void main(String[] args) {
MyEnum enum1 = MyEnum.Choice1;
System.out.println("enum1==>" + String.valueOf(enum1));
MyEnum enum2GotByValue = MyEnum.getByValue(enum1.getValue());
System.out.println("enum2GotByValue==>" + String.valueOf(enum2GotByValue));
MyEnum enum3Unknown = MyEnum.getByValue(4);
System.out.println("enum3Unknown==>" + String.valueOf(enum3Unknown));
}
}
This is my take on it:
public enum LoginState {
LOGGED_IN(1), LOGGED_OUT(0), IN_TRANSACTION(-1);
private int code;
LoginState(int code) {
this.code = code;
}
public int getCode() {
return code;
}
public static LoginState getLoginStateFromCode(int code){
for(LoginState e : LoginState.values()){
if(code == e.code) return e;
}
return LoginState.LOGGED_OUT; //or null
}
};
And I have used it with System Preferences in Android like so:
LoginState getLoginState(int i) {
return LoginState.getLoginStateFromCode(
prefs().getInt(SPK_IS_LOGIN, LoginState.LOGGED_OUT.getCode())
);
}
public static void setLoginState(LoginState newLoginState) {
editor().putInt(SPK_IS_LOGIN, newLoginState.getCode());
editor().commit();
}
where pref and editor are SharedPreferences and a SharedPreferences.Editor