How to compare String which are numbers?
I have Strings saved in file:
"2000 12 7 0 2 -3.0"
"2000 7 7 0 2 -4.0"
"2013 7 23 20 59 25.5"
First five values are date (year, month, day, hour, minute). I need to sort them chronologically.
Here is my code:
class Task3 {
BufferedWriter writer;
BufferedReader reader;
int licznik = 0;
Task3() throws IOException {
this.writer = new BufferedWriter(new FileWriter("c:\\zadanie.txt"));
this.reader = new BufferedReader(new FileReader("c:\\zadanie.txt"));
}
public void WriteMeasur(Measur measur) throws IOException{
//licznik++;
writer.write(measur.toString());
writer.newLine();
}
public void WriteChrono(Measur measur) throws IOException{
List<String> lista = new ArrayList<>();
String line;
while((line = reader.readLine()) != null){
lista.add(line);
}
}
}
class Time implements Serializable{
int year, month, day, hour, minute;
Time(int r, int m, int d, int h, int min){
if(r <= 2014 && r > 1990)
this.year = r;
if(m <= 12)
this.month = m;
if(d <= 30 || (m == 2 && d < 29))
this.day = d;
if(h <= 24)
this.hour = h;
if(min <= 60)
this.minute = min;
}
#Override
public String toString(){
return String.valueOf(year) + " " + String.valueOf(month) + " " +String.valueOf(day) + " " +String.valueOf(hour) + " " +String.valueOf(minute);
}
}
class Measur implements Serializable{
Time time;
double temp;
Measur(Time czas, double temp){
this.time = czas;
this.temp = temp;
}
#Override
public String toString(){
return time.toString() + " " +String.valueOf(temp);
}
}
public class Main{
public static void main(String args[]) throws IOException{
//Argumenty klasy czas: rok, miesiac, dzien, godzina, minuty
// Metody inicjujace klase czas
Time czas_1 = new Time(2013,7,23,20,59);
Time czas_3 = new Time(2000,07,7,25,2);
Time czas_2 = new Time(2000,12,7,25,2);
// Metody inicjujace klase pomiar
Measur pomiar_1 = new Measur(czas_1, 25.5);
Measur pomiar_2 = new Measur(czas_2, -3);
Measur pomiar_3 = new Measur(czas_3, -4);
Task3 zad3 = new Task3();
zad3.WriteMeasur(pomiar_1);
zad3.WriteMeasur(pomiar_2);
zad3.WriteMeasur(pomiar_3);
zad3.writer.close();
}
}
I have no idea how to sort it. I wanted use Collections.sort(), but in Strings 2000 12 is smaller then 2000 7.
Any advice?
Thanks!
I'm not sure this is a good idea or not. But you could use Collections.sort support of Comparator to customise the way in which values are compared while they are been sorted and SimpleDateFormat to convert the value to a Date value which can then be compared directly...for example...
List<String> values = new ArrayList<String>(25);
values.add("2013 7 23 20 59 25.5");
values.add("2000 12 7 0 2 -3.0");
values.add("2000 7 7 0 2 -4.0");
Collections.sort(values, new Comparator<String>() {
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy MM dd");
#Override
public int compare(String o1, String o2) {
int result = -1;
try {
Date d1 = sdf.parse(o1);
Date d2 = sdf.parse(o2);
result = d1.compareTo(d2);
} catch (ParseException exp) {
exp.printStackTrace();
}
return result;
}
});
for (String value : values) {
System.out.println(value);
}
Create yourself a personal MyDate Object that is passed a String in its constructor and parses that string to initialize your year, month, day, hour, min, sec fields.
Then write a custom Comparator for your class MyDateComparator and code your logic for sorting.
Store your MyDate objects not String in your List and use `Collections.sort(myDateList, new MyDateComparator())
See The Ordering Collections Java Tutorials for tips on how to use Comparators
Split the string with space as delimiter, convert into integer array and then sort?
Related
I have a method which works in this way:
Take as an argument 3 params - a list with dates (sorted in ascending order) , interval unit and interval value
Check whether the next element doesn't exceed the previous date (interval). In other words, given the interval of 30 min, prev - 10:00, next 10:29 - iterate further. if next is 10:31 - break it and return the counter of dates in a row.
The code for it is below:
public static void main(String[] args)
{
Date d1 = new Date();
Date d2 = addOrSubtractTimeUnitFromDate(d1, Calendar.MINUTE, 10, true);
Date d3 = addOrSubtractTimeUnitFromDate(d2, Calendar.MINUTE, 10, true);
Date d4 = addOrSubtractTimeUnitFromDate(d3, Calendar.MINUTE, 10, true);
Date d5 = addOrSubtractTimeUnitFromDate(d4, Calendar.MINUTE, 10, true);
Date d6 = addOrSubtractTimeUnitFromDate(d5, Calendar.MINUTE, 10, true);
List<Date> threeDates = new ArrayList<>();
threeDates.add(d1);
threeDates.add(d2);
threeDates.add(d3);
threeDates.add(d4);
threeDates.add(d5);
threeDates.add(d6);
System.out.println(returnDatesInARowCounter(threeDates, Calendar.MINUTE, 30));
}
private static int returnDatesInARowCounter(List<Date> allDates, int intervalBetween2DatesTimeUnit, int intervalValue)
{
int datesInARowCounter = allDates.size() > 0 ? 1 : 0; // esp. this line (in case allDates is empty)
Date lastDate = null;
Date nextDate;
Iterator<Date> iter = allDates.iterator();
while (iter.hasNext())
{
nextDate = iter.next();
if (lastDate != null) // both lastDate и nextDate are initialized now
{
if(isNextIncidentInIntervalWithLastOneOrNot(lastDate, nextDate, intervalBetween2DatesTimeUnit, intervalValue, true))
{
datesInARowCounter += 1;
}
else break;
}
lastDate = nextDate;
}
return datesInARowCounter;
}
public static Date addOrSubtractTimeUnitFromDate(Date dateToAddToOrSubtractFrom, int calendarTimeUnit, int value, boolean isAdd)
{
if(!isAdd)
{
value = -value;
}
Calendar cal = Calendar.getInstance();
cal.setTime(dateToAddToOrSubtractFrom);
cal.add(calendarTimeUnit, value);
return cal.getTime();
}
private static boolean isNextIncidentInIntervalWithLastOneOrNot(Date lastIncidentRegDate, Date nextIncidentRegDate, int intervalTimeUnit, int intervalValue, boolean isBetween)
{
Date currentIncidentPlusInterval = addOrSubtractTimeUnitFromDate(lastIncidentRegDate, intervalTimeUnit, intervalValue, true);
boolean betweenBool = isDateBetween(nextIncidentRegDate, lastIncidentRegDate, currentIncidentPlusInterval);
return isBetween == betweenBool;
}
private static boolean isDateBetween(Date targetDate, Date startDate, Date endDate)
{
return targetDate.compareTo(startDate) >= 0 && targetDate.compareTo(endDate) <= 0;
}
However, the code looks peculiar to me. Is the any way to make it look more readable?
If you are using Java 8 or newer, you can use the java.time-API instead. It's built-in support for "periods of time" makes the actual implementation much simpler.
static int daysInARow(List<Instant> allInstants, Duration maxDifference) {
int counter = allInstants.size() > 0 ? 1 : 0;
Instant previous = allInstants.get(0);
for (int i = 1; i < allInstants.size(); i++) {
Instant current = allInstants.get(i);
if (Duration.between(previous, current).compareTo(maxDifference) > 0)
break;
counter++;
previous = current;
}
return counter;
}
If you're using java.util.Date in other parts of your project, you can easily convert between Instants by using
Date#from(Instant)
and
Date#toInstant()
I have to implement an interface and try it out in two different classes one with Array and one with List. In these classes we have to add different methods as seen in the interface ->
public interface IStatistics {
public void addSample(String name, GregorianCalendar date, double value);
public double getMeanTemperature(int month);
public double getMedianTemperature(int month);
public double getVariance(int month);
public double getStandardDeviation(int month);
public void printSamples(int month);
}
I've already done most of it but it should only use the values from a specific month which doesn't work in both methods. In this exercise we get a certain value every day for one year(name, date, temperature). I don't know how to get it to only use the values from one month(which doesn't work in both classes) In the List I already tried it out but it doesn't work at all.
#Override
public double getMeanTemperature(int month) {
MeasurementValue m = this.head;
double result = 0;
while(m.date.get(GregorianCalendar.MONTH)==month){
while(m!=null){
result = result + m.temp;
m=m.getNext();
}
result = result/this.num;
}
return result;
}
And in the class with Array I don't even know how to start.
#Override
public double getMeanTemperature(int month) {
double sum = 0.0;
for(double a : values)
sum += a;
return sum/numValues;
}
Also it doesn't print out the dates correctly. Maybe anyone knows a solution for that.
import java.util.GregorianCalendar;
import kwm.statistics.IStatistics;
import kwm.statistics.MeasurementArray;
import kwm.statistics.MeasurementList;
public class TestStatistics {
public static void main(String[] args) {
GregorianCalendar date = new GregorianCalendar(2017,05,12);
GregorianCalendar date1 = new GregorianCalendar(2017,05,02);
GregorianCalendar date2 = new GregorianCalendar(2017,05,22);
GregorianCalendar date3 = new GregorianCalendar(2017,06,06);
GregorianCalendar date4 = new GregorianCalendar(2017,05,18);
// ***TESTLIST***
IStatistics statistics1 = new MeasurementList();
statistics1.addSample("Lisa", date, 12);
statistics1.addSample("Lisa", date1, 17);
statistics1.addSample("Lisa", date2, 14);
statistics1.printSamples(5);
// ***TESTARRAY***
IStatistics statistics2 = new MeasurementArray();
statistics2.addSample("Lisa", date, 12);
statistics2.addSample("Lisa", date1, 5);
statistics2.addSample("Lisa", date2, 40);
statistics2.addSample("Lisa", date3, 31);
statistics2.addSample("Lisa", date4, 23);
statistics2.printSamples(5);
}
}
That's the code for the output in MeasurementValue
public void output(){
GregorianCalendar date = this.date;
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
System.out.print(sdf.format(date.getTime()));
}
And the code for the output in MeasurementList.
public void printSamples(int month) {
MeasurementValue m = this.head;
// while(m.date.get(GregorianCalendar.MONTH)==month){
while(m != null){
if(month>=0 && 11>=month){
System.out.println("Name: "+m.getName());
System.out.println("Value: "+m.getTemp());
System.out.print("Date: ");m.output();
System.out.print("\n");
System.out.print("*****************\n\n");
m = m.getNext();
}
}
// }
System.out.print("\n");
}
Thanks for any help!
For the linked list version, try something like this:
#Override
public double getMeanTemperature(int month) {
double total = 0d;
int num = 0;
for (MeasurementValue m = this.head; m != null; m = m.getNext()) {
if (m.date.get(Calendar.MONTH) == month) {
total += m.temp;
num++;
}
}
if (num == 0) {
// Avoid division by zero
return 0d;
}
return total / (double) num;
}
Same principle for the array but you iterate differently (and you need to store the months as well).
I am trying my hands on this questions:https://www.codeeval.com/browse/214/ and below is my code and ouput:
CODE
public class TimeSort implements Comparable<TimeSort>{
public int hour;
public int minutes;
public int seconds;
public TimeSort(int hour, int minutes, int seconds) {
this.hour = hour;
this.minutes = minutes;
this.seconds = seconds;
}
public TimeSort(String str){
/*DateFormat formatter = new SimpleDateFormat("HH:mm:ss");
final String x = str;
try {
Date time = sdf.parse(x);
//Time time = new Time(new SimpleDateFormat("HH:mm:ss").parse(x).getTime());
this.hour = time.getHours();
this.minutes = time.getMinutes();
this.seconds = time.getSeconds();
} catch (ParseException e) {
e.printStackTrace();
}*/
String[] parts = str.split(":");
int hour = Integer.parseInt(parts[0]);
int minutes = Integer.parseInt(parts[1]);
int seconds = Integer.parseInt(parts[2]);
this.hour = hour;
this.minutes = minutes;
this.seconds = seconds;
}
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
public int getMinutes() {
return minutes;
}
public void setMinutes(int minutes) {
this.minutes = minutes;
}
public int getSeconds() {
return seconds;
}
public void setSeconds(int seconds) {
this.seconds = seconds;
}
#Override
public String toString() {
if(this.getHour() < 10){
return "0"+this.getHour()+":"+this.getSeconds()+":"+this.getSeconds();
}
return this.getHour()+":"+this.getSeconds()+":"+this.getSeconds();
}
public static void main(String[] args){
List<String> inputs = new ArrayList<>();
inputs.add("02:26:31 14:44:45 09:53:27");
inputs.add("05:33:44 21:25:41");
inputs.add("02:26:31 14:44:45 09:53:27 02:26:31 01:44:45 19:53:27");
for (String input : inputs){
sortTimes(input);
}
}
#Override
public int compareTo(TimeSort timeSort) {
if(this.getHour() > timeSort.getHour()){
return -1;
}
else if(this.getHour() < timeSort.getHour()){
return 1;
}
else if(this.getHour() == timeSort.getHour()) {
if(this.getMinutes() > timeSort.getMinutes()){
return -1;
}
else if(this.getMinutes() < timeSort.getMinutes()){
return 1;
}
}
else if(this.getSeconds() > timeSort.getSeconds()){
return 1;
}
return 0;
}
public static void sortTimes(String str){
List<TimeSort> list = new ArrayList<>();
String[] times = str.split(" ");
for (String time : times){
list.add(new TimeSort(time));
}
System.out.print("Before Sorting: ");
for (TimeSort t : list){
System.out.print(t + " ");
}
System.out.println();
Collections.sort(list);
System.out.print("After Sorting: ");
for (TimeSort t : list){
System.out.print(t + " ");
}
System.out.println();
System.out.println("==============================================================");
}
}
OUTPUT
Before Sorting: 02:31:31 14:45:45 09:27:27
After Sorting: 14:45:45 09:27:27 02:31:31
==============================================================
Before Sorting: 05:44:44 21:41:41
After Sorting: 21:41:41 05:44:44
==============================================================
Before Sorting: 02:31:31 14:45:45 09:27:27 02:31:31 01:45:45 19:27:27
After Sorting: 19:27:27 14:45:45 09:27:27 02:31:31 02:31:31 01:45:45
==============================================================
The weird thing I am seeing is the times do not print correctly. For example 02:26:31 is print as 02:31:31. And it's the same even if I tried to parse the string time(commented part of the code)
Any help is appreciated. Thanks
Your toString() method has a bug:
#Override
public String toString() {
if(this.getHour() < 10){
return "0"+this.getHour()+":"+this.getSeconds()+":"+this.getSeconds();
}
return this.getHour()+":"+this.getSeconds()+":"+this.getSeconds();
}
Note that the 2nd field is getSeconds() instead of getMinutes().
Your toString()-method does not print the minutes!
The other Answers found the bug in your code.
java.time
FYI, all of that code in unnecessary. Java 8 and later has the java.time framework built-in. Amongst its classes is LocalTime for representing a time-of-day-only value without a date and without a time zone. This class already knows how to compare and sort its values and how to parse/print its values. Printing follows standard ISO 8601 formats by default.
List<LocalTime> times = new ArrayList<>();
times.add( LocalTime.parse( "02:26:31" );
times.add( LocalTime.parse( "14:44:45" );
times.add( LocalTime.parse( "09:53:27" );
Collections.sort( times );
Dump to console.
System.out.println( times );
I am trying to get this to output all the weekdays (MON-FRI) between 5/16/2010 (a sunday) and 5/25/2010 (a tuesday). The correct output should be 17,18,19,20,21,24,25. However, the result im getting is 17,18,19,20,21,17,18,19. The other methods just split up the string the date is in
import java.util.*;
public class test
{
public static void main(String[] args) {
String startTime = "5/16/2010 11:44 AM";
String endTime = "5/25/2010 12:00 PM";
GregorianCalendar startCal = new GregorianCalendar();
startCal.setLenient(true);
String[] start = splitString(startTime);
//this sets year, month day
startCal.set(Integer.parseInt(start[2]),Integer.parseInt(start[0])-1,Integer.parseInt(start[1]));
startCal.set(GregorianCalendar.HOUR, Integer.parseInt(start[3]));
startCal.set(GregorianCalendar.MINUTE, Integer.parseInt(start[4]));
if (start[5].equalsIgnoreCase("AM")) { startCal.set(GregorianCalendar.AM_PM, 0); }
else { startCal.set(GregorianCalendar.AM_PM, 1); }
GregorianCalendar endCal = new GregorianCalendar();
endCal.setLenient(true);
String[] end = splitString(endTime);
endCal.set(Integer.parseInt(end[2]),Integer.parseInt(end[0])-1,Integer.parseInt(end[1]));
endCal.set(GregorianCalendar.HOUR, Integer.parseInt(end[3]));
endCal.set(GregorianCalendar.MINUTE, Integer.parseInt(end[4]));
if (end[5].equalsIgnoreCase("AM")) { endCal.set(GregorianCalendar.AM_PM, 0); }
else { endCal.set(GregorianCalendar.AM_PM, 1); }
for (int i = startCal.get(Calendar.DATE); i < endCal.get(Calendar.DATE); i++)
{
startCal.set(Calendar.DATE, i);
startCal.set(Calendar.DAY_OF_WEEK, i);
if (startCal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY || startCal.get(Calendar.DAY_OF_WEEK) == Calendar.TUESDAY || startCal.get(Calendar.DAY_OF_WEEK) == Calendar.WEDNESDAY || startCal.get(Calendar.DAY_OF_WEEK) == Calendar.THURSDAY || startCal.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY)
{
System.out.println("\t" + startCal.get(Calendar.DATE));
}
}
}
private static String[] splitDate(String date)
{
String[] temp1 = date.split(" "); // split by space
String[] temp2 = temp1[0].split("/"); // split by /
//5/21/2010 10:00 AM
return temp2; // return 5 21 2010 in one array
}
private static String[] splitTime(String date)
{
String[] temp1 = date.split(" "); // split by space
String[] temp2 = temp1[1].split(":"); // split by :
//5/21/2010 10:00 AM
String[] temp3 = {temp2[0], temp2[1], temp1[2]};
return temp3; // return 10 00 AM in one array
}
private static String[] splitString(String date)
{
String[] temp1 = splitDate(date);
String[] temp2 = splitTime(date);
String[] temp3 = new String[6];
return dateFill(temp3, temp2[0], temp2[1], temp2[2], temp1[0], temp1[1], temp1[2]);
}
private static String[] dateFill(String[] date, String hours, String minutes, String ampm, String month, String day, String year) {
date[0] = month;
date[1] = day;
date[2] = year;
date[3] = hours;
date[4] = minutes;
date[5] = ampm;
return date;
}
private String dateString(String[] date) {
//return month+" "+day+", "+year+" "+hours+":"+minutes+" "+ampm
//5/21/2010 10:00 AM
return date[3]+"/"+date[4]+"/ "+date[5]+" "+date[0]+":"+date[1]+" "+date[2];
}
}
startCal.set(Calendar.DAY_OF_WEEK, i); Will flip flip your date back every 7 loops.
This code isn't good.
I don't understand why you're doing all this parsing of Strings to get to Date and visa versa when you have java.text.DateFormat and java.text.SimpleDateFormat to do it easily for you.
I think this is better. See if you agree:
package com.contacts.util;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
public class DateUtils
{
private static final DateFormat DEFAULT_FORMAT = new SimpleDateFormat("dd-MMM-yyyy");
public static void main(String[] args)
{
try
{
Date startDate = ((args.length > 0) ? DEFAULT_FORMAT.parse(args[0]) : new Date());
Date endDate = ((args.length > 1) ? DEFAULT_FORMAT.parse(args[1]) : new Date());
List<Date> weekdays = DateUtils.getWeekdays(startDate, endDate);
Calendar calendar = Calendar.getInstance();
for (Date d : weekdays)
{
calendar.setTime(d);
int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
int month = calendar.get(Calendar.MONTH);
int year = calendar.get(Calendar.YEAR);
// System.out.println(DEFAULT_FORMAT.format(d));
System.out.println("day: " + dayOfMonth + " month: " + (month+1) + " year: " + year);
}
}
catch (ParseException e)
{
e.printStackTrace();
}
}
public static List<Date> getWeekdays(Date startDate, Date endDate)
{
List<Date> weekdays = new ArrayList<Date>();
if ((startDate == null) || (endDate == null))
return weekdays;
if (startDate.equals(endDate))
{
if (isWeekday(startDate))
{
weekdays.add(startDate);
}
}
else if (startDate.after(endDate))
{
weekdays = getWeekdays(endDate, startDate);
}
else
{
Calendar calendar = Calendar.getInstance();
calendar.setTime(startDate);
Date d = startDate;
while (endDate.equals(d) || endDate.after(d))
{
if (isWeekday(d))
{
weekdays.add(d);
}
calendar.add(Calendar.DATE, 1);
d = calendar.getTime();
}
}
return weekdays;
}
public static boolean isWeekday(Date d)
{
if (d == null)
return false;
Calendar calendar = Calendar.getInstance();
calendar.setTime(d);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
return ((dayOfWeek >= Calendar.MONDAY) && (dayOfWeek <= Calendar.FRIDAY));
}
}
I don't know if this is an issue with your code, but JDK uses some unexpected values for Calendar constants. For example, months star with zero. In other words, Calendar.JANUARY is 0. On the other hand, weekdays are 1 to 7, starting with Sunday as 1. etc.
I luckily don't know much about Date in Java, but I know it's basically a difficult and bad API. Go for JodaTime until the new JSR-310 is done.
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());
}
}