我创建了一个“待办事项列表”程序,其中一项操作要求该程序按用户输入的所有任务按其出现日期的升序列出所有任务。
输出示例:
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);
}
}
答案 0 :(得分:5)
您当前的问题解决方法很难实现您想要的目标。您有一个字符串列表,想要解析它们的一些片段并基于此进行排序。可以,但是您可以使其更简单。您已经有一个专门的课程来代表您的Task
。那么您应该保留List
中的Task
,而不是它们的String表示形式。
当您拥有List<Task>
时,可以通过几种方法对其进行排序。您可以在课堂上实现Comparable
,也可以使用Comparator
。您可以这样做:
currentList.sort(Comparator.comparing(Task::getDate))
或(取决于所需的顺序)
currentList.sort(Comparator.comparing(Task::getDate).reversed())
然后仅在要打印结果时才使用getItem()
(这种方法通常称为toString()
)。
答案 1 :(得分:1)
首先,您需要在列表中存储Task
个对象,而不是String
个对象。
通常,您可以将Comparator
传递给Collections.sort
。
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);
}
}
或者,您可以创建更复杂的sort
对象并将其传递给Comparator
,而Task
不是Comparable
对象。
但是请注意,这种方法使代码的可重用性降低。
Collections.sort(tasks,
Comparator
.comparing(Task::getTitle)
.thenComparing(Task::getDate)
.reverseOrder()
);
还考虑将SortedSet
或PriorityQueue
而不是List
用于您的任务,以避免显式排序并降低算法复杂度
答案 2 :(得分:1)
最好只维护List
个实例中的一个Task
并对该List
进行排序。
您可以使用以下选项之一对List
个实例中的Task
个实例进行排序:
要实现Comparable
接口,必须重写compareTo
类中的Task
方法。由于您要根据date
实例字段对任务进行排序,因此只需返回日期比较的结果即可。
这是您应重写compareTo()
方法以根据date
实例字段按升序对任务进行排序的方法。
@Override
public int compareTo(Task o) {
return this.date.compareTo(o.date);
}
由于Date
类已经实现了Comparable
接口,因此您可以调用compareTo
方法来比较两个Date
实例。
现在要对任务列表进行排序,请调用sort
类的Collections
方法。
Collections.sort(taskList);
Here's a version of your code,它实现了Comparable
界面,并使用date
实例字段对任务进行了排序
使用Comparator
界面对对象进行排序的方法有多种:
Comparator
接口的单独的类您可以创建一个实现Comparator
接口的类,然后重写compare
函数。 compare
函数的实现与上面通过实现compareTo
接口实现的Comparable
函数的实现相同。
class TaskComparator implements Comparator<Task> {
@Override
public int compare(Task o1, Task o2) {
return o1.getDate().compareTo(o2.getDate());
}
}
要对任务列表进行排序,您有两个选择:
使用sort
类的Collections
函数并传递TaskComparator
类的instacne作为第二个参数
Collections.sort(taskList, new TaskComparator());
使用sort
界面的List
方法
taskList.sort(new TaskComparator());
Here's a version of your code创建一个单独的比较器类,以使用date
实例字段对任务进行排序
您可以使用匿名类,而不必创建单独的类来实现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()));
Here's a version of your code,使用lambda表达式实现Comparator
接口
您还可以使用comparing
接口的名为Comparator
的静态方法。它将返回一个用于排序的比较器。
Collections.sort(taskList, Comparator.comparing(Task::getDate));
或
taskList.sort(Comparator.comparing(Task::getDate));
Here's a version of your code,使用Comparator.comparing
方法使用date
实例字段对任务进行排序
有关如何实现Comparable
或Comparator
接口的详细信息,请参阅:
答案 3 :(得分:0)
您可以使用List
方法和自定义sort
来对Comparator
进行排序
list.sort(Comparator.comparing(Task::getDate).reversed());
但是我认为您必须使用另一个集合。比PriorityQueue
好ArrayList
英尺。
Queue<Task> queue = new PriorityQueue<>(Comparator.comparing(...));
答案 4 :(得分:0)
@Amongalen 已经提供了创建TaskList和基于日期排序的解决方案。
我将提供一种时间复杂度更好的方法。由于对集合进行排序可以是 O(nlogn)。每次将元素添加到列表中后,进行排序都不是一个好主意。
相反,您可以维护PriorityQueue
个Task Object并根据日期进行比较,然后将Task
个对象添加到该PriorityQueue
中。
现在,您无需调用排序,只需在iterate
上方queue
并显示结果即可。
PriorityQueue<Task> queue = new PriorityQueue<>((o1,o2)-> o1.getDate.comapreTo(o2.getDate));
// Add task object to the queue
queue.add(myTaskObject);
//iterate and display when asked
Iterator<Task> it = queue.iterator();
while(it.hasNext()) {
System.out.println(it.next().toString());
}
注意:将任务对象添加到队列为O(logn) 这样可以缩短解决方案的时间