Reputation: 41
I'm working on a program which will generate a random month and year and then when it does will show what months are left over but just in this year for example 2016 January comes up so prints Feb-Dec 2016. I've created the random generation but I don't know how to create the line to show up whats left over.
public class months {
public static void main(String[] args) {
String[] years = {
"2017", "2016", "2015", "2104"
};
String[] months = {
"Januay", "Febuary", "March", "April", "May", "June", "july", "August"
, "september", "october"};
}
// initialize months
int i = (int) (Math.random() * months.length);
int j = (int) (Math.random() * years.length);
System.out.println(months[i] + " of " + years[j]);
System.out.println("The remaining months left in that suit are:");
//print out rest of remaining months in that year
}
}
any helps or tips would be greatly appreciated or could links where I could look to discover. Brand new to java and just playing around.
Upvotes: 4
Views: 823
Reputation: 338785
Loop through your array of month names. Start the loop at the randomly chosen element number rather than at 1
.
I revamped your code to use better variable names, and to fill your list of months to complete the year (you were missing Nov-Dec).
String[] years = {
"2017" , "2016" , "2015" , "2104"
};
String[] months = {
"Januay" , "Febuary" , "March" , "April" , "May" , "June" , "july" , "August" , "september" , "october" , "November" , "December" };
int n = years.length * months.length;
String[] deck = new String[ n ];
for ( int i = 0 ; i < months.length ; i++ )
{
for ( int j = 0 ; j < years.length ; j++ )
{
deck[ years.length * i + j ] = months[ i ] + " of " + years[ j ];
}
}
Generally better to use the newer ThreadLocalRandom
class for generating pseudo-random numbers rather than Math.Random
, especially if there is any chance of this code running in multiple threads. Beware that neither of those classes provide a cryptographically-strong random number, as noted in the class JavaDoc.
// Choose random month and random year.
int monthIndex = java.util.concurrent.ThreadLocalRandom.current( ).nextInt( 0 , months.length ); // ( inclusive , exclusive )
int yearIndex = java.util.concurrent.ThreadLocalRandom.current( ).nextInt( 0 , years.length ); // ( inclusive , exclusive )
System.out.println( months[ monthIndex ] + " of " + years[ yearIndex ] );
Now we can solve your problem. Loop the months
array, but instead of the first argument to the for
statement setting the counter to zero or one, set the counter to one past your randomly-chosen number.
Note that the chosen number might be the last month, index 11, for month of December. In such case there are no remaining months to report. So we add a test for this special case.
System.out.println( "The remaining months left in that suit are:" );
//print out rest of remaining months in that year
if ( monthIndex == months.length )
{
System.out.println( "No more months remaining after " + months[ monthIndex ] + " " + years[ yearIndex ] );
} else
{
// Loop through each of the remaining months.
// Strarting with first month *after* the chosen month, so adding one to the starting index.
for ( int m = ( monthIndex + 1 ) ; m < months.length ; m++ )
{
System.out.println( months[ m ] + " of year " + years[ yearIndex ] ); // Print chosen year with each remaining month.
}
}
october of 2017
The remaining months left in that suit are:
November of year 2017
December of year 2017
Having answered your direct question, let's look at a more pleasant and practical way to handle your problem using modern classes and collections rather than primitives and arrays.
We can use the Year
class for objects rather than mere numbers or strings.
We can use the Month
enum for objects rather than mere strings.
To represent the combination of a particular month in a particular year, we use the YearMonth
class.
We can use Set
interface and EnumSet
concrete implementation, and also List
/ArrayList
, rather than simple arrays.
// YEAR ***************
List < Year > years = new ArrayList <>( 4 );
years.add( Year.of( 2017 ) );
years.add( Year.of( 2016 ) );
years.add( Year.of( 2015 ) );
years.add( Year.of( 2014 ) );
int yearIndex = ThreadLocalRandom.current( ).nextInt( 0 , years.size( ) ); // ( inclusive , exclusive )
Year year = years.get( yearIndex );
// MONTH ***********
Set < Month > months = EnumSet.allOf( Month.class ); // EnumSet should be marked as implementing `SortedSet` but mysteriously is not. It does return its always in a particular order, in which defined in the Enum. So our months here will be ordered Jan-Dec as we expect.
int monthIndex = ThreadLocalRandom.current( ).nextInt( 0 , months.size( ) ); // ( inclusive , exclusive )
Month month = new ArrayList <>( months ).get( monthIndex ); // Make a `List` from `Set` to be able to conveniently pick a certain one by index number.
// YEAR-MONTH *************
YearMonth chosen = YearMonth.of( year.getValue() , month );
System.out.println("chosen: " + chosen );
// REMAINING ************
// Remaining year-month values to finish out the chosen year after the chosen month.
List < YearMonth > yearMonths = new ArrayList <>( months.size( ) - monthIndex ); // Collect results of our report generation.
Set < Month > remainingMonths = EnumSet.range( month , Month.DECEMBER );
for ( Month m : remainingMonths )
{
// Skip first month, as we want only the months *after* the chosen month.
if ( m.equals( month ) )
{
// Skip. No code needed here.
} else
{
yearMonths.add( YearMonth.of( year.getValue( ) , m ) ); // Instantiate a YearMonth object from our chosen year number and this nth remaining month of year.
}
}
// REPORT ******************
System.out.println( "yearMonths: " + yearMonths );
// Pretty-print the name of the month in English along with year number.
for ( YearMonth ym : yearMonths )
{
System.out.println( ym.getMonth( ).getDisplayName( TextStyle.FULL , Locale.US ) + " of " + ym.getYear( ) );
}
chosen: 2016-10
yearMonths: [2016-11, 2016-12]
November of 2016
December of 2016
Upvotes: 3