Посчитать сумму значений по разным полям объектов
Есть массив объектов Car[] cars. У объектов есть поля: Weight, Price.
Надо посчитать сумму значений всех Weight и всех Price.
Я сделал два метода, которые почти идентичны. Подскажите, пожалуйста, как сделать один универсальный метод, в который можно было бы просто передать инфу о том, какое поле надо посчитать.
public static void sumOfWeights(Car[] cars) {
int sum = 0;
for (Car car : cars) {
sum += car.getWeight();
}
System.out.println("\nTotal weight of all cars = " + sum + " ton");
}
public static void sumOfPrices(Car[] cars) {
int sum = 0;
for (Car car : cars) {
sum += car.getPrice();
}
System.out.println("\nTotal price of all cars = " + sum);
}
Ответы (4 шт):
Как с этими вещами в Java сейчас- не знаю, но когда-то, давным давно (еще когда доллар был по 25 рублей), это можно было сделать так (через рефлексию):
public static void sumOf(Car[] cars, String methodName) {
int sum = 0;
for (Car car : cars) {
method = car.class.getDeclaredMethod(methodName);
sum += method.invoke(null)
}
return sum;
}
Cars[] cars = new Cards[];
//...
sum1 = sumOf(cars, "getWeight");
sum2 = sumOf(cars, "getPrice");
Где-то оно и может пригодиться, но злоупотреблять не нужно
Передавайте функцию, которая будет предоставлять нужные данные из объекта car в самой функции.
public static int sumBy(Car[] cars, Function<Car, Integer> selector) {
int sum = 0;
for (Car car : cars) {
sum += selector.apply(car);
}
return sum;
}
...
int sumOfWeights = sumBy(cars, Car::getWeight);
int sumOfPrices = sumBy(cars, Car::getPrice);
System.out.println("\nTotal weight of all cars = " + sumOfWeights + " ton");
System.out.println("\nTotal price of all cars = " + sumOfPrices);
Но всё уже давно реализовано
int sumOfWeights = Arrays.stream(cars).mapToInt(Car::getWeight).reduce(0, Integer::sum);
int sumOfPrices = Arrays.stream(cars).mapToInt(Car::getPrice).reduce(0, Integer::sum);
public static void main(String[] args) {
Car [] cars = new Car[3];
cars [0] = new Car(1,3);
cars [1] = new Car(2,4);
cars [2] = new Car(3,5);
System.out.println(sum(cars, Car::getPrice));
System.out.println(sum(cars, Car::getWeight));
}
public static <K> Integer sum(K[] cars, Function<K, Integer> function) {
return Arrays.stream(cars)
.map(function)
.reduce(0, (a, b) -> a + b);
}
Выносим в отдельный метод суммирование значений массива объектов по определенному полю:
public static void main(String[] args) {
Car[] cars = {new Car(10, 20), new Car(30, 40)};
System.out.println(sumByField(cars, Car::getWeight)); // 40
System.out.println(sumByField(cars, Car::getPrice)); // 60
}
public static int sumByField(Car[] cars, ToIntFunction<Car> mapper) {
return Arrays.stream(cars).mapToInt(mapper).sum();
}
В классе Car должны присутствовать геттеры, для соответствующих полей:
public class Car {
int weight;
int price;
public Car(int weight, int price) {
this.weight = weight;
this.price = price;
}
public int getWeight() { return weight; }
public int getPrice() { return price; }
}