NewProgrammerMR NewProgrammerMR - 2 months ago 9
Java Question

Java Using strings from within a switch statement

I have the following code

switch (dayCurrent) {
case 0:
String today_sun = "Today is Sunday";
break;
case 1:
String today_mon = "Today is Monday";
break;
case 2:
String today_tues = "Today is Tuesday";
break;
case 3:
String today_wed = "Today is Wednesday";
break;
case 4:
String today_thurs = "Today is Thursday";
break;
case 5:
String today_fri = "Today is Friday";
break;
case 6:
String today_sat = "Today is Saturday";
break;
// If statement for invalid entry
default: if (dayCurrent >= 7) {
System.out.println("Invalid day entered");
}
}
// Switch statements to display future day
if (dayCurrent < 7) {
switch (dayFinal) {
case 0:
String future_sun = dayFuture + " day(s) later it is Sunday";
break;
case 1:
String future_mon = dayFuture + " day(s) later is Monday";
break;
case 2:
String future_tues = dayFuture + " day(s) later is Tuesday";
break;
case 3:
String future_wed = dayFuture + " day(s) later is Wednesday";
break;
case 4:
String future_thurs = dayFuture + " day(s) later is Thursday";
break;
case 5:
String future_fri = dayFuture + " day(s) later is Friday";
break;
case 6:
String future_sat = dayFuture + " day(s) later is Saturday";
break;


If I wanted to create a System.out.println that showed the results of both switches, how would I go about doing this?
I know this code appeared here before: Java (Find the future date with if else statements) , and that it would be easier to do System.out.print, but I'm curious on how to do the above for future reference.

Answer

Concatenation

When piecing together multiple strings across your code, concatenate them. There are multiple ways to do this in Java.

The + sign combines String objects. Each String object is immutable, meaning you to do not change (“mutate”) its value. Instead a new instance is born combining the original value and the newly added String object.

String message = "My name is ";
message = message + "Basil";
message = message + "."; 
System.out.println( message );  // My name is Basil.

Another way is to call append on an object of any class that implements the Appendable interface.

StringBuilder is the Appendable implementation appropriate to your situation.

StringBuilder message = new StringBuilder( "My name is " );
message.append( "Basil" );
message.append( "." ); 
System.out.println( message.toString() );  // My name is Basil.

Caveat: Use StringBuilder only where thread-safety is not a problem. When your Appendable object may be accessed across more than one thread, use StringBuffer instead.

For more information on the various kinds of string-related objects with a nifty chart to make sense of them, see my Answer to the Question, Exact difference between CharSequence and String in java.

DayOfWeek

The DayOfWeek enum holds seven instances, one for each day of the week. Getting today’s day-of-week means getting today’s date, and that requires a time zone. For any given moment, the date varies around the globe by zone.

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
DayOfWeek dow = DayOfWeek.from( today );  // `dow` is an *object*, not mere text like `Monday` or mere integer number like `1`.

Using objects of this enum rather than mere integers to represent a day-of-week makes your code more self-documenting, provides type-safety, and ensures valid values.

Define text object outside switch block

The main problem in the Question’s code is that the variable holding the String is defined inside the switch case; that variable goes out of scope upon exiting the switch case, and immediately becomes a candidate for garbage collection (your string object goes away and is destroyed, cleared from memory, in other words) before you ever got a chance to concatenate or print your text content.

So this code:

switch (dayCurrent) {
    case 0: 
            String today_sun = "Today is Sunday";
            break;
    case 1: 
            String today_mon = "Today is Monday";
            break;
…

…should have been:

String today = null;

switch (dayCurrent) {
    case 0: 
            today = "Today is Sunday";
            break;
    case 1: 
            today = "Today is Monday";
            break;
…

But, even better, we can replace that String object with an Appendable: StringBuilder.

StringBuilder

When concatenating more than a few strings, and thread-safety is not a problem in your context, use StringBuilder class.

Note that we define this StringBuilder object named message outside the switch block. Defining outside the switch means the object survives, existing before, during, and after the switch does its job.

StringBuilder message = new StringBuilder();

switch ( dow ) {
    case DayOfWeek.MONDAY:
    case DayOfWeek.TUESDAY: 
    case DayOfWeek.WEDNESDAY: 
    case DayOfWeek.THURSDAY:  
    case DayOfWeek.FRIDAY: 
        message.append( "Weekday - Working for a living. " );
        break;

    case DayOfWeek.SATURDAY:
    case DayOfWeek.SUNDAY: 
        message.append( "Wohoo! Weekend… Party on Garth! " );
        break;

    default: 
        System.out.println("ERROR - Unexpectedly reached case DEFAULT on value for DayOfWeek 'dow'.");
    }

The dayFuture part of your code makes no sense to me, and seems irrelevant to your question of piecing together text across multiple switch blocks. So I will use a nonsense whatever switch.

switch ( whatever ) {
    case thisThing: 
        message.append( "Use vanilla." );
        break;

    case thatThing: 
        message.append( "Use chocolate." );
        break;

    case theOtherThing: 
        message.append( "Use almond." );
        break;

    default: 
        System.out.println("ERROR - Unexpectedly reached case DEFAULT on value for whatever.");
    }

Now we have built up a message made of multiple components. We can output that to System.out.

System.out.println( message.toString() ); // Outputs day-of-week text combined with flavor text.

Weekday - Working for a living. Use chocolate.

Date math

As for adding days to a date to get another date, simply call the plus… or minus… methods.

If the user inputs a String of digits, parse as a number for the count of days to add.

Integer days = Integer.valueOf( "4" );

Add that number of days.

LocalDate future = today.plusDays( days );

If passing around this elapsed time, use a TemporalAmount such as Period or Duration object rather than mere integer.

Period period = Period.ofDays( days );
LocalDate future = today.plus( period );

To see that future date’s day-of-week, fetch a DayOfWeek enum object. No need for a switch.

DayOfWeek dow = DayOfWeek.from( future );

You can ask the DayOfWeek for its localized name. Call DayOfWeek::getDisplayName. Pass TextStyle to specify the length or abbreviation. And pass a Locale to specify the human language for translation and the cultural norms for deciding issues such as punctuation and ordering of the parts.

String dowName = 
    dow.getDisplayName( 
        TextStyle.FULL_STANDALONE , 
        Locale.CANADA_FRENCH );