Constructor not setting values? Get method not working [duplicate] - java

When I try to run this program, the result is always null, 0 0. Why do the values of monthName, day, and year not show up when the getDay() method is invoked and printed on the screen.
public class Assignment1 {
public static void main(String[] args) {
//creates an array of type Date filled with two LongDate objects
Date [] collectionOfDates = { new LongDate("February",2,1996), new LongDate("February",13,1999) };
// loops through the array and displays output of getDate() for each object
for( int i = 0; i < collectionOfDates.length; i++ ) {
System.out.println( collectionOfDates[i].getDate() );
}
}
}
For your information, the LongDate class is a subclass of the Date class which contains methods editDay() and editYear() along with several others. The LongDate method is listed below.
Any help greatly appreciated, Thanks. Also, feel free to comment if you want more information.
public class LongDate extends Date {
private String monthName;
private int day;
private int year;
public LongDate() {
}
public LongDate(String m, int d, int y) {
super.editday(d);
super.edityear(y);
editMonth(m);
}
public void setDate(String m, int d, int y) {
monthName = m;
day = d;
year = y;
}
public String getDate() {
StringBuilder fullDate = new StringBuilder();
fullDate.append(monthName);
fullDate.append(" ");
fullDate.append(day);
fullDate.append(", ");
fullDate.append(year);
return fullDate.toString();
}
public String getShortDate() {
int month = 0;
if (monthName == "January") {
month = 1;
} else if (monthName == "February") {
month = 2;
} else if (monthName == "March") {
month = 3;
} else if (monthName == "April") {
month = 4;
} else if (monthName == "May") {
month = 5;
} else if (monthName == "June") {
month = 6;
} else if (monthName == "July") {
month = 7;
} else if (monthName == "August") {
month = 8;
} else if (monthName == "September") {
month = 9;
} else if (monthName == "October") {
month = 10;
} else if (monthName == "November") {
month = 11;
} else if (monthName == "December") {
month = 12;
}
StringBuilder shortDate = new StringBuilder();
shortDate.append(month);
shortDate.append("/");
shortDate.append(day);
shortDate.append("/");
shortDate.append(year);
return shortDate.toString();
}
protected String editMonth(String m) {
// asks person to try again if month is not capitalized and spelled properly
if (m != "January" && m != "February" && m != "March" && m != "April" && m != "May" && m != "June" && m != "July" && m != "August" && m != "September" && m != "October" && m != "November" && m != "December") {
m = Input.getString( "Invalid month. Please type the month again." );
return m;
} else
return m;
}
}

There's nothing in the constructor of LongDate which sets the fields (monthName, day, and year) that getDate() reads.
I assume that the Date#editDay() and Date#editYear() functions look similar to LongDate#editMonth(). Note that editMonth() does not assign a value to the monthName field!

You should compare your strings with equals() and not ==. The equals() method compares string values, whereas == compares object references, which is not what you want here. So change:
if (monthName == "January") {
to:
if (monthName.equals("January")) {
and similarly for the other comparisons.

Couple of issues. First:
public LongDate(String m, int d, int y) {
super.day(d);
super.year(y);
editMonth(m);
}
You don't show Date so it is unclear to us what day() and year() are supposed to do, but regardless:
public class LongDate extends Date {
private String monthName;
private int day;
private int year;
...
}
Your declarations of these fields are hiding any similar fields that the base presumably has. In any case, at no point in your constructor are you setting this.day or this.year to anything, and so, of course, they remain at their initial value of 0.
You need to clean up your code a bit. Either refer to the correct day and year, or make sure you are setting and getting the base class' version of those fields instead of redeclaring them in the subclass (again, not sure what your base implementation does).
You may want to have a look at the official tutorial on Inheritance. It's concise and well-written and covers topics like overriding methods, hiding fields, etc. I think it will give you a good starting point for solving your issues here.
And, of course, comparing strings with == here will lead to other issues in the future: How do I compare strings in Java?

Your editMonth method returns a string, instead it should set the month:
monthName = m;
Another option is to keep the editMonth method the same, but in your constructor put:
monthName = editName(m);

Related

Input Validation Algorithm - Date and Odometer

I'm having a problem making an efficient algorithm that validates my date and odometer input within a given sorted data set. I'm trying to implement a gas mileage tracking program. The sorted data has a date with corresponding odometer value.
Sample Data Set:
Date Odometer Index
2021-2-14 156830 0
2021-2-5 156572 1
2021-2-4 156255 2
Index 0 being the top and recent data entry.
Sample Input:
Date: 2021-2-15
Odometer: 157000
I have to determine which position/order the inputted date belongs inside my data set. Since the user date input is greater than my top/recent date I know this belongs to the very top. Then I compare the odometer from that data to my input. If user odometer input is greater than data odometer then it is valid. If its less than then its invalid.
Another Sample Input:
Date: 2021-2-14
Odometer: 156255
Its okay if the user date input has the same date given in the data set. However, odometer cannot be less than the previously recorded at 156572 on 2021-2-5. So its invalid.
Here is my test input validation algorithm so far:
public static Date[] dates = new Date[3];
public static int[] odometer = new int[3];
public static void main(String[] args)
{
dates[0] = new Date(2021,2,14);
dates[1] = new Date(2021,2,5);
dates[2] = new Date(2021,2,4);
odometer[0] = 156830;
odometer[1] = 156572;
odometer[2] = 156255;
//Inputs
Date inputDate = new Date(2021,2,14);
int inputOdo = 156255;
if(!hasDuplicate(inputDate, inputOdo))//Checks for duplicate
{
int index = -1;
for(int i=0; i<dates.length; i++)
{
if(inputDate.compareTo(dates[i]) >= 0)
{
index = i;
break;
}
}
if(index == 0)
{
if(inputOdo <= odometer[index] && inputDate.compareTo(dates[index]) > 0)
{
System.out.println("Mileage cannot be less than "
+ "your previously recorded fill-up at\n"+odometer[index]+" miles on "+dates[index].toString()+".\n");
}
}else{
if(index > 0)
{
int top = index-1;
int bottom = index;
if(inputOdo >= odometer[top])
{
System.out.println("Mileage cannot be higher than "
+ "your previously recorded fill-up at\n"+odometer[top]+" miles on "+dates[top].toString()+".\n");
}else{
if(inputOdo <= odometer[bottom] && bottom != dates.length-1 && !inputDate.equals(dates[bottom]))
{
System.out.println("Mileage cannot be less than "
+ "your previously recorded fill-up at\n"+odometer[bottom]+" miles on "+dates[bottom].toString()+".\n");
}
}
}else{
int bottom = dates.length-1;
if(inputOdo >= odometer[bottom])
{
System.out.println("Mileage cannot be higher than "
+ "your previously recorded fill-up at\n"+odometer[bottom]+" miles on "+dates[bottom].toString()+".\n");
}
}
}
System.out.println("Gas has been added!");
}else{
System.out.println("Another fill-up with this date and mileage already exist.");
}
hasDuplicate method:
//Checks for duplicate
public static boolean hasDuplicate(Date date, int odo)
{
boolean duplicate = false; //Initialize duplicate variable
//Checks if date and mileage exist already
for(int i=0; i<dates.length; i++)
{
if(date.equals(dates[i]) && odo == odometer[i]) {
return true;
}
}
return duplicate;
}
I hope someone can understand what I am trying to achieve here. Any help and idea will be great! I'm a newbie.
Some changes which you may do-
Instead of having different array of data and odometer, use an object which implements Comparable interface
class MileageData implements Comparable<MileageData> {
LocalDate date;
int odometer;
public MileageData(LocalDate date, int odometer) {
this.date = date;
this.odometer = odometer;
}
#Override
public boolean equals(final Object obj) {
MileageData anotherData = (MileageData)obj;
return anotherData.date.equals(this.date) && anotherData.odometer == this.odometer;
}
#Override
public int hashCode(){
int hash = 7;
hash = 31 * hash + this.date.hashCode();
hash = 31 * hash + this.odometer;
return hash;
}
#Override
public int compareTo(final MileageData o) {
if (o.date.isBefore(this.date)) {
return -1;
} else if (o.date.isAfter(this.date)) {
return 1;
} else {
return 0;
}
}
#Override
public String toString(){
return this.date.toString()+" "+this.odometer;
}
}
Storing MileageData in Treeset which will sort data in the order given in compareTo method of MileageData.
Set<MileageData> data = new TreeSet<>();
data.add(new MileageData(LocalDate.of(2021,2,14),156830));
data.add(new MileageData(LocalDate.of(2021,2,4),156255));
data.add(new MileageData(LocalDate.of(2021,2,4),156255));
data.add(new MileageData(LocalDate.of(2021,2,5),156572));
As Treeset will not store duplicate data, you don't need separate check for duplicates. Above set will return only three objects instead of four.

Loop will not execute properly

I am writing a program for class and the loop seems to not execute correctly. It always returns the value for i as 0. The rest of the code seems to work as advertised, i is just not increasing in index value.
public class Day {
String strDay;
private int d = 0;
private String[] Days = {"SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY"};
String day;
public Day() {
return;
}
public Day(String strDay) {// this is my issue. I think I am going about this constructor all wrong
for (int i = 0; i < Days.length; i++) {
if (strDay.equalsIgnoreCase(Days[i]))
d = i;
return;
}
}
public int getDay() {
return d;
}
public void nexDay() {
int next;
if (d < 6) {
next = (this.d) + 1;
System.out.println("Next Day is :" + Days[next]);
} else {
next = 0;
System.out.println("Next Day is :" + Days[next]);
}
}
public void prevDay() {
int prev = 0;
if ((d > 0) && (d < 6)) {
prev = (this.d) - 1;
System.out.println("previous day is " + Days[prev]);
} else
System.out.println("previous day id " + Days[6]);
}
public int calcDay(int num) {
int newDay;
this.d = d + num;
newDay = this.d % 7;
System.out.println("calc day is" + Days[d]);
return newDay;
}
public void print() {
System.out.println("day is " + Days[d]);
}
public static void main(String[] args) {
String day;
Day Callmethod = new Day();
Scanner console = new Scanner(System.in);
System.out.println("enter a day of the week");
day = console.nextLine();
Callmethod.print();
Callmethod.nexDay();
Callmethod.prevDay();
Callmethod.getDay();
}
}
Well, this
Day Callmethod = new Day();
is calling your empty constructor. Not your constructor with a loop (which takes a String). Also, Java variables start with a lower case letter (Callmethod looks like a class). I think you were looking for something like
Day day = new Day("SUNDAY");
Also, your if needs braces or the return will be invoked without doing anything (unless it matches on the first entry) like
for(int i=0;i<Days.length;i++){
if (strDay.equalsIgnoreCase(Days[i])) {
d = i;
return;
}
}
try change this:
public Day(String strDay)/// this is my issue. I think I am going about this constructor all wrong
{
for(int i=0;i<Days.length;i++){
if (strDay.equalsIgnoreCase(Days[i]))
d = i;
return;
}
}
for this:
public Day(String strDay)/// this is my issue. I think I am going about this constructor all wrong
{
for(int i=0;i<Days.length;i++){
if (strDay.equalsIgnoreCase(Days[i]))
{
d = i;
return;
}
}
}
Without the curly braces your conditional block will be only the next line of code. So your loop was only running once
public Day(String strDay) {
for (int i = 0; i < Days.length; i++) {
if (strDay == Days[i])
d = i;
return;
}
}
If I understood it clearly this will work. If not, just explain me what the goal is on that for loop. And place the return statement outisde of the next bracket.

error: class, interface, or enum expected [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have the following code that I am trying to get working for a project in a class that I am in. I will also include the requirements
Design and implement the class Day that implements the day of the week in a program. The class Day should store the day, such as Sun for Sunday. The program should be able to perform the following operations on an object of type Day:
A. Set the day.
B. Print the day.
C. Return the day.
D. Return the next day.
E. Return the previous day.
F. Calculate and return the day by adding certain days to the current day. For example, if the current day is Monday and we add four days, the day to be returned is Friday. Similarly, if today is Tuesday and we add 13 days, the day to be returned is Monday.
G. Add the appropriate constructors.
H. Write the definitions of the methods to implement the operations for the class Day, as defined in A through G.
I. Write a program to test various operations on the class Day.
The code is as follows:
`import java.util.*;
class Day {
private int dayValue;
private static final int INVALID = -1;
public Day() { this.dayValue = INVALID; }
public Day(String day) { setDay(day); }
public Day(int day) { this.dayValue = (day<0 || day>6) ? INVALID : day; }
public void setDay(String day) {
if(day.equals("sunday") || day.equals("Sun")) {
this.dayValue = 0;
} else if(day.equal("monday") || day.equals("Mon")) {
this.dayValue = 1;
} else if(day.equals("tuesday") || day.equals("Tues")) {
this.dayValue = 2;
} else if(day.equal("wednesday") || day.equals("Wed")) {
this.dayValue = 3;
} else if(day.equals("thursday") || day.equals("Thurs")) {
this.dayValue = 4;
} else if(day.equal("friday") || day.equals("Fri")) {
this.dayValue = 5;
} else if(day.equal("saturday") || day.equals("Sat")) {
this.dayValue = 6;
} else {
this.dayValue = INVALID;
}
}
public String getDay() {
if (dayValue==0) { return "Sunday"; }
if (dayValue==1) { return "Monday"; }
if (dayValue==2) { return "Tuesday"; }
if (dayValue==3) { return "Wednesday"; }
if (dayValue==4) { return "Thursday"; }
if (dayValue==5) { return "Friday"; }
if (dayValue==6) { return "Saturday"; }
return "\"I don't know what day it is!\"";
}
public void printDay() {
System.out.println("When printing, your day is " + getDay()); //displays the day at the time of printing.
}
// Next Day
public String getNextDay()
{
// the compareTo() method allows us to set saturday as Sat, Sunday to Sun, etc
if((day.compareTo("sunday") == 0) || (day.compareTo("Sun") == 0))
return ("Monday");
else if((day.compareTo("monday") == 0) || (day.compareTo("Mon") == 0))
return ("Tuesday");
else if((day.compareTo("tuesday") == 0) || (day.compareTo("Tue") == 0))
return ("Wednesday");
else if((day.compareTo("wednesday") == 0) || (day.compareTo("Wed") == 0))
return ("Thursday");
else if((day.compareTo("thursday") == 0) || (day.compareTo("Thu") == 0))
return ("Friday");
else if((day.compareTo("friday") == 0) || (day.compareTo("Fri") == 0))
return ("Saturday");
else if((day.compareTo("saturday") == 0) || (day.compareTo("Sat") == 0))
return ("Sunday");
else
return ("\"I don't know what day it is!\"");
}
// Previous day
public String getPreDay()
{
if((day.compareTo("sunday") == 0) || (day.compareTo("Sun") == 0))
return ("Saturday");
else if((day.compareTo("saturday") == 0) || (day.compareTo("Sat") == 0))
return ("Friday");
else if((day.compareTo("friday") == 0) || (day.compareTo("Fri") == 0))
return ("Thursday");
else if((day.compareTo("thursday") == 0) || (day.compareTo("Thu") == 0))
return ("Wednesday");
else if((day.compareTo("wednesday") == 0) || (day.compareTo("Wed") == 0))
return ("Tuesday");
else if((day.compareTo("tuesday") == 0) || (day.compareTo("Tue") == 0))
return ("Monday");
else if((day.compareTo("monday") == 0) || (day.compareTo("Mon") == 0))
return ("Sunday");
return ("\"I don't know what day it is!\"");
}
public Day calcDay(int offset) { /* your code here */ }
// extra good for printin
public String toString() { return getDay(); }
}
// main execution point
public static void main (String args[]) {
{
// One of its weakness is the case sensitive: sun, Sunday, sunday, SuNdAy...
// need more codes to avoid this case sensitiveness...
// instantiate testday object of type MyDay class
// with "Sun" as initial value....
Day testday = new Day("Sun");
// prompt user to set his/her day
System.out.print("Enter day to set your day: ");
// read and store user's day
String storeday = readinput.nextLine().toLowerCase(); //Changes input into all lowercase to deal with variations
// invoke setDay() method to set a day defined by user
testday.setDay(storeday);
// invoke getDay() method to get a day
System.out.println("Your day is " + testday.getDay());
// test printing by invoking printDay() method
testday.printDay();
// invoke getPreDay() method to get the previous day
System.out.println("Your previous day is " + testday.getPreDay());
// invoke getNextDay() method to get the next day
System.out.println("Your next day is " + testday.getNextDay());
System.out.println("How many Days would you like to add? " + testday.calcNextDay());
}
}`
I am receiving the following error:
Day.java:92: error: class, interface, or enum expected
public static void main () {
^
Day.java:101: error: class, interface, or enum expected
System.out.print("Enter day to set your day: ");
^
Day.java:103: error: class, interface, or enum expected
String storeday = readinput.nextLine().toLowerCase(); //Changes input into all lowercase to deal with variations
^
Day.java:105: error: class, interface, or enum expected
testday.setDay(storeday);
^
Day.java:107: error: class, interface, or enum expected
System.out.println("Your day is " + testday.getDay());
^
Day.java:109: error: class, interface, or enum expected
testday.printDay();
^
Day.java:111: error: class, interface, or enum expected
System.out.println("Your previous day is " + testday.getPreDay());
^
Day.java:113: error: class, interface, or enum expected
System.out.println("Your next day is " + testday.getNextDay());
^
Day.java:115: error: class, interface, or enum expected
System.out.println("How many Days would you like to add? " + testday.calcNextDay());
^
Day.java:116: error: class, interface, or enum expected
}
^
10 errors
Originally my code looked like this
public class Day
{
static Scanner readinput = new Scanner(System.in);
String day;
public Day(String day)
{
day = "Sunday";
}
// set the day
public void setDay(String theDay)
{
day = theDay;
}
public String getDay()
{
return day;
}
public void printDay()
{
System.out.println("When printing, your day is " + day);
}
Why not use arrays?
With an array, you could handle things in a more concise and simple way.
String[] dayOfWeekShortNames = new String[] {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
String[] dayOfWeekLongNames = new String[] {
"Sunday", "Monday", "Wednesday", "Thursday", "Friday", "Saturday"
};
Then, simply validate whether the value passed in parameter is correct.
public void setDay(String dayOfWeek) {
if (dayOfWeek == null || (0 < dayOfWeek.length() && dayOfWeek.trim().length() == 0))
throw new IllegalArgumentException("dayOfWeek cannot be null or white space.");
for (int i = 0; i < dayOfWeek.length(); i++)
if (dayOfWeek.charAt(i).isDigit())
throw new IllegalArgumentException("dayOfWeek cannot be numeric.");
if (dayOfWeek.length() < 3) // for short names
throw new IllegalArgumentException("dayOfWeek must be at least 3 characters long.");
for (int i = 0; i < dayOfWeekShortNames.length && i < dayOfWeekLongNames.length; i++)
if (dayOfWeekShortNames[i].toLowerCase() == dayOfWeek.ToLowerCase()
|| dayOfWeekLongNames[i].toLowerCase() == dayOfWeek.ToLowerCase()) {
dayValue = i;
return;
}
throw new IllegalArgumentException(
"Day of week: " + dayOfWeek + " could not be found.");
}
This is just a simple example off the top of my head.
Why not use a Program class?
Instead of just writing the main() method out of nowhere which can lead to multiple compile-time errors, perhaps one great deal would be to locate your main method inside a Program class so that it is a member of a class, and the compiler shall no longer complaint. Furthermore, the advantage of doing so shall make it obvious, at least at some extent, that your program entry point is there. This Program class shall contain nothing more than the main() method.
public class Program {
public static void main(String args[]) {
// You code here...
}
}
As for the user inputs, perhaps using the Console class... Here's an example on how to use it.
I/O from the Command Line
Disclaimer
I have not tested this code and is provided as-is for example purposes only. I am not a Java expert, and I did my best off the top of my head to help.
EDIT
I did not use an array because I wanted to store the value as a string and not the index.
In fact, the code sample in your question stores the day of week in an integer value as per this line:
private int dayValue;
Hence the assignments when you set the day as follows:
public void setDay(String day) {
if (day == "sunday" || day == "Sun")
dayValue = 0;
else if (day == "monday" || day == "Mon")
dayValue = 1;
...
}
The above actually stores the day of week in an integer format which shall satisfy most of any systems which is going to use days of week. Plus, you cannot guarantee the exact syntax of a string input by the user so that even if you either compare day == "sunday" or day == "Sun", you would have to adjust your casing according to the string you're expecting in your setDay() function, which in my opinion doesn't make sense.
The most common practice for such behaviour playing around with days of week, etc. is to use arrays with the proper expected casing, then compare the input values with either uppercase or lowercase values for both, the input and the value from the array (only this can guarantee a perfect match), then you can store the index in you dayValue private member. Then, when retrieving the day of week through the getDay() function, you can simply write a single line of code which can assure you to work flawlessly, since you captured any potential errors while setting the input through the setDay() method.
public String getDay() { return dayOfWeekLongNames[dayValue]; }
And you shall get the name of the day of week previously set, instead of having to write if statements over and over again.
Another way to approach the problem is to use an enum for the days of the week. Here's a working example provided to show the general idea:
public class Day
{
enum DAY {
MONDAY("Monday"), TUESDAY("Tuesday"), WEDNESDAY("Wednesday"), THURSDAY("Thursday"), FRIDAY("Friday"), SATURDAY(
"Saturday"), SUNDAY("Sunday");
public static DAY parse(final String value)
{
for (final DAY day : values())
{
if (day.description.equalsIgnoreCase(value) || day.description.substring(0, 3).equalsIgnoreCase(value))
{
return day;
}
}
return null;
}
private String description;
private DAY(final String description)
{
this.description = description;
}
#Override
public String toString()
{
return description;
}
}
public static void main(final String args[])
{
Day myDay;
myDay = new Day(DAY.SUNDAY);
System.out.println(myDay);
System.out.println(myDay.getPreviousDay());
System.out.println(myDay.getNextDay());
myDay = new Day("monday");
System.out.println(myDay);
System.out.println(myDay.getPreviousDay());
System.out.println(myDay.getNextDay());
myDay = new Day("wed");
System.out.println(myDay);
System.out.println(myDay.getPreviousDay());
System.out.println(myDay.getNextDay());
}
private final DAY day;
public Day(final DAY day)
{
this.day = day;
}
public Day(final String day)
{
this.day = DAY.parse(day);
}
public DAY getNextDay()
{
final DAY[] days = DAY.values();
return days[(day.ordinal() + 1) % days.length];
}
public DAY getPreviousDay()
{
final DAY[] days = DAY.values();
return days[((day.ordinal() - 1) + days.length) % days.length];
}
#Override
public String toString()
{
return day.toString();
}
}

Java, Creating a calendar

In my Java class, I have to build a calendar application. I've got it mostly completed, however I need help with a couple of methods. I have commented the parts that I need help with. The code includes three classes and a main called TestCalendar. The functions I need help with are located in the Calendar class, named removeEvent(two of them, taking two different arguments), printEvents, and findEvents. Thanks in advance!
Here is the Date class.
public class Date {
int year, month, day;
//constructor
public Date(int yr, int mth, int dy){
year = yr;
if (yr < 2000 || yr > 2100)
{
System.out.println("Wrong Calander Year");
System.exit(1);
}
month = mth;
if (mth < 1 || mth > 12)
{
System.out.println("Wrong Month");
System.exit(1);
}
day = dy;
if (dy < 1 || dy > 31)
{
System.out.println("Wrong Day");
System.exit(1);
}
}
//accessor methods
public int getYear()
{
return year;
}
public int getMonth()
{
return month;
}
public int getDay()
{
return day;
}
//returns date in correct format
public String toString()
{
return "" + month + "/" + day + "/" + year;
}
}
Here is the Event class
public class Event {
Date date;
int hour;
String activity;
Event(int year, int month, int day, int hour, String activity)
{
if (year < 2000 || year > 2100)
{
System.out.println("Wrong Calander Year");
System.exit(1);
}
if (month < 1 || month > 12)
{
System.out.println("Wrong Month");
System.exit(1);
}
if (day < 1 || day > 31)
{
System.out.println("Wrong Day");
System.exit(1);
}
this.date = new Date(year, month, day);
this.hour = hour;
this.activity = activity;
}
public Date getDate()
{
return date;
}
public int getHour()
{
return hour;
}
public String getActivity()
{
return activity;
}
void setActivity(String newActivity)
{
this.activity = newActivity;
}
public String toString()
{
return "" + date +" " + "#" + hour +":" + " " + activity;
}
public boolean equals(Object obj)
{
if (obj instanceof Event)
{
return true;
}
else return false;
}
}
The Calendar class
public class Calander {
static final int MAXEVENTS = 10;
Event[] events;
int numEvents;
// constructor
public Calander() {
numEvents = 0;
events = new Event[MAXEVENTS];
}
void addEvent(int year, int month, int day, int hour, String activity) {
Event newEvent = new Event(year, month, day, hour, activity);
events[numEvents] = newEvent;
numEvents++;
}
void removeEvent(int year, int month, int day, int hour, String activity) {
{
if (events[numEvents] == null);
numEvents--;
}
}
// instructions say to remove (all) Event objects in the Calendar that are equals to the event argument. Use the equals method from the event class
void removeEvent(Event event) {
//what to put here?
}
// this method needs to print every Event in the associated Calendar that matches the date arguments. Print each on a separate line, using the toString method from the Event class.
void printEvents(int year, int month, int day) { // how to set equality
if (this.events[numEvents] == )
{
// what to put here?
}
}
// same as above but matches the (Date date) arguments
void printEvents(Date date) {
toString();
}
// Return the first Event in the Calendar that has a matching (equals) activity field. If no match is found, you must return a reference type, so return null.
Event findEvent(String activity) {
//what to put here?
return null;
}
void dump() {
for (int i = 0; i < MAXEVENTS; i++)
{
if (events[i] != null)
System.out.println(events[i]);
}
}
}
well, your event class has a method:
public boolean equals(Object obj)
Which, presumably, should return whether or not the passed event is equal to the instance.
So your void removeEvent(Event event) method should look similar to the following:
take note that this is psudo-code and not valid java. you're going to have to flesh out the details on your own.
void removeEvent(Event event)
{
foreach(event e in this.events)
{
if(event.equals(e))
{
// remove e from the events array
}
}
}
The rest of the methods are going to more or less be similar in concept to the first one with 2 varying factorrs:
how you identify a match
what you do with the match
Since this is homework, I don't actually want to do your homework. So as a hint, you want to use (your event).equals(comparing to other event), not "==".

Generics and Performance question

I was wondering if anyone could look over a class I wrote, I am receiving generic warnings in Eclipse and I am just wondering if it could be cleaned up at all. All of the warnings I received are surrounded in ** in my code below.
The class takes a list of strings in the form of (hh:mm AM/PM) and converts them into HourMinute objects in order to find the first time in the list that comes after the current time.
I am also curious about if there are more efficient ways to do this. This works fine but the student in me just wants to find out how I could do this better.
public class FindTime {
private String[] hourMinuteStringArray;
public FindTime(String[] hourMinuteStringArray){
this.hourMinuteStringArray = hourMinuteStringArray;
}
public int findTime(){
HourMinuteList hourMinuteList = convertHMStringArrayToHMArray(hourMinuteStringArray);
Calendar calendar = new GregorianCalendar();
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
HourMinute now = new HourMinute(hour,minute);
int nearestTimeIndex = findNearestTimeIndex(hourMinuteList, now);
return nearestTimeIndex;
}
private int findNearestTimeIndex(HourMinuteList hourMinuteList, HourMinute now){
HourMinute current;
int position = 0;
Iterator<HourMinute> iterator = **hourMinuteList.iterator()**;
while(iterator.hasNext()){
current = (HourMinute) iterator.next();
if(now.compareTo(current) == -1){
return position;
}
position++;
}
return position;
}
private static HourMinuteList convertHMStringArrayToHMArray(String[] times){
FindTime s = new FindTime(new String[1]);
HourMinuteList list = s.new HourMinuteList();
String[] splitTime = new String[3];
for(String time : times ){
String[] tempFirst = time.split(":");
String[] tempSecond = tempFirst[1].split(" ");
splitTime[0] = tempFirst[0];
splitTime[1] = tempSecond[0];
splitTime[2] = tempSecond[1];
int hour = Integer.parseInt(splitTime[0]);
int minute = Integer.parseInt(splitTime[1]);
HourMinute hm;
if(splitTime[2] == "AM"){
hm = s.new HourMinute(hour,minute);
}
else if((splitTime[2].equals("PM")) && (hour < 12)){
hm = s.new HourMinute(hour + 12,minute);
}
else{
hm = s.new HourMinute(hour,minute);
}
**list.add(hm);**
}
return list;
}
class **HourMinuteList** extends **ArrayList** implements RandomAccess{
}
class HourMinute implements **Comparable** {
int hour;
int minute;
public HourMinute(int hour, int minute) {
setHour(hour);
setMinute(minute);
}
int getMinute() {
return this.minute;
}
String getMinuteString(){
if(this.minute < 10){
return "0" + this.minute;
}else{
return "" + this.minute;
}
}
int getHour() {
return this.hour;
}
void setHour(int hour) {
this.hour = hour;
}
void setMinute(int minute) {
this.minute = minute;
}
#Override
public int compareTo(Object aThat) {
if (aThat instanceof HourMinute) {
HourMinute that = (HourMinute) aThat;
if (this.getHour() == that.getHour()) {
if (this.getMinute() > that.getMinute()) {
return 1;
} else if (this.getMinute() < that.getMinute()) {
return -1;
} else {
return 0;
}
} else if (this.getHour() > that.getHour()) {
return 1;
} else if (this.getHour() < that.getHour()) {
return -1;
} else {
return 0;
}
}
return 0;
}
}
If you have any questions let me know.
Thanks,
Rob
It's because you a not specify generics for your List and Comparable instances, that can support generics. You can rewrite your code with:
class HourMinuteList extends ArrayList<HourMinute> implements RandomAccess{
}
class HourMinute implements Comparable<HourMinute> {
public int compareTo(HourMinute aThat) {
....
}
}
Note: generics is not required, and not used at runtime, but it's better to use them because it helps you to avoid some bugs at your code.
I wouldn't use the HourMinute class, unless it has some other added value. If you only need to find the closest event time after a given point in time, convert your strings to Date (or to long values representing time), and store them in some sorted collection.
The conversion can be done with SimpleDateFormat.
If items are added dynamically, use TreeSet<Date>, together with ceiling(t) / higher(t) methods.
If the set of items is not dynamic, use an array Date[], together with Arrays.binarySearch(..).
Here is a (working) draft of the first approach:
public class TimedEventsMgr {
private TreeSet<Date> pointsInTime = new TreeSet<Date>();
private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd hh:mm a");
//timeStr: hh:mm AM/PM
public void add(String timeStr) throws ParseException{
Date time = sdf.parse("20000101 "+timeStr);
pointsInTime.add(time);
}
public Date closestFutureTime(Date time){
Calendar c = Calendar.getInstance();
c.setTime(time);
c.set(Calendar.YEAR, 2000);
c.set(Calendar.MONTH, 0); //January
c.set(Calendar.DATE, 1);
return pointsInTime.higher(c.getTime());
}
}

Categories