我已经创建了一个To-Do-List程序,其中的一个操作要求程序按照用户输入的所有任务所在日期的升序列出这些任务。
输出示例:
Tasks listed in ascending order (earliest first):
TaskName, 20/04/2020, time, location, duration, category
TaskName, 18/07/2020, time, location, duration, category
TaskName, 09/08/2020, time, location, duration, category
TaskName, 21/12/2020, time, location, duration, category 到目前为止,在我的代码中,用户输入的所有任务都列出了,但它们不是按每个任务的日期升序列出的。
到目前为止,我的代码如下:
public void sortTasks() {
System.out.println("Sorted tasks by date (earliest first): ");
Collections.sort(currentList);
currentList.forEach(System.out::println);
}
}发布于 2020-07-01 15:34:20
你目前解决问题的方法使你很难实现你想要的。您有一个字符串列表,并希望解析其中的一些片段,并根据这些片段进行排序。这是可能的,但你可以让它变得更简单。您已经有了一个专用的类来表示您的Task。那么您应该保留Tasks的List,而不是它们的字符串表示。当您有一个List<Task>时,有几种方法可以对其进行排序。您可以在类中实现Comparable,也可以使用Comparator。你可以这样做:
currentList.sort(Comparator.comparing(Task::getDate))或者(取决于所需的顺序)
currentList.sort(Comparator.comparing(Task::getDate).reversed())然后,只有在需要打印结果时才使用getItem() (这种方法通常称为toString())。
发布于 2020-07-01 15:30:29
首先,您需要在列表中存储Task对象,而不是String。
通常,您可以向Collections.sort传递一个Comparator。
Collections.sort(tasks, Comparator.reverseOrder());为了让它正常工作,你必须让Task成为Comparable的一个实现,你比较对象字段的方式取决于你的特定任务,在这里你可以提供升序比较的实现,然后通过reverseOrder方法反转它。
class Task implements Comparable<Task> {
...
@Override
public int compareTo(Task task) {
return Comparator
.comparing(Task::getTitle)
.thenComparing(Task::getDate)
.compare(this, task);
}
}或者,您可以创建一个更复杂的Comparator对象并将其传递给sort,而不必将Task作为Comparable对象。但请注意,这种方法降低了代码的可重用性。
Collections.sort(tasks,
Comparator
.comparing(Task::getTitle)
.thenComparing(Task::getDate)
.reverseOrder()
);还要考虑使用SortedSet或PriorityQueue而不是List来执行任务,以避免显式排序并降低算法复杂性
发布于 2020-07-01 15:32:11
如果只维护Task实例的List并对该List进行排序,效果会更好。
您可以使用以下选项之一对Task实例的List进行排序:
实现可比较的Interface
实现可比较的接口
若要实现Comparable接口,必须重写Task类中的compareTo方法。由于您希望根据date实例字段对任务进行排序,因此可以只返回日期比较的结果。
下面介绍如何重写compareTo()方法以根据date实例字段对任务进行升序排序。
@Override
public int compareTo(Task o) {
return this.date.compareTo(o.date);
}因为Date类已经实现了Comparable接口,所以您可以只调用compareTo方法来比较两个Date实例。
现在,要对任务列表进行排序,请调用Collections类的sort方法。
Collections.sort(taskList);实现Comparable接口并使用date实例字段对任务进行排序的Here's a version of your code
使用比较器
使用Comparator接口对对象进行排序的方法有多种:
使用lambda expression
Comparator 创建一个单独的类来实现比较程序接口的静态方法
创建实现比较器接口的单独类
您可以创建一个实现Comparator接口的类,然后覆盖compare函数。compare函数的实现与上面通过实现Comparable接口实现的compareTo函数相同。
class TaskComparator implements Comparator<Task> {
@Override
public int compare(Task o1, Task o2) {
return o1.getDate().compareTo(o2.getDate());
}
}要对任务列表进行排序,您有两个选项:
Collections类的sort函数,并将TaskComparator类的实例作为第二个参数传递Collections.sort(taskList,新的TaskComparator());
List接口的sort方法TaskList.sort(新TaskComparator());
创建单独的比较器类以使用date实例字段对任务进行排序的Here's a version of your code
使用匿名类或使用lambda表达式
您可以使用匿名类,而不是创建单独的类来实现Comparator接口
Collections.sort(taskList, new Comparator<Task>() {
@Override
public int compare(Task t1, Task t2) {
// code to compare Task objects
}
});或
taskList.sort(new Comparator<Task>() {
@Override
public int compare(Task o1, Task o2) {
return o1.getDate().compareTo(o2.getDate());
}
});Java 8引入了lambda表达式,您可以用lambda表达式替换匿名类,使您的代码更简洁
Collections.sort(taskList, (o1, o2) -> o1.getDate().compareTo(o2.getDate()));或
taskList.sort((o1, o2) -> o1.getDate().compareTo(o2.getDate()));使用lambda表达式实现Comparator接口的Here's a version of your code
使用比较程序接口的静态方法
也可以使用Comparator接口名为comparing的静态方法。它将返回一个用于排序的比较器。
Collections.sort(taskList, Comparator.comparing(Task::getDate));或
taskList.sort(Comparator.comparing(Task::getDate));使用Comparator.comparing方法对使用date实例字段的任务进行排序的Here's a version of your code
有关如何实现Comparable或Comparator接口的详细信息,请参阅:
https://stackoverflow.com/questions/62671598
复制相似问题