我有一个具有名称和日期的Task对象。日期值必须为String
。一个示例是11/9/2015 23:00
与11/24/2015 12:00
进行比较。
我需要帮助为此编写compareTo()
,以便首先显示具有最短日期的任务。我所拥有的是不正确的,因为它没有正确比较。我知道有其他选择,但我需要使用String。我曾考虑使用.split()
按"/"
分解mm / dd / yyyy但不知道如何执行此操作。
public class Task implements Comparable<Task> {
/** Task name. */
private String name;
/** Task due date. */
private String dueDate;
/**
* Initializes a tasks name and due date.
* @param n Name
* @param d due date
*/
public Task(String n, String d) {
name = n;
dueDate = d;
}
/**
* Accessor for task name.
* @return Task name.
*/
public String getName() {
return name;
}
/**
* Accessor for task due date.
* @return Task due date.
*/
public String getDueDate() {
return dueDate;
}
/**
* Compares the due dates of the tasks to get the soonest to the front of the list.
* @param t The task to compare.
* @return The tasks in chronological order.
*/
@Override
public int compareTo(Task t) { //Need help here.
int val = dueDate.compareTo(t.getDueDate());
if(val == 0) {
val = name.compareTo(t.getName());
}
if(dueDate.compareTo(t.getDueDate()) > 0) {
val = -1;
}
if(dueDate.compareTo(t.getDueDate()) < 0) {
val = 1;
}
return val;
}
答案 0 :(得分:2)
您必须将日期作为字符串这一事实并不意味着您无法将其转换为Date
并使用该类的自然顺序:
@Override
public int compareTo(Task t) {
// Handling ParseExceptions omitted for bravity's sake
SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm");
Date d1 = df.parse(dueDate);
Date d2 = df.parse(t.getDueDate());
int val = d1.compareTo(d2);
if(val != 0) {
return val;
}
return name.compareTo(t.getName());
}
答案 1 :(得分:1)
我建议你使用日期时间对象而不是字符串作为你班级的成员。
Java 8及更高版本包含非常有用的java.time框架。使用这些新类(受Joda-Time启发),而不是臭名昭着的旧类java.util.Date/.Calendar。
无需解析日期时间输入字符串。默认情况下,java.time框架会解析ISO 8601格式的任何字符串。对于其他格式,定义预期输入的格式化模式,让java.time完成工作。
您无法在不知道时区的情况下比较此类日期时间字符串。也许是UTC?或者您认为所有数据都是指特定时区?
在下面的示例中,我任意假设时区为America/Los_Angeles
。
Java 8中的示例代码使用java.time.format包来解析您的字符串以在构造函数中输入,并再次使用dueDateTimeAsAmericaLosAngeles
方法生成String表示。
通常最好将日期时间值保留在UTC时区。然后在用户或其他软件预期时调整到时区。所以我们在班级上存储一个Instant
,在UTC时间轴上的一个时刻。对于特定时区,请创建ZonedDateTime
对象。
根据我的建议,如果您坚持将日期时间值存储为字符串,那么您可以通过在字符串解析到即时发生的位置移动来修改此代码。
package timestuff;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Task implements Comparable<Task> {
String title;
Instant due;
public Task ( String title , String dateTimeAssumedToBeAmericaLosAngles ) {
this.title = title;
ZoneId zoneId = ZoneId.of ( "America/Los_Angeles" );
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "M/d/yyyy HH:mm" ).withZone ( zoneId ); // Example data: 11/24/2015 12:00
this.due = formatter.parse ( dateTimeAssumedToBeAmericaLosAngles , Instant :: from );
}
@Override
public String toString () {
return "Task{ " + "title=" + title + " | instant=" + due + " }";
}
@Override
public int compareTo ( Task t ) {
// Sort by the date-time of when this task is due.
int result = this.due.compareTo ( t.due );
return result;
}
String dueDateTimeAsAmericaLosAngeles () {
ZoneId zoneId = ZoneId.of ( "America/Los_Angeles" );
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "M/d/yyyy HH:mm" ).withZone ( zoneId ); // Example data: 11/24/2015 12:00
ZonedDateTime zdt = ZonedDateTime.ofInstant ( this.due , zoneId );
String output = zdt.format ( formatter );
return output;
}
public static void main ( String[] args ) {
Task t1 = new Task ( "x" , "11/9/2015 23:00" );
Task t2 = new Task ( "y" , "11/24/2015 12:00" );
int compared = t1.compareTo ( t2 );
System.out.println ( "t1: " + t1 + " & t2: " + t2 + " compared: " + compared );
}
}
运行时:
t1:任务{title = x |时刻= 2015-11-10T07:00:00Z}&amp; t2:任务{title = y | instant = 2015-11-24T20:00:00Z}比较:-1