Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a good way to get ENUM values from a ENUM representing some Weekdays

Tags:

java

I have an ENUM with only 3 constant. Based on flag, named weekend, ENUM.values() should return either 3 or 2 constants.

public enum Weekday { 
    SUNDAY, MONDAY, TUESDAY;
}

public Weekday[] getDays() {
    boolean weekend = true;
    if (weekend){
        return Weekday.values() // this will reurn SUNDAY, MONDAY, TUESDAY
    } else { // when weekend is false
         return Weekday.values() // it should return on MONDAY, TUESDAY
      }
}

Please suggest, what is the a reasonable good approach to achieve this. I am able to achieve it with the below code. Unfortunately, the PR reviewer does not seem to be happy this that. Could you suggest a better approach?

My solution.

 EnumMap<Weekday, Integer> days= new EnumMap<>(Weekday.class);
    days.put(Weekday.MONDAY, 1);
    days.put(Weekday.TUESDAY, 2);

    return days.keySet().toArray(new Weekday[0]); // this returns MONDAY and TUESDAY.
like image 419
Rajesh Kumar Avatar asked Dec 22 '22 16:12

Rajesh Kumar


2 Answers

How about:

 public enum Weekday {
        SUNDAY, MONDAY, TUESDAY;
    }

    public Weekday[] getDays() {
        boolean weekend = callFromSomeAPI();
        return weekend ? Weekday.values() : new Weekday[] {Weekday.MONDAY, Weekday.TUESDAY};
    }

Of course, in a more typical use of the Enum Weekday would be to represent all the 7 days of the week, and using a variable (e.g., weekend or weekdays) to differentiate from week days and weekend days. Something like:

enum Weekday {
    MONDAY(false),
    TUESDAY(false),
    WEDNESDAY(false),
    THURSDAY(false),
    FRIDAY(false),
    SATURDAY(true),
    SUNDAY(true);

    private final boolean weekend;

    Weekday(boolean weekend) {
        this.weekend = weekend;
    }

    public static Weekday[] getDays(boolean weekend) {
        return Arrays.stream(values()).filter(i -> i.weekend == weekend).toArray(Weekday[]::new);
    }
}
like image 71
dreamcrash Avatar answered May 13 '23 07:05

dreamcrash


The Answer by dreamcrash is correct. I’ll add a few notes.

DayOfWeek

Java provides your enum in the java.time package: DayOfWeek.

No need to define your own Enum here for your purpose.

Non-modifiable List

Instead of an array, you can return a non-modifiable List using convenient methods List.of.

public List< DayOfWeek > getDays() {
    boolean weekend = callFromSomeAPI();
    return weekend ? List.of( DayOfWeek.SUNDAY , DayOfWeek.MONDAY, DayOfWeek.TUESDAY ) : List.of( Weekday.MONDAY, Weekday.TUESDAY );
}

Being non-modifiable, you can keep a single copy of each list as a static constant for repeated use.

static final List< DayOfWeek > WEEKEND = List.of( DayOfWeek.SUNDAY , DayOfWeek.MONDAY , DayOfWeek.TUESDAY ) ;
static final List< DayOfWeek > FIRST_WEEKDAYS = List.of( DayOfWeek.MONDAY , DayOfWeek.TUESDAY ) ;

…and…

public List< DayOfWeek > getDays() {
    boolean weekend = callFromSomeAPI();
    return weekend ? WEEKEND : FIRST_WEEKDAYS ;
}

With proper naming of such constants, your code gets shorter and more readable while your intentions become more obvious.

If the calling programmer really wants an array, they can call List::toArray.

… whatever.getDays().toArray( new DayOfWeek[0] ) …

EnumSet

The class EnumSet provides similar-looking of methods but:

  • are modifiable.
  • are highly optimized for holding enum objects, being fast to execute while taking very little memory.

The EnumSet iterator returns the enum in order of their enum definition. In DayOfWeek that order is MONDAY to SUNDAY per ISO 8601 standard. So this approach may not work for you if you were depending on Sunday being first (if so, stick to using a List).

Set< DayOfWeek > getDays( String flag )  
{
    if ( flag.equalsIgnoreCase( "weekend" ) ) // Better to use an enum as your flag rather than error-prone strings. 
    {
        return EnumSet.of( DayOfWeek.SUNDAY , DayOfWeek.MONDAY , DayOfWeek.TUESDAY ) ) ;  // Be aware: This EnumSet will iterate in Monday-Tuesday-Sunday order, the order of their definition in the Enum. 
    } else 
    {
        return EnumSet.of( DayOfWeek.MONDAY , DayOfWeek.TUESDAY ) ) ;
    }
}
like image 32
Basil Bourque Avatar answered May 13 '23 09:05

Basil Bourque