如何在Eclipse中为Java中的每个扫描规程创建新列表

idv4meu8  于 2023-04-10  发布在  Java
关注(0)|答案(2)|浏览(94)

我想打印包含以下信息的列表:
| 学科|等级|平均|
| --------------|--------------|--------------|
| 纪律1|1级、2级、3级、|平均纪律1|
| 纪律2|1级、2级、3级、|平均纪律1|
问题是我只做了一份成绩单,我不知道如何为每一门学科都做一份新的清单。
我试过这个:

package graduation;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class GraduationGrade {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        List <String> disciplines = new ArrayList<>();
        List <Integer> disciplineGrades = new ArrayList<>();
        List <Integer> disciplineAverage = new ArrayList<>();
        int i=0;

        
        while(true) {
            System.out.println("Please enter a discipline or type EXIT");
            Scanner sc = new Scanner(System.in);
            String discipline = sc.next();
    
            
            if(discipline.equals("EXIT")) {
                
                System.out.println("    DISCIPLINE      GRADES          AVERAGE "); 
                
                for (int j = 0; j < disciplines.size(); j++) {
                    System.out.println((j + 1) + "      " + disciplines.get(j) + "       " + disciplineGrades.get(j)+ "         " + disciplineAverage.get(j));
                }
                
                break;
            } else {
                System.out.println("Please enter how many grades do you have for " + discipline);
                sc = new Scanner(System.in);
                int gradeNumbers = sc.nextInt();
                
                do {
                    System.out.println("Please enter your grades for " + discipline + " one by one (between 4 and 10)");
                    sc = new Scanner(System.in);
                    int grades = sc.nextInt();
        
                    int sum = disciplineGrades.stream().mapToInt(Integer::intValue).sum();
                    int average= sum/gradeNumbers;
                    
                    disciplines.add(discipline);
                    disciplineGrades.add(grades);
                    disciplineAverage.add(average);
                    i++;
                    
                    
                } while(i<gradeNumbers);
                
            
            }
        }
    }

}

当我运行程序时,这是我得到的:

Please enter a discipline or type EXIT
Math
Please enter how many grades do you have for Math
4
Please enter your grades for Math one by one (between 4 and 10)
4
Please enter your grades for Math one by one (between 4 and 10)
5
Please enter your grades for Math one by one (between 4 and 10)
6
Please enter your grades for Math one by one (between 4 and 10)
7
Please enter a discipline or type EXIT
Biology
Please enter how many grades do you have for Biology
10
Please enter your grades for Biology one by one (between 4 and 10)
8
Please enter your grades for Biology one by one (between 4 and 10)
6
Please enter your grades for Biology one by one (between 4 and 10)
7
Please enter your grades for Biology one by one (between 4 and 10)
5
Please enter your grades for Biology one by one (between 4 and 10)
4
Please enter your grades for Biology one by one (between 4 and 10)
6
Please enter a discipline or type EXIT
EXIT
DISCIPLINE      GRADES          AVERAGE 
1       Math         4      0
2       Math         5      1
3       Math         6      2
4       Math         7      3
5       Biology      8      2
6       Biology      6      3
7       Biology      7      3
8       Biology      5      4
9       Biology      4      4
10      Biology      6      5
ruarlubt

ruarlubt1#

源代码的问题在于,它将每个学科的所有成绩存储在一个列表(disciplineGrades)中。因此,在计算平均值时,它使用所有成绩的总和,而不是特定学科的成绩总和。
要解决这个问题,需要创建一个列表列表,分别存储每个学科的成绩,可以修改代码如下:

package graduation;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class GraduationGrade {

    public static void main(String[] args) {
        List<String> disciplines = new ArrayList<>();
        List<List<Integer>> disciplineGrades = new ArrayList<>();
        List<Integer> disciplineAverages = new ArrayList<>();

        while(true) {
            System.out.println("Please enter a discipline or type EXIT");
            Scanner sc = new Scanner(System.in);
            String discipline = sc.next();

            if(discipline.equals("EXIT")) {
                System.out.println("    DISCIPLINE      GRADES          AVERAGE ");
                for (int j = 0; j < disciplines.size(); j++) {
                    List<Integer> grades = disciplineGrades.get(j);
                    int sum = grades.stream().mapToInt(Integer::intValue).sum();
                    int average = sum / grades.size();
                    System.out.println((j + 1) + "      " + disciplines.get(j) + "       " + grades.toString() + "         " + average);
                }
                break;
            } else {
                System.out.println("Please enter how many grades do you have for " + discipline);
                sc = new Scanner(System.in);
                int gradeNumbers = sc.nextInt();

                List<Integer> grades = new ArrayList<>();
                for (int i = 0; i < gradeNumbers; i++) {
                    System.out.println("Please enter your grade for " + discipline + " (between 4 and 10)");
                    sc = new Scanner(System.in);
                    int grade = sc.nextInt();
                    grades.add(grade);
                }

                disciplines.add(discipline);
                disciplineGrades.add(grades);
            }
        }
    }
}

这段代码创建一个名为disciplineGradesList<List<Integer>>来保存每个学科的成绩。当添加一个新学科时,将创建一个新的空成绩列表并添加到disciplineGrades中。然后,当用户输入该学科的成绩时,这些成绩将添加到disciplineGrades中的相应列表中。
当程序完成接受输入时,通过迭代disciplineGrades列表,对每个学科的分数求和,然后除以分数,计算每个学科的平均分数。平均值存储在一个单独的List<Integer>中,称为disciplineAverages
最后,当用户输入“EXIT”时,程序通过迭代disciplinesdisciplineGradesdisciplineAverages列表,检索每个学科的相应值,并以所需格式打印出学科、成绩和平均值的表。
最终输出如下。

Please enter a discipline or type EXIT
Math
Please enter how many grades do you have for Math
4
Please enter your grade for Math (between 4 and 10)
4
Please enter your grade for Math (between 4 and 10)
5
Please enter your grade for Math (between 4 and 10)
6
Please enter your grade for Math (between 4 and 10)
7
Please enter a discipline or type EXIT
Biology
Please enter how many grades do you have for Biology
10
Please enter your grade for Biology (between 4 and 10)
4
Please enter your grade for Biology (between 4 and 10)
5
Please enter your grade for Biology (between 4 and 10)
6
Please enter your grade for Biology (between 4 and 10)
7
Please enter your grade for Biology (between 4 and 10)
8
Please enter your grade for Biology (between 4 and 10)
9
Please enter your grade for Biology (between 4 and 10)
4
Please enter your grade for Biology (between 4 and 10)
5
Please enter your grade for Biology (between 4 and 10)
6
Please enter your grade for Biology (between 4 and 10)
7
Please enter a discipline or type EXIT
EXIT
    DISCIPLINE      GRADES          AVERAGE 
1      Math       [4, 5, 6, 7]         5
2      Biology       [4, 5, 6, 7, 8, 9, 4, 5, 6, 7]         6
rt4zxlrg

rt4zxlrg2#

首先,不要将Scanner声明放入while循环中。在每次while循环迭代时,您都要声明一个新的Scanner对象。您只需要一个Scanner,因此在成员区域中声明它,以便它可以在整个类中全局使用。您还声明了一个新的Scanner for ever prompt(sc = new Scanner(System.in);)......尽量不要这样做。
不要使用一堆List,而是使用一个Discipline List(List<Discipline>)。创建一个Discipline对象类,并将其用于您的oneList。
在所有提示中验证用户的输入也是一个好主意,这样就不会遇到任何错误。你会注意到在提供的可运行代码中,我喜欢只对所有字母,数字或字母数字输入提示使用Scanner#nextLine()方法。然而,是个人的选择,因为我发现它是最灵活的,我不需要利用 Try/Catch 机制进行提示验证。
下面的可运行代码使用了一个Discipline类。虽然在下面的演示代码中,它是一个 * 内部类 ,但它实际上应该是一个*.java**类文件。下面是可运行代码。请务必阅读代码中的所有注解。如果您愿意,您可以在完成这些注解时删除它们,因为太多的注解可能会相当显眼。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class GraduationGrade {
    
    // Member variables:
    // OS related newline character sequence.
    private final String ls = System.lineSeparator();
    
    /* Open a keyboard input Stream. Do not close. The JVM
       will close this resource automatically when the app
       closes.                     */
    private final Scanner userInput = new Scanner(System.in);
    
    /* List of available school courses that can be entered by 
       the User. This is used for Discipline entry validation.
       Any courses can be added or removed from this list.  */
    private final List<String> coursesList = Arrays.asList(
            "English", "Math", "Art", "Science", "History", "Music",
            "Geography", "P.E.", "Drama", "Biology", "Chemistry",
            "Physics", "I.T.", "Foreign Languages", "Social Studies", 
            "Technology", "Philosophy", "Graphic Design", "Literature",
            "Algebra", "Geometry"
        );
    
    
    // Application start entry point method:
    public static void main(String[] args) {
        /* App started this way to avoid the need for statics
           except where desired.        */
        new GraduationGrade().StartApp(args);  // See the `startApp()` method.
    }

    private void StartApp(String[] args) {
        /* List Interface of Discipline (List<Discipline>) to hold all 
           instances of created disciplines.        */
        List<Discipline> disciplinesList = new ArrayList<>();
        
        // Variable to hold Discipline Number (ID):
        int idx = 0;
        
        // Variable to hold current discipline name (Math, Art, Biology, etc):
        String discipline;

        // Main Outer `while` loop (enter 'e' to print table and exit this loop:
        while (true) {
            discipline = ""; // Initialize `discipline` to hold Null String:
            
            // Prompt for Discipline Name (Math, Art, Biology, etc):
            while (discipline.isEmpty()) {
                System.out.print("Please enter a Discipline (e to exit): -> ");
                discipline = userInput.nextLine().trim();  // Get User input:
                
                // Validate Input...
                boolean haveIt = false; // Flag

                /* Check User supplied discipline name with what is contained
                   within the `coursesList` List:          */
                for (String course : coursesList) {
                    // If the discipline name exist in List then...
                    if (discipline.equalsIgnoreCase(course)) {
                        haveIt = true;       // set flag to boolean true
                        /* Set `discipline` to what it's named within the
                           `coursesList` List. It will be assumed that the
                           `coursesList` will contain proper letter case
                           for the discipline at hand.                  */
                        discipline = course;  
                        break; // Since found, break out of this `for` loop.
                    }
                }
                
                /* If the provided discipline name does not exist and
                   the provided discipline name is not the letter 'e'
                   inform of invalid entry and permit the User to view
                   all available courses that can be entered.      */
                if (!haveIt && !discipline.equalsIgnoreCase("e")) {
                    System.out.println("Invalid Discipline Entry (" + discipline + ")! Not In Course List!");
                    String listIt = "";
                    while (listIt.isEmpty()) {
                        System.out.print("Enter 'List' to see course list or just ENTER to skip: -> ");
                        listIt = userInput.nextLine().trim();  // Get User input:
                        if (listIt.isEmpty()) {
                            break;
                        }
                        else if (listIt.equalsIgnoreCase("list")) {
                            /* Display the available Courses that can be entered as a
                               four column sorted list within the console window:  */
                            System.out.println();
                            System.out.println("Available Courses:" + ls + "==================");
                            Collections.sort(coursesList);
                            int cnt = 0;
                            for (String clst : coursesList) {
                                System.out.printf("%-20s", clst);
                                cnt++;
                                if (cnt == 4) {
                                    System.out.println();
                                    cnt = 0;
                                }
                            }
                            System.out.println(ls);
                        }
                        else {
                            // Otherwise just indicate an Invalid Entry and allow User to try again:
                            System.out.println("Invalid Entry (" + listIt + ")! Try again..." + ls);
                            listIt = ""; // Empty `listIt` to ensure re-loop.
                        }
                    }
                    discipline = ""; // Empty `discipline` to ensure re-loop.
                }
            }
            
            // If the code makes this far, then validation passed!
            // Was 'e' Entered?
            if (discipline.equalsIgnoreCase("e")) {
                // Yes...it was:
                // Display the List of Discipline to the Console Window:
                System.out.println();
                for (int d = 0; d < disciplinesList.size(); d++) {
                    if (d == 0) {
                        System.out.println(disciplinesList.get(d).toTableString(true));
                    }
                    else{
                        System.out.println(disciplinesList.get(d).toTableString());
                    }
                }
                break; // This break will effectively end the application.
            }
            
            // Otherwise, move onto next application Prompt:
            // The Number of Grades for currently supplied Discipline:
            else {
                // PROMPT: Number of grades for supplied Discipline:
                String numOfGrades = ""; // For prompt use
                while (numOfGrades.isEmpty()) {
                    System.out.print("Please enter how many grades do you have for '"
                            + discipline + "': -> ");
                    numOfGrades = userInput.nextLine().trim();  // Get User input:
                    // Validate Input...
                    /* Is the User input a string representation of a unsigned
                       integer value and is that value greater than 0?     */
                    if (!numOfGrades.matches("\\d+") && Integer.parseInt(numOfGrades) > 0) {
                        // No...Inform User of invalid entry and allow to try again:
                        System.out.println("Invalid Entry (" + numOfGrades + ")! Try Again..." + ls);
                        numOfGrades = "";   // Empty `numOfGrades` to ensure re-loop.
                    }
                }
                
                // If the code makes this far, then validation passed!
                // Convert `numOfGrades` into an int type value:
                int numberOfGrades = Integer.parseInt(numOfGrades);
                System.out.println();
                
                /* Declare a List Interface of Integer (List<Integer>) so 
                   to hold all the grades that will be entered for the 
                   supplied Discipline. This list will later be converted
                   to an int[] array so that it can be properly applied 
                   later to a Discipline instance.                */
                List<Integer> gradeList = new ArrayList<>();
                
                // PROMPT: Cycling prompt for Grades entry:
                int j = 1; // Counter used to keep track of the number of grades entered.
                // Outer loop to ensure the proper number of grades are supplied.
                while (j <= numberOfGrades) {
                    String grd = ""; // variable used for prompt input:
                    while (grd.isEmpty()) {
                        System.out.print("Please enter your grade #" + j + " for "
                                        + discipline + " (between 4 and 10): -> ");
                        grd = userInput.nextLine().trim();  // Get User input:
                        
                        /* Is the User input a string representation of a signed
                           or unsigned integer value and is that value inclusively 
                           between 4 qnd 10?     */
                        if (!grd.matches("-?\\d+") && (Integer.parseInt(grd) < 4 || Integer.parseInt(grd) > 10)) {
                            // No...Inform User and allow to try again:
                            System.out.println("Invalid Grade Entry (" + grd + ")! Try Again..." + ls);
                            grd = "";   // Empty `grd` to ensure re-loop.
                        }
                    }
                    
                    // If the code makes this far, then validation passed!
                    // Convert `grd` into an int type value:
                    gradeList.add(Integer.valueOf(grd));
                    j++;  // Increment the number of grades tracker variable.
                }
                
                // Convert List<Integer> to int[] array:
                int[] grades = gradeList.stream().mapToInt(d -> d).toArray();
                
                /* Sum the supplied grades for the supplied Discipline 
                   contained within the `gradesList` List:          */
                double sum = gradeList.stream().mapToInt(Integer::intValue).sum();
                
                // Get the average for those supplied grades:
                double average = sum / numberOfGrades;

                // Create an instance of Discipline and add it to the List:
                disciplinesList.add(new Discipline((idx + 1), discipline, grades, average));
            }
            System.out.println();
            idx++;  // Increment the Discipline number:
        }
    }

    /* INNER CLASS:
       Used this way for demo purpose. Although this works, it
       would be better if it were a .java class file of it's own: */
    public class Discipline {
        // Member variables:
        private int disciplineID;
        private String disciplineName;
        private int[] grades;
        private double gradesAverage;

        // Constructor
        public Discipline(int disciplineID, String disciplineName, int[] grades, double gradesAverage) {
            this.disciplineID = disciplineID;
            this.disciplineName = disciplineName;
            this.grades = grades;
            this.gradesAverage = gradesAverage;
        }

        // Getters and Setters:
        public int getDisciplineID() {
            return disciplineID;
        }

        public void setDisciplineID(int disciplineID) {
            this.disciplineID = disciplineID;
        }

        public String getDisciplineName() {
            return disciplineName;
        }

        public void setDisciplineName(String disciplineName) {
            this.disciplineName = disciplineName;
        }

        public int[] getGrades() {
            return grades;
        }

        public void setGrades(int[] grades) {
            this.grades = grades;
        }

        public double getGradesAverage() {
            return gradesAverage;
        }

        public void setGradesAverage(double gradesAverage) {
            this.gradesAverage = gradesAverage;
        }

        /**
         * A custom toString() type method for returning Table spaced strings 
         * of instance data.
         * 
         * @param applyTheHeader (boolean - Optional - Default is false) If 
         * set to boolean true then this method will return a lined header 
         * with the table spaced instance data. This would only ever be 
         * supplied for the first call to this method unless you want the 
         * header to be applied to each line of instance data returned. if 
         * nothing is supplied then boolean false is implied.
         * 
         * @return (String)
         */
        public String toTableString(boolean...applyTheHeader) {
            boolean applyHeader = false;
            if (applyTheHeader.length > 0) {
                applyHeader = applyTheHeader[0];
            }
            String header = String.format("%-24s %-24s %-6s%n","DISCIPLINE", "GRADES", "AVERAGE");
            String tableTopLine = String.join("", java.util.Collections.nCopies(header.length() - 2, "=")) + ls;
            String headerUnderline = String.join("", java.util.Collections.nCopies(header.length() - 2, "-")) + ls;
            
            StringBuilder sb = new StringBuilder("");
            if(applyHeader) {
                sb.append(tableTopLine).append(header).append(headerUnderline);
            }
            String id = String.valueOf(this.getDisciplineID());
            String dis = String.format("%-4s%-12s", id, disciplineName);
            StringBuilder sb2 = new StringBuilder("");
            for (Integer n : grades) {
                if (!sb2.toString().isEmpty()) {
                    sb2.append(", ");
                }
                sb2.append(n);
            }
            String gradesStrg = sb2.toString();
            String average = String.format("%.2f", gradesAverage);
            String dataLine = String.format("%-24s %-24s %-22s", dis, gradesStrg, average);
            sb.append(dataLine);
            return sb.toString();
        }
        
        @Override
        public String toString() {
            return disciplineID + "; " + disciplineName + "; " 
                    + Arrays.toString(grades).replaceAll("[\\[\\]]", "") + "; " + gradesAverage;
        }
    }
}

运行此代码时,条目可能看起来像....

Please enter a Discipline (e to exit): -> Forign Languages
Invalid Discipline Entry (Forign Languages)! Not In Course List!
Enter 'List' to see course list or just ENTER to skip: -> list

Available Courses:
==================
Algebra             Art                 Biology             Chemistry           
Drama               English             Foreign Languages   Geography           
Geometry            Graphic Design      History             I.T.                
Literature          Math                Music               P.E.                
Philosophy          Physics             Science             Social Studies      
Technology          

Please enter a Discipline (e to exit): -> Foreign Languages
Please enter how many grades do you have for 'Foreign Languages': -> 4

Please enter your grade #1 for Foreign Languages (between 4 and 10): -> 4
Please enter your grade #2 for Foreign Languages (between 4 and 10): -> 5
Please enter your grade #3 for Foreign Languages (between 4 and 10): -> 6
Please enter your grade #4 for Foreign Languages (between 4 and 10): -> 7

Please enter a Discipline (e to exit): -> Music
Please enter how many grades do you have for 'Music': -> 3

Please enter your grade #1 for Music (between 4 and 10): -> 7
Please enter your grade #2 for Music (between 4 and 10): -> 8
Please enter your grade #3 for Music (between 4 and 10): -> 9

Please enter a Discipline (e to exit): -> Biology
Please enter how many grades do you have for 'Biology': -> 5

Please enter your grade #1 for Biology (between 4 and 10): -> 5
Please enter your grade #2 for Biology (between 4 and 10): -> 6
Please enter your grade #3 for Biology (between 4 and 10): -> 7
Please enter your grade #4 for Biology (between 4 and 10): -> 8
Please enter your grade #5 for Biology (between 4 and 10): -> 9

Please enter a Discipline (e to exit): -> e

=========================================================
DISCIPLINE               GRADES                   AVERAGE
---------------------------------------------------------
1   Foreign Languages    4, 5, 6, 7               5.50                  
2   Music                7, 8, 9                  8.00                  
3   Biology              5, 6, 7, 8, 9            7.00

相关问题