java问题:有个类Student Student stu=null 与Student stu= new Student()有和区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java问题:有个类Student Student stu=null 与Student stu= new Student()有和区别相关的知识,希望对你有一定的参考价值。

Student stu=null是初始化赋值,Student stu= new Student()是在堆中创建一个Student对象的空间,并stu指向改空间地址,stu的值为内存地址。用前者调用Student中的属性会空指针异常,后者则不会。 参考技术A 前者就是把一个Student类型的指针存在了stu里,但是,这个stu没有指向对象内存;后者是让这个Student类型的指针stu指向对象内存中的一个默认Student的类对象。 参考技术B null还没有申请内存空间,也就是只是申明了,还是没生出来,new就是已经申请内存空间生出出来了 参考技术C Student stu=null ; 空指针
stu 没有指向任何内存地址
Student stu= new Student()
stu 指针指向了一个新分配的内存地址
参考技术D 第一个没有内存地址,第二个有内存地址

Java - 如何找到在 Student 类中编写方法的得分最高的学生?

【中文标题】Java - 如何找到在 Student 类中编写方法的得分最高的学生?【英文标题】:Java - How to find students with their highest marks writing a method in a Student class? 【发布时间】:2020-04-02 00:16:27 【问题描述】:

我是 Java 初学者,但被困在一项任务中。如果有人能帮助我,我将不胜感激。我有一个具有这些属性的学生班级 - 姓名、化学标记、数学标记和物理标记。在 Main 类中,我创建了一个包含几个学生的 ArrayList。我的任务是找到所有学生中化学分数最高、数学分数最高、物理分数最高的学生(他们的名字)。我在 Main 类的 main 方法中这样做了,但问题是我必须在 Student 的类中编写它,而此时我没有这样做。

这是我的代码:

public class Student 

    protected String name;
    private int chemistry;
    private int mathematics;
    private int physics;


    public Student(String name, int chemistry, int mathematics, int physics) 
        this.name = name;
        this.chemistry = chemistry;
        this.mathematics = mathematics;
        this.physics = physics;
    

    public int getChemistry() 
        return chemistry;
    

    public void setChemistry(int chemistry) 
        this.chemistry = chemistry;
    

    public int getMathematics() 
        return mathematics;
    

    public void setMathematics(int mathematics) 
        this.mathematics = mathematics;
    

    public int getPhysics() 
        return physics;
    

    public void setPhysics(int physics) 
        this.physics = physics;
    

import java.util.ArrayList;

public class Main 

    public static void main(String[] args) 


        Student tom = new Student("Tom", 7, 6, 4);
        Student rome = new Student("Rome", 9, 5, 8);
        Student jack = new Student("Jack", 6, 9, 8);
        Student simon = new Student("Simon", 10, 8, 5);
        Student darek = new Student("Darek", 10, 9, 8);

        ArrayList<Student> students = new ArrayList<>();

        students.add(tom);
        students.add(rome);
        students.add(jack);
        students.add(simon);
        students.add(darek);


        System.out.println("Student(s) with the highest Chemistry grade among all students:");

        int max = 0;
        String names = null;
        for (int i = 0; i < students.size(); i++) 
            if (max == students.get(i).getChemistry())  
                names += ", " + students.get(i).name;
             else if (max < students.get(i).getChemistry()) 
                       max = students.get(i).getChemistry(); 
                       names = students.get(i).name; 
            
        
        System.out.println(names);


        System.out.println();
        System.out.println("Student(s) with the highest Mathematics grade among all students:");

        max = 0;
        names = null;
        for (int i = 0; i < students.size(); i++) 
            if (max == students.get(i).getMathematics()) 
                names += ", " + students.get(i).name;
             else if (max < students.get(i).getMathematics()) 
                       max = students.get(i).getMathematics();
                       names = students.get(i).name; 
            
        
        System.out.println(names);


        System.out.println();
        System.out.println("Student(s) with the highest Physics grade among all students:");


        max = 0;
        names = null;
        for (int i = 0; i < students.size(); i++) 
            if (max == students.get(i).getPhysics()) 
                names += ", " + students.get(i).name;
             else if (max < students.get(i).getPhysics()) 
                       max = students.get(i).getPhysics();
                       names = students.get(i).name; 
            
        
        System.out.println(names);

    

我尝试在Student类中写一个类似的方法:

public int bestOfChemistry(int max, String names) 
        if (max == chemistry) 
            names += ", " + name;   
         else if (max < chemistry) 
            max = chemistry;
            names = name;
        
        return max;
    

但是当我尝试在 Main 类中使用此方法时,我只能获得最高分。我知道,因为我只在 bestOfChemistry(..) 方法中返回它,但我也不知道如何获取它们的名称:

int max = 0;
String names = null;
for (int i = 0; i < students.size(); i++) 
            max = students.get(i).bestOfChemistry(max, names);
        
        System.out.println(max);

我也不知道如何为这三个课程编写一个方法,以避免几个相同的方法。

【问题讨论】:

stavla - 如果其中一个答案解决了您的问题,您可以通过将其标记为已接受来帮助社区。接受的答案有助于未来的访问者自信地使用该解决方案。查看meta.stackexchange.com/questions/5234/… 了解如何操作。 【参考方案1】:

您不应该在一个表示单个对象的类中创建引用多个对象的方法,这在语义上没有意义。

编辑:由于您不允许在主课中这样做,您可以添加一个新课程,其功能是搜索最优秀的学生。例如,我将其命名为“StudentsFinder”。它看起来像这样:

class StudentsFinder 

    private final ArrayList<Student> students;
    private ArrayList<String> bestStudents;

    StudentsFinder(ArrayList<Student> students) 
        this.students = students;
    

    ArrayList<String> getBestChemistryStudents() 
        bestStudents = new ArrayList<>();
        int maxChemistryGrade = 0;
        //We look for the best grade first.
        for (Student student : students) 
            if (student.getChemistry() > maxChemistryGrade) 
                maxChemistryGrade = student.getChemistry();
            
        
        //Now we can add those students with the best grade in the array
        for (Student student : students) 
            if (student.getChemistry() == maxChemistryGrade) 
                bestStudents.add(student.getName());
            
        
        //And we return the results
        return bestStudents;
    
    //The following methods do the same thing but with math and physics grades, respectively 
    ArrayList<String> getBestMathStudents() 
        bestStudents = new ArrayList<>();
        int maxMathGrade = 0;
        for (Student student : students) 
            if (student.getMathematics() > maxMathGrade) 
                maxMathGrade = student.getMathematics();
            
        
        for (Student student : students) 
            if (student.getMathematics() == maxMathGrade) 
                bestStudents.add(student.getName());
            
        
        return bestStudents;
    

    ArrayList<String> getBestPhysicsStudents() 
        bestStudents = new ArrayList<>();
        int maxPhysicsGrade = 0;
        for (Student student : students) 
            if (student.getPhysics() > maxPhysicsGrade) 
                maxPhysicsGrade = student.getPhysics();
            
        
        for (Student student : students) 
            if (student.getPhysics() == maxPhysicsGrade) 
                bestStudents.add(student.getName());
            
        
        return bestStudents;
    

在 Student 类中,您将需要一个获取名称的方法:

public String getName() 
    return name;

然后,您可以在主类中添加一个新的 StudentsFinder 实例,在构造函数中将学生数组传递给它,并调用每个方法:

StudentsFinder finder = new StudentsFinder(students);

System.out.println("Student(s) with the highest Chemistry grade among all students:");
System.out.println(finder.getBestChemistryStudents());

System.out.println("Student(s) with the highest Mathematics grade among all students:");
System.out.println(finder.getBestMathStudents());

System.out.println("Student(s) with the highest Physics grade among all students:");
System.out.println(finder.getBestPhysicsStudents());

请注意,我们可以将结果直接传递给println() 方法:

System.out.println(finder.getBestChemistryStudents());

...因为它会自动调用ArrayList 中的toString(),其实现继承自AbstractCollection 类。它以[value1, value2, ..., valueN] 格式打印所有值。

【讨论】:

他不是问在Student类中如何实现吗?我认为他已经在main() 中找到了实现这一目标的方法 谢谢,这是使用 Arraylist 找到最佳化学学生的另一种好方法。但我的任务是在学生或其他班级中写出最高分的计算,但不是主要的。这不是我的决定,所以我必须这样做。或许您知道您的代码在主类中的样子? @stavla 我编辑了我的答案,检查一下。如果您有任何问题,请告诉我。【参考方案2】:

我猜你有一些设计问题。类是您将在其上初始化一个对象的蓝图,在这种情况下,每个学生对象都是一个单独的学生,具有名称、化学、物理、数学的属性。在 Student 类中有一个方法来为您提供最高分的学生姓名列表是没有意义的。所以,我的建议是有一个 Clas-s-room、Course 或 School 类,它们将具有诸如学生列表之类的属性。在该课程中,获取获得最高分的学生列表的功能很有意义,因为对于每个教室,可以说您可以找到它。希望对你有帮助。

【讨论】:

当您将其标记为无用答案时,请您发表评论。 我赞成你的回答,因为它与其他答案不同 这是一个非常合乎逻辑的评论,谢谢。我的班级教室应该扩展学生的班级还是应该是独立班级?另外,我不知道我可以从 Main 调用它的新类中***方法的语法应该是什么。 Clas-s-room 类可能有 ArrayList 其中 Student 是您编写的类。扩展意味着您正在基于基类创建子类。学生类不是 Clas-s-room 的基类,但例如Person 类可能是 Student 类的超类,因此 Student 可以从 Person 类扩展。说方法的语法是指它的签名? 对不起,我指的是代码。我不知道如何编写一种方法来找到班级教室中成绩最高的学生。我认为应该是我在 Main 类中写的类似循环?【参考方案3】:

最简单的方法:

import java.util.ArrayList;

public class Main 
    public static void main(String[] args) 
        Student tom = new Student("Tom", 7, 6, 4);
        Student rome = new Student("Rome", 9, 5, 8);
        Student jack = new Student("Jack", 6, 9, 8);
        Student simon = new Student("Simon", 10, 8, 5);
        Student darek = new Student("Darek", 10, 9, 8);
        derek.bestChem();
        derek.bestPhys();
        derek.bestMath();

public class Student 
    private String name;
    private int chemistry;
    private int mathematics;
    private int physics;
    public static ArrayList<Student> students= new ArrayList<Student>();

    public Student(String name, int chemistry, int mathematics, int physics) 
        this.name = name;
        this.chemistry = chemistry;
        this.mathematics = mathematics;
        this.physics = physics;
        students.add(this);
    

    public int getChemistry() 
        return chemistry;
    

    public void setChemistry(int chemistry) 
        this.chemistry = chemistry;
    

    public int getMathematics() 
        return mathematics;
    

    public void setMathematics(int mathematics) 
        this.mathematics = mathematics;
    

    public int getPhysics() 
        return physics;
    

    public void setPhysics(int physics) 
        this.physics = physics;
    
    public String getName()
        return name;
    
    public void bestChem()
        int x=-2;
        String y="";
        for (int j=0; j< students.size(); j++)
            if (students.get(j).getChemistry()>x) 
                x=students.get(j).getChemistry();
                y=students.get(j).getName();
            
        
        System.out.println("Student(s) with the highest Chemistry grade among all students:" + y);
    
    public void bestPhys()
        int x=-2;
        String y="";
        for (int j=0; j< students.size(); j++)
            if (students.get(j).getPhysics()>x) 
                x=students.get(j).getPhysics();
                y=students.get(j).getName();
            
        
        System.out.println("Student(s) with the highest Physics grade among all students:" + y);
    
    public void bestMath()
        int x=-2;
        String y="";
        for (int j=0; j<students.size(); j++)
            if (students.get(j).getMathematics()>x) 
                x=students.get(j).getMathematics();
                y=students.get(j).getName();
            
        
        System.out.println("Student(s) with the highest Mathematics grade among all students:" + y);
    

【讨论】:

ArrayList 类中没有length() 方法(也许您的意思是size())。并且请在回答之前检查其他答案,以确保您没有重复任何想法或概念。 你是对的,我现在要改变它。谢谢@Steyrix 我不完全理解,能否请您澄清一下 - 如果我们用一个学生调用 bestChem() 方法,在这个例子中 - 使用darek.bestChem() - 循环如何这种方法可以在所有学生中搜索吗? ArrayList 学生是静态的,这意味着无论它当前在哪个学生中,它都将保持不变。有关静态字段的更多信息:techopedia.com/definition/24033/static-field@stavla【参考方案4】:
public enum Subject
    CHEMISTRY,
    MATH,
    PHYSICS;



public String findNameOfTheBest(List<Student> students, Subject subject)
    switch(subject)
        case CHEMISTRY:
            return students.stream().sorted(Comparator.comparingInt(Student::getChemistry).reversed()).findFirst().map(Student::getName).get();
        case MATH:
            return students.stream().sorted(Comparator.comparingInt(Student::getMathematics).reversed()).findFirst().map(Student::getName).get();
        case PHYSICS:
            return students.stream().sorted(Comparator.comparingInt(Student::getPhysics).reversed()).findFirst().map(Student::getName).get();
        default:
            throw new Exception("unknown subject type");
    
 

只需使用不同的主题类型调用此方法并将返回值分配给变量。一个简短的解释:它通过属性之一对列表中的每个学生对象进行排序,这些属性可以是化学、数学或物理,具体取决于您传入的主题(例如 Subject.CHEMISTRY)。然后它反转排序,使最高标记位于列表的最开始。然后它调用 findFirst() 返回一个 Optional。在这个 Optional 上调用了一个 map 方法,它基本上将元素从 Student 对象转换为其属性“名称”。

编辑:这是考虑到多个学生获得最高成绩的可能性的调整方法。

public List<String> findNameOfTheBest(List<Student> students, Subject subject)
    switch(subject)
        case CHEMISTRY:
            int highestMark = students.stream().max(Comparator.comparingInt(Student::getChemistry)).get();
            return students.stream().filter(student -> student.getChemistry == highestMark).map(Student::getName).collect(Collectors.toList());
        case MATH:
            int highestMark = students.stream().max(Comparator.comparingInt(Student::getMathematics)).get();
            return students.stream().filter(student -> student.getMathematics == highestMark).map(Student::getName).collect(Collectors.toList());
        case PHYSICS:
            int highestMark = students.stream().max(Comparator.comparingInt(Student::getPhysics)).get();
            return students.stream().filter(student -> student.getPhysics == highestMark).map(Student::getName).collect(Collectors.toList());
        default:
            throw new Exception("unknown subject type");
    
 

【讨论】:

如果有两个或多个学生的科目成绩最高,它只返回一个学生怎么办? @stavla 我已经包含了一个可以返回名称列表的新方法

以上是关于java问题:有个类Student Student stu=null 与Student stu= new Student()有和区别的主要内容,如果未能解决你的问题,请参考以下文章

Java定义学生类student

Java之经典Student问题2

在派生类中调用重写的方法

Java基础知识之初始化——初始化顺序

Java 设计一个Student类

从 List<Student> 中获取具有匹配名称的学生对象而不进行迭代(Java)