java-如何在不使用比较器和比较器接口的情况下对地图进行排序?如何编写自定义排序?
问题-我有一个学生类,它包含名称,卷号,三个主题分数m1,m2,m3和总分数.如果两个或两个以上学生分数相等,则需要根据学生对象的总分数对其进行排序,然后根据其名称对其进行排序.注意-我必须用Google搜索它,但是并不能使用Comparable和Comparator接口在*问题中获得预期的解决方案.
我已经创建了Studnt类
public class Student {
private String name;
private Integer rollNumber;
private int m1;
private int m2;
private int m3;
private int totMarks;
//Getter setter
}
主班
public class StudentData {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enetr the number of Student");
int totalStudent = sc.nextInt();
Map<Integer,Student> map = new TreeMap<Integer,Student>();
for(int i =0;i<totalStudent;i++) {
Student ss = new Student();
System.out.println("Enter the Student roll number");
ss.setRollNumber(sc.nextInt());
System.out.println("Enter the Student Name");
ss.setName(sc.next());
System.out.println("Enter the m1 marks ");
ss.setM1(sc.nextInt());
System.out.println("Enetr the m2 marks ");
ss.setM2(sc.nextInt());
System.out.println("Enter the m3 marks ");
ss.setM3(sc.nextInt());
ss.setTotMarks(ss.getM1()+ss.getM2()+ss.getM3());
map.put(ss.getTotMarks(),ss);
ss=null;
}
//stdList.forEach(System.out::print);
for(Map.Entry<Integer,Student> m :map.entrySet()) {
System.out.println(m);
}
}
}
实际上,我正在使用TreeMap,它按键对值进行排序(总标记是TreeMap中的键).但是两个或两个以上的学生则得分相等.然后,由于**不允许旧学生对象(值)被新学生替换
输出
6=Student [name=ved, rollNumber=12, m1=2, m2=2, m3=2, totMarks=6]
9=Student [name=prakash, rollNumber=56, m1=3, m2=3, m3=3, totMarks=9]
地图中存储的唯一唯一的totMark
最佳答案
由于您无法使用现有的比较器或排序算法,因此需要自己完成.我实现了一个静态函数lessOrEqual,该函数接受2个Student实例,对其进行比较并返回s1是否小于或等于s2.仅当s1大于s2时才返回true的large(student s1,Student s2).可以有许多种不同的方法,这实际上取决于您,因为这只是一个机构.该功能首先检查成绩,如果成绩匹配,它将检查名称并相应返回.
编辑:正如您所看到的,因为我正在使用的选择排序需要查找更大的值,所以我用大替换了lessOrEqual.效果是一样的,我这样做只是为了提高可读性.
然后,我实现了另一个静态函数,该函数接受ArrayList< Student> ;,对其进行排序并返回排序后的结果.所使用的排序算法非常基础:选择排序. O(N ^ 2)效率不高,但是为了简化起见,在下面的演示中我这样做了. 码:
import java.util.ArrayList;
public class Student {
private String name;
private Integer rollNumber;
private int m1;
private int m2;
private int m3;
private int totMarks;
public static boolean larger(Student s1, Student s2){
if(s1.totMarks < s2.totMarks) return false;
else if (s1.totMarks > s2.totMarks) return true;
// compare names
else return s1.name.compareTo(s2.name) > 0;
}
public static ArrayList<Student> sortSelection(ArrayList<Student> list){
for(int i=0; i<list.size(); i++){
for(int j=i+1; j< list.size(); j++){
if(larger(list.get(i), list.get(j))){ // swap
Student temp = list.get(i);
list.set(i, list.get(j));
list.set(j, temp);
}
}
}
return list;
}
//Getter setter
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getTotMarks(){
return totMarks;
}
public void setTotMarks(int totMarks){
this.totMarks = totMarks;
}
@Override
public String toString(){
return String.format("Name: %20s - Total Marks: %3d", name, totMarks);
}
public static void main(String[] args){
Student s1 = new Student();
Student s2 = new Student();
Student s3 = new Student();
Student s4 = new Student();
s1.setName("John Smith");
s1.setTotMarks(98);
s2.setName("Jack Smith");
s2.setTotMarks(98);
s3.setName("Adam Noob");
s3.setTotMarks(100);
s4.setName("Ved Parkash");
s4.setTotMarks(99);
ArrayList<Student> list = new ArrayList<>();
list.add(s4);
list.add(s3);
list.add(s1);
list.add(s2);
System.out.println("Array before sorting:");
for(int i=0; i<list.size(); i++){
System.out.println(list.get(i).toString());
}
Student.sortSelection(list);
System.out.println("Array after sorting:");
for(int i=0; i<list.size(); i++){
System.out.println(list.get(i).toString());
}
}
}
输出:
Array before sorting:
Name: Ved Parkash - Total Marks: 99
Name: Adam Noob - Total Marks: 100
Name: John Smith - Total Marks: 98
Name: Jack Smith - Total Marks: 98
Array after sorting:
Name: Jack Smith - Total Marks: 98
Name: John Smith - Total Marks: 98
Name: Ved Parkash - Total Marks: 99
Name: Adam Noob - Total Marks: 100
笔记:
1)看到添加到列表中的学生的顺序,是4,3,1,然后是2.这是为了证明当年级匹配时,它会根据名称进行排序(杰克·史密斯与约翰·史密斯).
2)我对学生进行了硬编码,以使其更好地进行演示.
3)您可能会注意到,由于问题仅与排序有关,因此我没有设置任何其他变量,并且对排序唯一起作用的变量是:name和totMarks.您将不得不做剩下的事情.
4)我使用的是ArrayList,但不仅限于此,只需进行简单的更改,就可以在普通的Student []数组上使用它.
5)较大的函数不必是静态的,您可以使其成为成员函数并以不同的方式使用它.例如,上面的代码将更改为:
public boolean larger(Student other){
if(totMarks < other.totMarks) return false;
else if (totMarks > other.totMarks) return true;
// compare names
else return name.compareTo(other.name) > 0;
}
public static ArrayList<Student> sortSelection(ArrayList<Student> list){
for(int i=0; i<list.size(); i++){
for(int j=i+1; j< list.size(); j++){
// comparison way changes accordingly
if(list.get(i).larger(list.get(j))){ // swap
Student temp = list.get(i);
list.set(i, list.get(j));
list.set(j, temp);
}
}
}
return list;
}