假設我有這樣的Student課程:
public class Student {
private String name;
private double height;
private double weight;
}
我有一個這樣的學生名單:
private List<Student> studentList;
要求:- 我想計算所有學生的平均體重和身高。
因此,我想撰寫一個名為 的方法findAverage,我可以在其中以某種方式發送fieldNameas 引數,該方法將相應地獲取資料,如下所示:
public double findAverage(List<Student> studentList, String fieldName){
List<Double> numList = new Arraylist<>();
for(Student student: studentList){
numList.add(studentList.getFieldName()); // How do I map the correct field name here?
}
double total = 0.0;
for(Double item: numList){
total = item;
}
return total/(double)numList.size();
}
System.out.println("Average Height :- " findAverage(studentList, height));
System.out.println("Average Weight :- " findAverage(studentList, weight));
uj5u.com熱心網友回復:
使用 java 流 API,您可以使用函式來提取欄位并計算平均值,如下所示:
public static void main(String[] args) {
List<Student> students = ...;
System.out.println(getAverage(students, Student::getHeight));
System.out.println(getAverage(students, Student::getWeight));
}
private static double getAverage(Collection<Student> students, ToDoubleFunction<Student> toDoubleFunction) {
return students
.stream()
.mapToDouble(toDoubleFunction)
.average()
.orElse(Double.NaN);
}
uj5u.com熱心網友回復:
在(常見)寫入的情況下,要訪問的屬性不僅在運行時確定,而且已經在編譯時確定,我建議避免反射。
這意味著,與其嘗試通過提供fieldName欄位名稱(ToDoubleFunction<Student>Function<Student, Double>double
這樣做將使您的代碼對重構更加友好,并且將在編譯時而不是運行時檢測到錯誤。
然后你的函式看起來像這樣
public double findAverage(List<Student> studentList, ToDoubleFunction<Student> getValue) {
List<Double> numList = new Arraylist<>();
for(Student student: studentList){
numList.add(getValue.applyAsDouble(student));
}
return ...;
}
你會像這樣應用它:
double avgHeight = findAverage(studentList, Student::getHeight);
double avgWeight = findAverage(studentList, Student::getWeight);
或(稍長):
double avgHeight = findAverage(studentList, student -> student.getHeight());
double avgWeight = findAverage(studentList, student -> student.getWeight());
uj5u.com熱心網友回復:
你可以通過反射來做到這一點,但它很脆弱。您可以在 中折疊可能的數量,Exception但throws我想更加強調脆弱性。您假設呼叫者可以訪問欄位;有時他們是。但有時他們不是。這取決于包裝和Java版本。不管,private
public double findAverage(List<Student> studentList, String fieldName)
throws NoSuchFieldException, SecurityException,
IllegalArgumentException, IllegalAccessException
{
Field f = Student.class.getField(fieldName);
int count = 0;
double acc = 0;
for (Student student : studentList) {
acc = f.getDouble(student);
count ;
}
if (count > 0) {
return acc / count;
}
return 0;
}
uj5u.com熱心網友回復:
如何使用方法參考來動態定義獲取欄位值的方式:
public class Student {
private String name;
private double height;
private double weight;
// note I define getters here, probably you'll have those anyway
public double getHeight() {return height;}
public double getWeight() {return weight;}
}
現在定義平均計算方法:
import java.util.function.ToDoubleFunction;
...
public double findAverage(List<Student> studentList, ToDoubleFunction<Student> func){
List<Double> numList = new ArrayList<>();
for(Student student: studentList){
// note this call!
numList.add(func.applyAsDouble(student));
}
// whatever you need for calculating the average, omitted
}
現在如果你想計算平均值。你應該:
List<Student> students = ...
findAverage(students, Student::getHeight);
對于平均體重,您可以撥打以下電話:
List<Student> students = ...
findAverage(students, Student::getWeight);
現在,雖然你沒有問,但你也可以使用流來計算平均值。我發布了原始版本,因為它更容易理解ToDoubleFunction這種方式的使用,但可能你希望最終得到(可以說更干凈的)實作:
public double findAverage(List<Student> studentList, ToDoubleFunction<Student> func){
return studentList.stream()
.mapToDouble(func)
.average()
.orElse(0);
}
uj5u.com熱心網友回復:
您可以在 for 回圈中添加一個條件來確定要使用哪個屬性,然后洗掉第二個 for 回圈,因為它是不必要的。
double total = 0;
for(Student student: studentList){
if(fieldName.equals("height")) {
numList.add(studentList.getHeight());
total = studentList.getHeight();
} else {
numList.add(studentList.getWeight());
total = studentList.getWeight();
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/426717.html
標籤:爪哇
