2

I have a 2 column list that has the ff data:

-4123.800000000000;"type1"
-67.620000000000;"type2"
-3128.870000000000;"type2"
-2443.770000000000;"type1"
-30000.000000000000;"type1"
-812.580000000000;"type3"
-8062.990000000000;"type3"
-177.800000000000;"type1"
-28655.400000000000;"type2"

I'm trying to use a for loop and to add the amount if the type is the same. Is this possible for a for loop or is there a better way.

for (int i = 0; i < vecRow.size(); i++) {
    // Do something
}
Arnold Cristobal
  • 843
  • 2
  • 16
  • 36
  • Yes, you can use a `for` loop. You probably want a `Map` too, for collecting the sums, keyed by the type string. If using Java 8, you can also use streams and [collect/grouping](http://stackoverflow.com/q/25441088/5221149). – Andreas Aug 08 '16 at 07:04
  • Mind rounding error when using float/double. If it matters, you may consider using [BigDecimal](https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html). – Fildor Aug 08 '16 at 07:15
  • state clearly and give [mcve](http://stackoverflow.com/help/mcve) – Enamul Hassan Aug 08 '16 at 08:14

1 Answers1

1

In java 8:

    Stream.of("-4123.800000000000;\"type1\"",
            "-67.620000000000;\"type2\"",
            "-3128.870000000000;\"type2\"",
            "-2443.770000000000;\"type1\"",
            "-30000.000000000000;\"type1\"",
            "-812.580000000000;\"type3\"",
            "-8062.990000000000;\"type3\"",
            "-177.800000000000;\"type1\"",
            "-28655.400000000000;\"type2\"")
            .map((s) -> s.split(";", 2))
            .collect(Collectors.toMap(
                    (fields) -> fields[1].replace("\"", ""),
                    (fields) -> new BigDecimal(fields[0]),
                    (oldValue, newValue) -> newValue.add(oldValue)))
            .entrySet()
            .forEach((s) -> System.out.println(s));

Or in parts to better understand

    String[] vecRow = {
            "-4123.800000000000;\"type1\"",
            "-67.620000000000;\"type2\"",
            "-3128.870000000000;\"type2\"",
            "-2443.770000000000;\"type1\"",
            "-30000.000000000000;\"type1\"",
            "-812.580000000000;\"type3\"",
            "-8062.990000000000;\"type3\"",
            "-177.800000000000;\"type1\"",
            "-28655.400000000000;\"type2\"",
    };
    Map<String, BigDecimal> map = Stream.of(vecRow)
        .map((s) -> s.split(";", 2))
        .peek((ss) -> System.out.println(Arrays.toString(ss)))
        .collect(Collectors.toMap(
                (fields) -> fields[1].replace("\"", ""),
                (fields) -> new BigDecimal(fields[0]),
                (oldValue, newValue) -> newValue.add(oldValue)));
    map.entrySet()
        .forEach((s) -> System.out.println(s));

For the evident desire to have a precision one cannot use double, hence: BigDecimal.

Collectors.mapTo here has key mapper, value mapper and - needed to sum - a BigDecimal combiner(BigDecimal, BigDecimal).

type3=-8875.570000000000
type2=-31851.890000000000
type1=-36745.370000000000
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138