英文:
Multiple checks in Comparator.comparing
问题
我有一个对象列表,'Students' - 每个 'Student' 存储姓名和学生ID。
我想按ID升序对列表进行排序,并确保没有两个学生具有相同的ID号码。
如果有多个具有相同ID的学生,抛出异常,否则执行某些操作。
对于排序部分,我正在使用一个比较器 -
students.sort((Comparator.comparing(Student::getStudentID).reversed()));
对于第二部分,我可以添加另一个循环,遍历学生,然后进行检查。
我想在排序过程中避免第二个循环,并检查多个ID。有没有一种高效的方法可以做到这一点?
[如果问题太基础,我正在尝试寻找更高效的编码方式,敬请谅解]
英文:
I have a list of objects, 'Students' - each 'Student' storing Name & Student ID.
I want to sort the list in ascending order of their ID and also make sure that no two students have the same ID number.
If there are multiple students with same ID, throw an exception, else do something.
For sorting part, I am using a Comparator -
students.sort((Comparator.comparing(Student::getStudentID).reversed()));
For the second part, I can add another for loop, iterate through students, and do the check.
I want to avoid the second loop and check for multiple IDs while I am sorting itself. Is there an efficient way to do this ?
[Sorry if the question is too basic, I am trying to look for more efficient way of coding]
答案1
得分: 0
你可以编写自己的 Comparator
- 例如:
class StudentsComparator implements Comparator<Student> {
@Override
public int compare(Student student1, Student student2) {
if (student1.getStudentId().equals(student2.getStudentId())) {
throw new IllegalStateException("Same ids");
}
return student2.getStudentId().compareTo(student1.getStudentId());
}
}
然后你可以这样做:
students.sort(new StudentsComparator());
来获得正确的结果。
然而,首先查找重复项,然后在另一个步骤中进行排序可能会是一个更 "清晰" 的解决方案,将两个不同的要求解耦。除非你真的非常关心性能,进行两次运行会是一个更好的选择 - 这会是更清晰的代码。
更新
至于查找重复项,你可以采取不同的方法之一:
private boolean hasDuplicates(List<Student> students) {
return students.size() != students.stream().map(Student::getStudentId).distinct().count();
}
在这里,对于每个学生,你获取他的 id(在 map
方法中,你将学生替换为他的 id),然后仅获取不同的值。如果不同值的数量与原始列表的大小不同,则列表中有重复项。
英文:
You could write your own Comparator
- i.e:
class StudentsComparator implements Comparator<Student> {
@Override
public int compare(Student student1, Student student2) {
if (student1.getStudentId().equals(student2.getStudentId())) {
throw new IllegalStateException("Same ids");
}
return student2.getStudentId().compareTo(student1.getStudentId());
}
}
then you could just do:
students.sort(new StudentsComparator());
to get the proper result.
However, searching for the duplicates first and then sorting in another pass would probably be a cleaner
solution, decoupling two different requirements from each other. Unless you really really care about performance, it's a better choice to do 2 runs - it is a cleaner code.
UPDATE
As for finding duplicates, you could go in various directions. One being:
private boolean hasDuplicates(List<Student> students) {
return students.size() != students.stream().map(Student::getStudentId).distinct().count();
}
Here, for every student, you're getting his id (in the map
method you're replacing student with his id), and then you're getting only distinct values. If the number of distinct values is different from the size of the original list, then there are duplicates in the list.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论