有没有办法使用 Comparator 来比较 Class 个对象的值?
Is there a way to compare values of Class objects using Comparator?
我们不能将比较器用于自定义 Class 或结构。我试图将 Student class 用作 Comparator 的参数,但似乎不起作用。知道如何在比较器的帮助下对 class 对象进行排序。
代码:
import java.util.*;
class Student {
int id;
String name;
int marks[] = new int[5];
public Student(int id, String name, int marks[]) {
this.id = id;
this.name = name;
for (int i = 0; i < 5; i++) {
this.marks[i] = marks[i];
}
}
}
class MarksSort {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Student arr[] = new Student[n];
for (int i = 0; i < n; i++) {
int id = sc.nextInt();
String name = sc.next();
int marks[] = new int[5];
for (int j = 0; j < 5; j++)
marks[j] = sc.nextInt();
arr[i] = new Student(id, name, marks);
}
int res[] = marksSort(n, arr);
for (int j : res) {
System.out.print(j + " ");
}
}
static int[] marksSort(int n, Student arr[]) {
int[] result = new int[n];
Collections.sort(arr, new Comparator<Student> (){
@Override public int compare(Student A, Student B){
//will add sorting logic here
}
});
return result;
}}
我想在比较器中以这种方式排序。
- 总分最高的学生必须进入排行榜。
- 总分相同的学生将按姓名字母升序排序。
- 在所有其他情况下,id 较小的学生将在排行榜中排在前面
我得到的错误:-
Compile Error
MarksSort.java:46: error: no suitable method found for sort(Student[],<anonymous Comparator<Student>>)
Collections.sort(arr, new Comparator<Student> (){
^
method Collections.<T#1>sort(List<T#1>) is not applicable
(cannot infer type-variable(s) T#1
(actual and formal argument lists differ in length))
method Collections.<T#2>sort(List<T#2>,Comparator<? super T#2>) is not applicable
(cannot infer type-variable(s) T#2
(argument mismatch; Student[] cannot be converted to List<T#2>))
where T#1,T#2 are type-variables:
T#1 extends Comparable<? super T#1> declared in method <T#1>sort(List<T#1>)
T#2 extends Object declared in method <T#2>sort(List<T#2>,Comparator<? super T#2>)
1 error
Collections.sort
用于对集合进行排序;你有一个数组;你必须使用 Arrays.sort
。其次,你当然可以使用比较器中的便捷方法,这使得事情更容易编写并且启动时更具可读性:
Arrays.sort(arr, Comparator
.comparingInt(Student::getMarkSum)
.thenComparing(Student::getName)
.thenComparingInt(Student::getId));
这正是它所说的:分数较低的学生比分数较晚的学生排在前面。为了区分具有相同分数的学生,使用他们的名字;为了区分具有相同分数和相同名称的学生,使用了 id。如果它仍然相同,则 2 在比较方面被认为是相等的。这意味着什么取决于数据结构。对于数组排序,这意味着它们将以任意顺序保留。例如TreeSet
,这意味着如果与 TreeSet 相关联的比较器表示他们在比较器方面彼此相等,那么集合中不能有 2 个学生。
注意:您必须在您的 Student class 中创建方法 getId
、getMarkSum
和 getName
,但这听起来像是您应该做的所以:Java 程序员通常会做吸气剂,所以,在罗马时,要像罗马人一样。如果你真的不想,你可以自由地在分拣机中实现它们,例如使用s -> s.id
而不是 Student::getId
。重点是:您需要提供一个将学生对象转换为 int 或对象的函数。 Student::getId
是 java-ese 的原因:只需调用 getId() 方法即可。 s -> s.id
将是 java-ese 用于:获取 id
字段的值。你也可以把代码放在那里:
s -> {
int sum = 0;
for (int mark : s.marks.length) sum += mark;
return sum;
};
作为 thenComparingInt
方法的参数。但是,如果您只是在 Student 本身中创建一个 getMarkSum
方法,它会使事情更具可读性和更容易测试:这将是正确的面向对象设计。
我们不能将比较器用于自定义 Class 或结构。我试图将 Student class 用作 Comparator 的参数,但似乎不起作用。知道如何在比较器的帮助下对 class 对象进行排序。 代码:
import java.util.*;
class Student {
int id;
String name;
int marks[] = new int[5];
public Student(int id, String name, int marks[]) {
this.id = id;
this.name = name;
for (int i = 0; i < 5; i++) {
this.marks[i] = marks[i];
}
}
}
class MarksSort {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Student arr[] = new Student[n];
for (int i = 0; i < n; i++) {
int id = sc.nextInt();
String name = sc.next();
int marks[] = new int[5];
for (int j = 0; j < 5; j++)
marks[j] = sc.nextInt();
arr[i] = new Student(id, name, marks);
}
int res[] = marksSort(n, arr);
for (int j : res) {
System.out.print(j + " ");
}
}
static int[] marksSort(int n, Student arr[]) {
int[] result = new int[n];
Collections.sort(arr, new Comparator<Student> (){
@Override public int compare(Student A, Student B){
//will add sorting logic here
}
});
return result;
}}
我想在比较器中以这种方式排序。
- 总分最高的学生必须进入排行榜。
- 总分相同的学生将按姓名字母升序排序。
- 在所有其他情况下,id 较小的学生将在排行榜中排在前面
我得到的错误:-
Compile Error
MarksSort.java:46: error: no suitable method found for sort(Student[],<anonymous Comparator<Student>>)
Collections.sort(arr, new Comparator<Student> (){
^
method Collections.<T#1>sort(List<T#1>) is not applicable
(cannot infer type-variable(s) T#1
(actual and formal argument lists differ in length))
method Collections.<T#2>sort(List<T#2>,Comparator<? super T#2>) is not applicable
(cannot infer type-variable(s) T#2
(argument mismatch; Student[] cannot be converted to List<T#2>))
where T#1,T#2 are type-variables:
T#1 extends Comparable<? super T#1> declared in method <T#1>sort(List<T#1>)
T#2 extends Object declared in method <T#2>sort(List<T#2>,Comparator<? super T#2>)
1 error
Collections.sort
用于对集合进行排序;你有一个数组;你必须使用 Arrays.sort
。其次,你当然可以使用比较器中的便捷方法,这使得事情更容易编写并且启动时更具可读性:
Arrays.sort(arr, Comparator
.comparingInt(Student::getMarkSum)
.thenComparing(Student::getName)
.thenComparingInt(Student::getId));
这正是它所说的:分数较低的学生比分数较晚的学生排在前面。为了区分具有相同分数的学生,使用他们的名字;为了区分具有相同分数和相同名称的学生,使用了 id。如果它仍然相同,则 2 在比较方面被认为是相等的。这意味着什么取决于数据结构。对于数组排序,这意味着它们将以任意顺序保留。例如TreeSet
,这意味着如果与 TreeSet 相关联的比较器表示他们在比较器方面彼此相等,那么集合中不能有 2 个学生。
注意:您必须在您的 Student class 中创建方法 getId
、getMarkSum
和 getName
,但这听起来像是您应该做的所以:Java 程序员通常会做吸气剂,所以,在罗马时,要像罗马人一样。如果你真的不想,你可以自由地在分拣机中实现它们,例如使用s -> s.id
而不是 Student::getId
。重点是:您需要提供一个将学生对象转换为 int 或对象的函数。 Student::getId
是 java-ese 的原因:只需调用 getId() 方法即可。 s -> s.id
将是 java-ese 用于:获取 id
字段的值。你也可以把代码放在那里:
s -> {
int sum = 0;
for (int mark : s.marks.length) sum += mark;
return sum;
};
作为 thenComparingInt
方法的参数。但是,如果您只是在 Student 本身中创建一个 getMarkSum
方法,它会使事情更具可读性和更容易测试:这将是正确的面向对象设计。