-2

I have an object with many properties

I want to sum all of 50 values in one properties called sumOfValues;

And also, valueX can be null, this is why I use Double

With java 8.

public class MyObject {

    private String id;
    private String name;

    private Double value1;
    private Double value2;
    ....
    private Double value50;

    private Double sumOfValues;

}

Edit :

All values have to be stored in database, so i can't create a list

Mohammed
  • 89
  • 1
  • 3
  • 12
  • 8
    why not use an array or a list to store all those values? – Ousmane D. Nov 10 '17 at 10:22
  • `DoubleStream.of(value1, value2, ...., value50).sum()` would do the trick. But as @Aominè already said. Why are you storing them into different variables? With a list it would be easier: `list.stream().mapToDouble(Double::valueOf).sum()` – Lino Nov 10 '17 at 10:24
  • yes, and if you also want to be able to identify value for individual props, store them in a map as (prop1,val1),(prop2,val2)...anytime your require iterate and get the sum – akshaya pandey Nov 10 '17 at 10:26
  • If you can't use a list or array, try with introspection and reflection : https://stackoverflow.com/questions/2126714/java-get-all-variable-names-in-a-class – Julien Nov 10 '17 at 10:27
  • I can't use a list, because each value is inserted in database The custumer want to see the value of all properties, and the total. – Mohammed Nov 10 '17 at 10:31
  • Then there's no clean solution, unless you want to resort to reflection. – shmosel Nov 10 '17 at 10:46
  • @Lino With DoubleStream i can't escape null value, Double sum1 = DoubleStream.of(value1, value2).filter(Objects::nonNull).sum(); value2 = null; – Mohammed Nov 10 '17 at 11:00
  • Then just use `Stream.of()` and check for nulls – Lino Nov 10 '17 at 11:01
  • Stream.of(value1, value2).filter(Objects::nonNull).mapToDouble(Double::valueOf).sum(); good, but with 50 properties I think I will use reflection. Thanks !! – Mohammed Nov 10 '17 at 13:55

2 Answers2

3

that's not a good idea and wouldn't work well with streams, nevertheless, you can define an array or a list to store all the Double values, in which case you can then perform the summation of all the values. i.e

when using an array:

double sum1 = Arrays.stream(array).filter(Objects::nonNull).mapToDouble(x -> x).sum();

when using a list:

double sum1 = myList.stream().filter(Objects::nonNull).mapToDouble(e -> e).sum();
Ousmane D.
  • 54,915
  • 8
  • 91
  • 126
1

You can user java reflection to solve this.

I am considering your class having getters and setters for all fields;

so getter for valueX will be getValueX()

myObject.setSumOfValues(
    Arrays.stream(myObject.getClass().getMethods())
          .filter(method -> method.getName().contains("getValue"))
          .mapToDouble(method -> {
              try {
                  Double result = (Double) method.invoke(myObject);
                  return result != null ? result : 0;
              } catch (IllegalAccessException | InvocationTargetException ignored) {
                  return 0;
              }
          })
          .sum()
);
Malte Hartwig
  • 4,477
  • 2
  • 14
  • 30
J.R
  • 2,113
  • 19
  • 21
  • @MohaDarficops at it is very slow too; this is the correct way to do it: https://stackoverflow.com/a/47220632/1059372 – Eugene Nov 10 '17 at 13:58
  • In this case, why not use stream.of(value1, value2).filter(Objects::nonNull).mapToDouble(Double::valueOf).sum(); – Mohammed Nov 10 '17 at 14:09