I am trying to test the day class using Junit Testing. This method is the method I am struggling with.
public Day previousDay() {
int y = year;
int m = month;
int d = date;
if (y == GREGORIAN_START_YEAR && m == GREGORIAN_START_MONTH
&& d == GREGORIAN_START_DAY)
d = JULIAN_END_DAY;
else if (d > 1)
d--;
else
{
m--;
if (m < JANUARY)
{
m = DECEMBER;
y--;
if (y == 0)
y--;
}
d = daysPerMonth(y, m);
}
return new Day(y, m, d);
}
This is what I have so far
public class DayTest extends TestCase
{
/**
* Test the constructor
*/
public void testDay()
{
//calling
Day today = new Day(2015,2,14);
assertEquals(2015,today.getYear());
assertEquals(2,today.getMonth());
assertEquals(14,today.getDate());
}
public void testAddDays()
{
Day today = new Day(2015,2,14);
int n = 5;
Day otherDay = today.addDays(n);
assertTrue(otherDay.daysFrom(today) == n);
}
public void testPreviousDays()
{
Day today = new Day(2015,2,14);
today.previousDay();
assertEquals(13,today.getDate());
}
public void testLeapYear()
{
Day today = new Day(2015,2,14);
assertEquals(today.isLeapYear(2015),false);
}
}
The other tests went smoothly but this test for previousday() is giving me trouble. When I call previousDay() it doesn't seem to work at all. I am confused why when the other tests worked fine. Any help would be appreciated!
You probably mean:
today = today.previousDay()
Right now you're ignoring the return value of the function.
Related
F(n):
if n >= 6:
F(n/3)
F(2*n/3)
print n
How would I turn this into a nonrecursive function? ive tried to use two while loops one for the n/3 case and one for the 2*n/3 case but nothing outputs the right things
public static void F2Stack(int n) {
Stack stack2 = new Stack();
int current = n;
int current2 = n;
while(current >= 6) {
current = current/3;
stack2.push(current);
}
while(current2 >= 6) {
current2 = current2*2/3;
stack2.push(current2/3);
stack2.push(current2*2/3);
stack2.push(current2);
}
while(!(stack2.isEmpty())){
System.out.println(stack2.pop());
}
}
Damn Corono Virus Lockdown! it took four or five hours today, but we got something. The hard part was java is not capable to do "go to label" I guess. Only you can do "continue/break label". Anyway hope this helps someone;
public static void main(String[] args) {
System.out.println("vvvv 18 recursive vvvv");
recursive(18);
System.out.println("vvvv 18 nonrecursive vvvv");
nonRecursive(18);
System.out.println("vvvv 25 recursive vvvv");
recursive(25);
System.out.println("vvvv 25 nonrecursive vvvv");
nonRecursive(25);
System.out.println("vvvv 31 recursive vvvv");
recursive(25);
System.out.println("vvvv 31 nonrecursive vvvv");
nonRecursive(25);
}
static void doJob(int n) {
System.out.println(n);
}
static void recursive(int number) {
if (number >= 6) {
recursive(number/3);
recursive(2*number/3);
}
doJob(number);
}
static void nonRecursive(int number) {
// a basic context
class Ctx {
int n, m;
boolean bn, bm;
public Ctx(int num) {
n = num / 3;
// do not try m = 2 * n :)
m = 2 * num / 3;
}
};
// how many times can we change the context?
// we will use here a bit math
int d = 2 * ((int)(Math.log(2 * number)/Math.log(3)) + 1);
Ctx[] ctx = new Ctx[d];
// current context
ctx[0] = new Ctx(number);
int i = 0;
while (number >= 6 && ctx[0] != null) {
// do n/3
if (ctx[i].n >= 6 && !ctx[i].bn) {
i++;
ctx[i] = new Ctx(ctx[i-1].n);
continue;
}
// we reached as deep as poosible for n/3
if (!ctx[i].bn) {
doJob(ctx[i].n);
ctx[i].bn = true;
}
// now do 2*n/3
if (ctx[i].m >= 6 && !ctx[i].bm) {
i++;
ctx[i] = new Ctx(ctx[i-1].m);
continue;
}
if (!ctx[i].bm) {
doJob(ctx[i].m);
ctx[i].bm = true;
}
// we are done with this context
ctx[i] = null;
if (i > 0) {
i--;
if (!ctx[i].bn) {
doJob(ctx[i].n);
ctx[i].bn = true;
} else if (!ctx[i].bm) {
doJob(ctx[i].m);
ctx[i].bm = true;
}
}
}
doJob(number);
}
I have 1 constructor and 1 factory method for my Date class. The first one just have 3 int parameter represent month, day and year. And the second one, I provide it in case user give string as one parameter to represent month/day/year.
As you can see in the main(), I forget to call parseIt, the factory method. But compiler still provide correct result. So question is: can JAVA call this factory method implicitly?
Please take a look the 1st constructor and 2nd factory methods:
import java.io.*;
class Date {
private int month;
private int day;
private int year;
public Date(int month, int day, int year) {
if (isValidDate(month, day, year)) {
this.month = month;
this.day = day;
this.year = year;
} else {
System.out.println("Fatal error: Invalid data.");
System.exit(0);
}
}
public static Date parseIt(String s) {
String[] strSplit = s.split("/");
int m = Integer.parseInt(strSplit[0]);
int d = Integer.parseInt(strSplit[1]);
int y = Integer.parseInt(strSplit[2]);
return new Date(m, d, y);
}
public static boolean isLeapYear(int year) {
if (year%4 != 0) {
return false;
} else if (year%100 == 0 && year%400 != 0) {
return false;
}
return true;
}
public static int daysInMonth(int month, int year) {
if (month == 2) {
if (isLeapYear(year)) {
return 29;
} else {
return 28;
}
} else if (month == 4 || month == 6 || month == 9 || month == 11) {
return 30;
} else {
return 31;
}
}
public static boolean isValidDate(int month, int day, int year) {
if (year < 1 || year > 9999 || month <= 0 || month > 12 || day <= 0) {
return false;
} else if (day > daysInMonth(month, year)) {
return false;
}
return true;
}
public static void main(String[] argv) {
Date d1 = new Date(1, 1, 1);
System.out.println("Date should be 1/1/1: " + d1);
d1 = new Date("2/4/2");
System.out.println("Date should be 2/4/2: " + d1);
}
}
No, it will not. There is no constructor which takes in a string, so it would throw a syntax error. In order to make it work, you would have to define a constructor which takes in a String parameter performs the same logic as the parseIt(String) function.
I am currently designing a GUI for a bank database application. In my GUI I have a "List accounts opened before" button that I am trying to code to list all of the accounts in the database in a text area that have dates before a date that the user inputs into a text field. I am very confused about the implementation behind a Comparable interface and how to correctly compare two dates in a array of objects. In my mind my ShowBefore methods logic is correct, however I think that is not the case and I do not know why. My problem is with the BankDatabase's showBefore() method, Date's compareTo() method, and the GUI's ShowAllActions button. Any help would be greatly appreciated. I receive
"Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at BankDatabase.showBefore(BankDatabase.java:234)
at TransactionManager.showAllAccountsActionPerformed(TransactionManager.java:474)
at TransactionManager.access$1200(TransactionManager.java:17)
at TransactionManager$13.actionPerformed(TransactionManager.java:202)
"
When I input any date into the gui.
*I only posted the bare minimum methods required
public class BankDatabase
{
private static final int GROW_SIZE = 2;
private static final int NOT_FOUND = -1;
private static final int ARRAY_SIZE = 100; //i added this
private Account[] bank;
private int num;
/**
default constructor
*/
public BankDatabase()
{
num = 0;
bank = new Account[ARRAY_SIZE];
}
public String showBefore( Date prevDate)
{
String temp = new String();
for ( int i = 0; i < size(); i++)
{
if ( bank[i].getDate().compareTo(prevDate) == -1 )
{
temp += bank[i].toString(); //
temp += "\n";
}
}
return temp;
}
import java.util.Calendar;
import java.util.StringTokenizer;
public class Date implements Comparable {
private int invalidCheck = 0;
private int day;
private int month;
private int year;
/**
Parameterized Constructor.
#param d date
*/
public Date(String d)
{
StringTokenizer st = new StringTokenizer(d, "/");
month = Integer.parseInt(st.nextToken());
day = Integer.parseInt(st.nextToken());
year = Integer.parseInt(st.nextToken());
}
/**
Copy Constructor.
#param d date
*/
public Date(Date d)
{
month = d.month;
day = d.day;
year = d.year;
}
/**
Creates an instance with todays date
*/
public Date()
{
Calendar c = Calendar.getInstance();
this.day = c.get(Calendar.DAY_OF_MONTH);
this.month = c.get(Calendar.MONTH) + 1;
this.year = c.get(Calendar.YEAR);
}
/**
Compare “this” with (Date) o; if “this” is before o, return -1; if “this” is equal
to o return 0; if “this” is after o, return 1.
#param o
#return the value of the date
*/
public int compareTo(Object o)
{
Date d = new Date((Date) o);
if(d.year > year)
return -1;
if(d.year < year)
return 1;
if(d.month > month)
return -1;
if(d.month < month)
return 1;
if(d.day > day)
return -1;
if(d.day < day)
return 1;
return 0;
}
/**
checks to see if certain dates are valid. Also checks
if it is a leap year to verify the correct amount of days
in February.
#return true if the date is valid, false otherwise
*/
public boolean isValid()
{
if (( month == Month.JAN || month == Month.MAR
|| month == Month.MAY || month == Month.JUL
|| month == Month.OCT || month == Month.OCT
|| month == Month.DEC )
&& ( day <= Month.DAYS_ODD && day > invalidCheck ) )
return true;
if (( month == Month.APR || month == Month.JUN
|| month == Month.SEP
|| month == Month.NOV )
&& ( day <= Month.DAYS_EVEN && day > invalidCheck ) )
return true;
boolean leapYear = false;
if ( year % Month.QUADRENNIAL == invalidCheck
|| year % Month.CENTENNIAL == invalidCheck
|| year % Month.QUATERCENTENNIAL == invalidCheck )
{
leapYear = true;
}
if (leapYear)
{
if (month == Month.FEB && day <= Month.DAYS_FEB + 1)
return true;
}
if (month == Month.FEB && day <= Month.DAYS_FEB)
return true;
return false;
}
/**
Return the name and date of the TeamMember as a String.
#return name::price as a string.
*/
public String toString()
{
return month + "/" + day + "/" + year;
}
/**
day,month, and year are equal if they have the
same day, month, and year
#param obj
#return true if they are equal, false otherwise.
*/
public boolean equals(Object obj)
{
if (obj instanceof Date)
{
Date d = (Date) obj;
return d.day == day && d.month == month && d.year == year;
}
return false;
}
}
public abstract class Account
{
private static int numAccount = 1000; //incremented by 1 for each acc op.
protected final int PERCENTAGE = 100;
protected final int MONTH_PER_YEAR = 12;
protected Profile holder; //account holder's profile
protected int accNumber; //a sequence number from numAccount
protected double balance;
protected Date openOn; //the date the account is opened on
/**
parameterized constructor
#param name String that will be the name
#param phone String that will be the phone associated with the account
*/
public Account(String name, String phone)
{
holder = new Profile(name, phone);
accNumber = numAccount++;
balance = 0;// 0 if deposit has to happen after
openOn = new Date();
}
public Date getDate()
{
return openOn;
}
public abstract String toString(); //subclass must implement this method
public class TransactionManager extends javax.swing.JFrame
{
BankDatabase database = new BankDatabase();
TransactionSimulator sim = new TransactionSimulator();
ButtonGroup accType = new ButtonGroup();
private Vector client;
/**
Creates new form TransactionManager
*/
public TransactionManager()
{
initComponents();
database = new BankDatabase();
accType.add(checking);
accType.add(savings);
accType.add(moneyMarket);
cbSpecialSavings.setEnabled(false);
client = new Vector<String>();
}
private void showAllAccountsActionPerformed(java.awt.event.ActionEvent evt)
{
Date openOn = new Date(dateBefore.getText());
outputArea.append(database.showBefore(openOn));
}
About your showBefore() at least make some additional checks
public String showBefore( Date prevDate)
{
StringBuilder builder = new StringBuilder("");
for ( int i = 0; i < size(); i++)
{
Account account = bank[i];
if (account != null) {
Date date = account.getDate();
if (date != null && date.compareTo(prevDate) == -1 ) {
builder.append(account.toString() + "\n")
}
}
}
return builder.toString();
}
and keep in mind what StringBuilder is not synchronized
In other case read more about Java 8 features such as Stream API, New Date/Time API, lambda
public String showBefore(LocalDate prevDate)
{
StringBuilder builder = new StringBuilder("");
Arrays.asList(bank).parallelStream().forEach(account -> {
if (account != null) {
LocalDate date = account.getDate();
if (date != null && date.compareTo(prevDate) == -1 ) {
builder.append(account.toString()).append("\n");
}
}
});
return builder.toString();
}
if(d.month > month)
return -1;
if(d.month > month)
return 1;
You have equivalent if clauses in equals method.
I'n my application i want to sort the "MyDate" class so, my teacher show me how to sort but how can i compare years first and then the rest?
Comparator<MyDate > dateCompare = new Comparator<MyDate >() {
#Override
public int compare(MyDate o1, MyDate o2) {
int dd1 = o1.getDateDay();
int mm1 = o1.getDateMonth();
//////years to compare ???????????????????
int years1 = o1.getYear();
int dd2 = o2.getDateDay();
int mm2 = o2.getDateMonth();
//////years to compare ?????????????????
int years2 = o2.getYear();
if (mm1 > mm2) {
return 1;
} else if (mm1 < mm2) {
return -1;
} else { // ==
if (dd1 > dd2) {
return 1;
} else if (dd1 < dd2) {
return -1;
} else {
return 0;
}
}
}
};
Collections.sort(list,dateCompare);
Compare the most significant field first. With a Date that is year.
Also, there is no need for a trailing else since the if and else if conditions return. Something like
if (years1 > years2) {
return 1;
} else if (years1 < years2) {
return -1;
}
if (mm1 > mm2) {
return 1;
} else if (mm1 < mm2) {
return -1;
}
if (dd1 > dd2) {
return 1;
} else if (dd1 < dd2) {
return -1;
}
return 0;
You could use the before() method of Date objects to compare the dates, it'll make writing code for your task very simple. Of course, that means that you have to convert your MyDate objects to Date but it should be very easy.
You can use the built-in functionality of the GregorianCalendar class to do this in a single line.
return new GregorianCalendar(years1, mm1 - 1, dd1).compareTo(new GregorianCalendar(years2, mm2 - 1, dd2));
Note that the - 1 in the month arguments are needed because the GregorianCalendar constructor uses a month value in the range of 0 to 11.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
why am i getting the following error message when i call the toString of class Date from toString of class Time2 ?
Exception in thread "main" java.lang.NullPointerException
at Exerciseschpt8.Time2.toString(Time2.java:111)
at Exerciseschpt8.Time2Test.main(Time2Test.java:18)
package Exerciseschpt8;
public class Date{
private int month; // 1-12
private int day; // 1-31 based on month
private int year; // any year
public Date(){
this(0,0,0);
}
public Date(int theMonth, int theDay, int theYear) {
month = checkMonth(theMonth); // validate month
year = theYear; // could validate year
day = checkDay(theDay); // validate day
System.out.printf("Date object constructor for date %s\n", this);
}
private int checkMonth(int month) {
if (month > 0 && month <= 12) // validate month
return month;
else // month is invalid
{
System.out.printf("Invalid month (%d) set to 1.", month);
return 1; // maintain object in consistent state
} // end else
} // end method checkMonth
// utility method to confirm proper day value based on month and year
private int checkDay(int day) {
int[] daysPerMonth = { 0, 31, 28, 31, 30, 31, 30, 28, 31, 30, 31, 30,
31 };
// check if day in range for month
if (day > 0 && day <= daysPerMonth[month])
return day;
// check for leap year
if (month == 2 && day == 29
&& (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)))
return day;
System.out.printf("Invalid day (%d) set to 1.", day);
return 1; // maintain object in consistent state
} // end method checkDay
// return a String of the form month/day/year
public String toString() {
return ""+month+"/"+ day+"/"+year;
} // end method toString
public int nextDay() {
int testDay = day + 1;
if (checkDay(testDay) == testDay)
day = testDay;
else {
day = 1;
//nextMonth();
}
return day;
}
public int nextMonth() {
if (1 == month)
month++;
return month = 1;
}
public String toDateString() {
return month + "/" + day + "*/" + year;
}
}
package Exerciseschpt8;
import Exerciseschpt8.Date;
public class Time2 {
Date dateX;
private int hour; // 0 - 23
private int minute; // 0 - 59
private int second; // 0 - 59
public Time2() {
this(0, 0, 0);
}
public Time2(int h) {
this(h, 0, 0);
}
public Time2(int h, int m) {
this(h, m, 0);
}
public Time2(int h, int m, int s) {
setTime(h, m, s);
}
public Time2(Time2 time) {
this(time.getHour(), time.getMinute(), time.getSecond());
}
public boolean setTime(int h, int m, int s) {
boolean hourValid, minuteValid, secondValid;
hourValid = setHour(h); // set the hour
minuteValid = setMinute(m); // set the minute
secondValid = setSecond(s); // set the second
return (hourValid && minuteValid && secondValid);
}
public boolean setHour(int h) {
// hour = ((h >= 0 && h < 24) ? h : 0);
if (h >= 0 && h < 24) {
hour = h;
return true;
} else {
hour = 0;
return false;
}
} // end method setHour
public boolean setMinute(int m) {
// minute = ((m >= 0 && m < 60) ? m : 0);
if (m >= 0 && m < 60) {
minute = m;
return true;
} else {
minute = 0;
return false;
}
} // end method setMinute
public boolean setSecond(int s) {
// second = ((s >= 0 && s < 60) ? s : 0);
if (s >= 0 && s < 60) {
second = s;
return true;
} else {
second = 0;
return false;
}
} // end method setSecond
public int getHour() {
return hour;
} // end method getHour
public int getMinute() {
return minute;
} // end method getMinute
public int getSecond() {
return second;
} // end method getSecond
// Tick the time by one second
public void tick() {
setSecond(second + 1);
if (second == 23)
incrementMinute();
}
public void incrementMinute() {
setMinute(minute + 1);
if (minute == 25)
incrementHour();
}
public void incrementHour() {
setHour(hour + 1);
if (hour == 0)
dateX.nextDay();
}
public String toString() {
return + hour + ":" + minute + ":" + second + "\n"+dateX.toString();
}
package Exerciseschpt8;
public class Time2Test {
public static void main(String[] args) {
Time2 t1 = new Time2(2,15,23); // 00:00:00
/
Date d1 = new Date(10,23,1973);
//System.out.println(d1.toDateString());
System.out.println("Constructed with:");
System.out.println("t1: all arguments defaulted");
//System.out.printf(" %s\n", t1.toUniversalString());
System.out.printf(" %s\n", t1.toString());
}
}
You are nowhere initializing dateX in your Time2 class and using a method on it (dateX.toString()) in the toString() method of Time2 class. That is causing the valid NullPointerException.
To fix the issue, intialize dateX as appropriate to your program.
In the line Date dateX; you are declaring dateX, but you aren't initializing it, so it's a null pointer. To initialize it, change the line to Date dateX = new Date();