你的方式
使用您的代码,您按职位划分的三个等级中的每一个都可能代表三个不同的课程。我假设您将“法语”课程的所有成绩放在grade1 字段中,将“作文”课程的成绩放在grade2 字段中,将“数学”课程的成绩放在grade3 中。
所以循环学生,分别拉出每个成绩。
float frenchPoints = 0 ;
float compositionPoints = 0 ;
float mathPoints = 0 ;
for( Student student : students )
{
frenchPoints = ( frenchPoints + student.getGrade1() ) ;
compositionPoints = ( compositionPoints + student.getGrade2() ) ;
mathPoints = ( mathPoints + student.getGrade3() ) ;
}
用分数除以分数来取平均值。
如果您想要float 结果,请不要将float(小数)除以int(整数)。因此,在进行除法之前,我们必须将 int 转换为 float。
float frenchAverage = ( frenchPoints / (float) students.size() ) ;
…
我的方式
正如Answer by Bruno Souza Picinini 中所建议的那样,在更现实的情况下,您可以将数据分解为单独的类。您可能会在一个类中表示Student,而该类又可能包含CourseGrade 类的对象集合。
在 Java 16 中,我们可以使用新的 records 特性来简单地编写一个类,其主要目的是透明且不可变地传递数据。编译器隐式创建构造函数、getter、equals & hashCode 和 toString。
public record CourseGrade(String courseName , YearMonth term , Float grade) {}
public record Student(UUID id , String name , Set < CourseGrade > courseGrades) {}
让我们获取一些示例数据。
private List < Student > fetchStudents ( )
{
List < Student > students =
List.of(
new Student( UUID.fromString( "57ce6790-5094-480c-88f5-79ee9e59b9bb" ) , "Alice" ,
Set.of(
new CourseGrade( "French" , YearMonth.of( 2021 , Month.JANUARY ) , 3.2F ) ,
new CourseGrade( "French" , YearMonth.of( 2021 , Month.APRIL ) , 3.6F ) ,
new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.JANUARY ) , 3.3F ) ,
new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.APRIL ) , 3.7F )
)
) ,
new Student( UUID.fromString( "3ed40f58-fb82-44f0-9ae8-7cc1b317085e" ) , "Bob" ,
Set.of(
new CourseGrade( "French" , YearMonth.of( 2021 , Month.JANUARY ) , 2.7F ) ,
new CourseGrade( "French" , YearMonth.of( 2021 , Month.APRIL ) , 2.6F ) ,
new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.JANUARY ) , 2.9F ) ,
new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.APRIL ) , 2.7F )
)
) ,
new Student( UUID.fromString( "9058567e-8a5e-4606-81b0-1def2bb8ceb5" ) , "Carol" ,
Set.of(
new CourseGrade( "French" , YearMonth.of( 2021 , Month.JANUARY ) , 3.0F ) ,
new CourseGrade( "French" , YearMonth.of( 2021 , Month.APRIL ) , 3.1F ) ,
new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.JANUARY ) , 3.2F ) ,
new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.APRIL ) , 3.4F )
)
)
);
return students;
}
编写一个方法来报告特定学期特定课程名称的平均成绩。
我们报告Optional,因为我们可能会在没有提供此类课程的学期中要求课程。因此,如果没有上课,则没有学生获得任何成绩。因此,我们不想报告一个数字,而是要报告一个空的Optional 对象。如果该学期提供的课程有学生注册,那么我们返回一个 Optional,其中包含一个 Float 对象,用于表示平均成绩。
对了,注意浮点类型如float/Floattrade away inaccuracy for speed的执行。如果您关心准确性,请改用BigDecimal 类。
private Optional < Float > reportAverageGradePerCourseInTerm ( String courseName , YearMonth term )
{
Objects.requireNonNull( courseName );
Objects.requireNonNull( term );
List < CourseGrade > courseGrades = new ArrayList <>( this.students.size() );
for ( Student student : this.students )
{
for ( CourseGrade courseGrade : student.courseGrades() )
{
if ( courseGrade.courseName().equals( courseName ) && courseGrade.term().equals( term ) )
{
courseGrades.add( courseGrade ); // If a match on name and term, remember this `CourseGrade` object. Else, forget/skip.
}
}
}
if ( courseGrades.size() == 0 ) { return Optional.empty(); }
float totalPoints = 0F;
for ( CourseGrade courseGrade : courseGrades )
{
totalPoints = totalPoints + courseGrade.grade();
}
Float average = ( totalPoints / ( float ) courseGrades.size() );
return Optional.of( average );
}
使用main 方法将所有代码拉入类App 以驱动演示。
package work.basil.example.reportcard;
import java.time.Month;
import java.time.YearMonth;
import java.util.*;
public class App
{
public static void main ( String[] args )
{
App app = new App();
app.students = app.fetchStudents();
System.out.println( "app.students = " + app.students );
Optional < Float > averageForFrenchIn2021_01 = app.reportAverageGradePerCourseInTerm( "French" , YearMonth.of( 2021 , Month.JANUARY ) );
System.out.println( "averageForFrenchIn2021_01 = " + averageForFrenchIn2021_01 );
}
// Member fields
List < Student > students;
// Logic
private List < Student > fetchStudents ( )
{
List < Student > students =
List.of(
new Student( UUID.fromString( "57ce6790-5094-480c-88f5-79ee9e59b9bb" ) , "Alice" ,
Set.of(
new CourseGrade( "French" , YearMonth.of( 2021 , Month.JANUARY ) , 3.2F ) ,
new CourseGrade( "French" , YearMonth.of( 2021 , Month.APRIL ) , 3.6F ) ,
new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.JANUARY ) , 3.3F ) ,
new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.APRIL ) , 3.7F )
)
) ,
new Student( UUID.fromString( "57ce6790-5094-480c-88f5-79ee9e59b9bb" ) , "Bob" ,
Set.of(
new CourseGrade( "French" , YearMonth.of( 2021 , Month.JANUARY ) , 2.7F ) ,
new CourseGrade( "French" , YearMonth.of( 2021 , Month.APRIL ) , 2.6F ) ,
new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.JANUARY ) , 2.9F ) ,
new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.APRIL ) , 2.7F )
)
) ,
new Student( UUID.fromString( "57ce6790-5094-480c-88f5-79ee9e59b9bb" ) , "Carol" ,
Set.of(
new CourseGrade( "French" , YearMonth.of( 2021 , Month.JANUARY ) , 3.0F ) ,
new CourseGrade( "French" , YearMonth.of( 2021 , Month.APRIL ) , 3.1F ) ,
new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.JANUARY ) , 3.2F ) ,
new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.APRIL ) , 3.4F )
)
)
);
return students;
}
private Optional < Float > reportAverageGradePerCourseInTerm ( String courseName , YearMonth term )
{
Objects.requireNonNull( courseName );
Objects.requireNonNull( term );
List < CourseGrade > courseGrades = new ArrayList <>( this.students.size() );
for ( Student student : this.students )
{
for ( CourseGrade courseGrade : student.courseGrades() )
{
if ( courseGrade.courseName().equals( courseName ) && courseGrade.term().equals( term ) )
{
courseGrades.add( courseGrade ); // If a match on name and term, remember this `CourseGrade` object. Else, forget/skip.
}
}
}
if ( courseGrades.size() == 0 ) { return Optional.empty(); }
float totalPoints = 0F;
for ( CourseGrade courseGrade : courseGrades )
{
totalPoints = totalPoints + courseGrade.grade();
}
Float average = ( totalPoints / ( float ) courseGrades.size() );
return Optional.of( average );
}
}
当main 运行时。
app.students = [Student[id=57ce6790-5094-480c-88f5-79ee9e59b9bb, name=Alice, courseGrades=[CourseGrade[courseName=French, term=2021-04, grade=3.6], CourseGrade[courseName=French, term=2021-01, grade=3.2], CourseGrade[courseName=Composition, term=2021-01, grade=3.3], CourseGrade[courseName=Composition, term=2021-04, grade=3.7]]], Student[id=57ce6790-5094-480c-88f5-79ee9e59b9bb, name=Bob, courseGrades=[CourseGrade[courseName=French, term=2021-04, grade=2.6], CourseGrade[courseName=French, term=2021-01, grade=2.7], CourseGrade[courseName=Composition, term=2021-01, grade=2.9], CourseGrade[courseName=Composition, term=2021-04, grade=2.7]]], Student[id=57ce6790-5094-480c-88f5-79ee9e59b9bb, name=Carol, courseGrades=[CourseGrade[courseName=French, term=2021-04, grade=3.1], CourseGrade[courseName=Composition, term=2021-01, grade=3.2], CourseGrade[courseName=Composition, term=2021-04, grade=3.4], CourseGrade[courseName=French, term=2021-01, grade=3.0]]]]
averageForFrenchIn2021_01 = Optional[2.9666665]
看起来是对的,( 3.2 , 2.7 , 3.0 ) 的平均值是 2.96...。