欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java-如何在不使用比较器和比较器接口的情况下对地图进行排序?如何编写自定义排序?

程序员文章站 2022-05-27 16:26:09
...

问题-我有一个学生类,它包含名称,卷号,三个主题分数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&gt ;,对其进行排序并返回排序后的结果.所使用的排序算法非常基础:选择排序. 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;
    }