简体   繁体   中英

Efficieny with switch Statements, Java

I recently worked on a program that asked the user for his age in: years, months, and days.

After receiving that input, it had to calculate and print

a) Age in Seconds (totalAgeInSecs) and

b) the Amount of Seconds left to live. b is going to be based on the average lifespan in seconds (avgLifeSpan = 250000000000l. So secondsLeft = avgLifeSpan - totalAgeInSecs) .

Anyway,I was able to get the program to work utilizing (switch) statements for simplicity purposes and not having to write a bunch of if/else statements, but I feel that in doing that, I ended up writing repetitive lines, and I'd like to be able to not have to repeat the calculation or the print statements.

I know there are classes and arrays I can combine with loops, but for the sake of simplicity and logic understanding I didn't use them to understand the bareback bones and logic of this project in "English." haha.

Anyway, check the code out below and let me know your thoughts on how to simplify the repetitive lines or better ways of approaching this. Thanks.

import java.util.*;

public class AgeInSeconds {

    static Scanner kbd = new Scanner(System.in);
    public static void main(String[] args) {

        int totalNumDays, daysInMonth, daysToHours;
        int yrsToDays,minsInHr, secsInMin;

        long timeRemaining, avgLifeSecs;

        System.out.println("Enter your age in years months and days: ");

        System.out.print("Years: ");
        int years = kbd.nextInt();

        System.out.print("Months: ");
        int months = kbd.nextInt();

        System.out.print("Days: ");
        int days = kbd.nextInt();

        yrsToDays = years * 365;
        avgLifeSecs = 2500000000l;

        switch (months){
        case 1: 
            daysInMonth = 31;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;

            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);           
            break;
        case 2: 
            daysInMonth = 59;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;    

            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);
            break;      
        case 3: 
            daysInMonth = 90;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;

            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);
            break;      
        case 4: 
            daysInMonth = 120;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;

            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);
            break;      
        case 5:
            daysInMonth = 151;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;

            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);
            break;      
        case 6: 
            daysInMonth = 181;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;
            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);           
            break;      
        case 7: 
            daysInMonth = 212;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;
            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);       
            break;      
        case 8: 
            daysInMonth = 243;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;
            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);

            break;

        case 9: 
            daysInMonth = 273;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;
            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);           
            break;      
        case 10: 
            daysInMonth = 304;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;
            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);           
            break;          
        case 11: 
            daysInMonth = 334;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;
            timeRemaining = avgLifeSecs - secsInMin;

            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);
            break;      
        case 12:
            daysInMonth = 365;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;

            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);

        default:

        }

        kbd.close();    

    }


}

This is the output when: years = 24, months = 5, days = 8.

Enter your age in years months and days: 
Years: 24
Months: 5
Days: 8
You have been alive for 770,601,600 seconds.
The average human life is  2,500,000,000 seconds.
You have  1,729,398,400 seconds.

To correctly calculate how many days the user is alive, you should first calculate his birthdate based on the supplied data and today's date. For example:

  • User is 1 month old, current date is Sept 28th 2015, thus user was born at Aug 28th 2015 and he is 31 days old.
  • User is 1 month old, current date is March 2nd 2015, thus user was born at Feb 2nd 2015 and he is 28 days old.

After that you can calculate the difference in seconds. There are ready classes and methods in Java API to do these steps. The easiest is to use Java 8 Time API:

import java.time.LocalDateTime;
import java.time.Period;
import java.time.temporal.ChronoUnit;
import java.util.Scanner;

public class AgeInSeconds {

    public static void main(String[] args) {
        try (Scanner kbd = new Scanner(System.in)) {

            System.out.println("Enter your age in years months and days: ");

            System.out.print("Years: ");
            int years = kbd.nextInt();

            System.out.print("Months: ");
            int months = kbd.nextInt();

            System.out.print("Days: ");
            int days = kbd.nextInt();

            Period period = Period.of(years, months, days);
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime birthDate = now.minus(period);
            long seconds = birthDate.until(now, ChronoUnit.SECONDS);
            long avgLifeSecs = 2500000000l;
            long timeRemaining = avgLifeSecs - seconds;

            System.out.printf("You have been alive for %,d seconds.\n", seconds);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);
        }
    }
}

I'm not addressing the statistical problem here. To calculate estimate remaining lifespan (provided I'm an average person) you should average the lifespan of the people who died older than me.

Your integer daysInMonth will transfer past the switch statement. So you can just utilise the repetitive code after the switch statement.

As a rule of thumb: When you have repeating code put it in it's own method, or cosolidate the code so you only need to call it at one spot.

import java.util.*;

public class AgeInSeconds {

static Scanner kbd = new Scanner(System.in);
public static void main(String[] args) {

    int totalNumDays, daysInMonth, daysToHours;
    int yrsToDays,minsInHr, secsInMin;

    long timeRemaining, avgLifeSecs;

    System.out.println("Enter your age in years months and days: ");

    System.out.print("Years: ");
    int years = kbd.nextInt();

    System.out.print("Months: ");
    int months = kbd.nextInt();

    System.out.print("Days: ");
    int days = kbd.nextInt();

    yrsToDays = years * 365;
    avgLifeSecs = 2500000000l;

    switch (months){
    case 1: 
        daysInMonth = 31;
        break;
    case 2: 
        daysInMonth = 59;
        break;      
    case 3: 
        daysInMonth = 90;
        break;      
    case 4: 
        daysInMonth = 120;
        break;      
    case 5:
        daysInMonth = 151;
        break;      
    case 6: 
        daysInMonth = 181;
        break;      
    case 7: 
        daysInMonth = 212;
        break;      
    case 8: 
        daysInMonth = 243;
        break;

    case 9: 
        daysInMonth = 273;
        break;      
    case 10: 
        daysInMonth = 304;
        break;          
    case 11: 
        daysInMonth = 334;
        break;      
    case 12:
        daysInMonth = 365;
        break;
    default:
        daysInMonth = 0;
    }
    totalNumDays = yrsToDays + daysInMonth + days;
    daysToHours = totalNumDays * 24;
    minsInHr = daysToHours * 60;
    secsInMin = minsInHr * 60;

    timeRemaining = avgLifeSecs - secsInMin;

    System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
    System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
    System.out.printf("You have  %,d seconds.\n", timeRemaining);           

    kbd.close();    

}


}

The above is a "quick and dirty" solution to your code so you can see how you can transfer variables past an switch statement.

Better practise it would be to use an modulus operator to check if it's odd or even and if it's not month two, give the correct value.

import java.util.*;

public class AgeInSeconds {

static Scanner kbd = new Scanner(System.in);
public static void main(String[] args) {

    int totalNumDays, daysInMonth, daysToHours;
    int yrsToDays,minsInHr, secsInMin;

    long timeRemaining, avgLifeSecs;

    System.out.println("Enter your age in years months and days: ");

    System.out.print("Years: ");
    int years = kbd.nextInt();

    System.out.print("Months: ");
    int months = kbd.nextInt();

    System.out.print("Days: ");
    int days = kbd.nextInt();

    yrsToDays = years * 365;
    avgLifeSecs = 2500000000l;
    /** predifine with 0 so we always have a value **/
    daysInMonth = 0;
    /** Our months here. Please consider using calendar **/
    int[] legaldays =  {31,28,31,30,31,30,31,31,30,31,30,31};
    /** Looping through all months **/
    for(i=0;i<legaldays.length;i++) { 
       /** check if we didn't pass our max limit **/
       if(i+1 > daysInMonth) {
          break;
       }
       /** add the days to our tally **/
       daysInMonth += legaldays[i];
    }
    totalNumDays = yrsToDays + daysInMonth + days;
    daysToHours = totalNumDays * 24;
    minsInHr = daysToHours * 60;
    secsInMin = minsInHr * 60;

    timeRemaining = avgLifeSecs - secsInMin;

    System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
    System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
    System.out.printf("You have  %,d seconds.\n", timeRemaining);           

    kbd.close();    

   }    
}

See the comments to know how I improved it. By looping you take yourself off the headache of having to hardcode the values of the months days and it gives you an amount of flexibility. For a more reliable day count instead of hardcode I suggest you look at Number of days in a month of a particular year so you can be flexible with leap years and such.

When ever possible try to not hardcode intangible or dynamic data values, but try to deduct them accurately. Dates are notoriously hard to keep in order.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM