I want the new list List<String[]> newDataLine as if 0th,1st,3rd,5th are same then do the addition of 6th element
To group these arrays in the required way and merge their data, you can use a HashMap
, non-nested one. Nested maps, like the one in your code, are cumbersome and difficult to deal with.
For that, we need an object which would serve as a Key. I'll use a Java 16 record
, but it can be implemented a class
as well.
public record Key(String s0, String s1, String s2, String s3, String s4, String s5, String s7) {
public Key(String[] line) {
this(line[0], line[1], line[2], line[3], line[4], line[5], line[7]);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Key key = (Key) o;
return Objects.equals(s0, key.s0) && Objects.equals(s1, key.s1) && Objects.equals(s3, key.s3) && Objects.equals(s5, key.s5);
}
@Override
public int hashCode() {
return Objects.hash(s0, s1, s3, s5);
}
public String[] toArray(Double s6) {
return new String[]{s0, s1, s2, s3, s4, s5, String.valueOf(s6), s7};
}
}
If we translate it into a class
here's how it would look like:
public class Key {
private final String s0;
private final String s1;
private final String s2;
private final String s3;
private final String s4;
private final String s5;
private final String s7;
public Key(String s0, String s1, String s2, String s3, String s4, String s5, String s7) {
this.s0 = s0;
this.s1 = s1;
this.s2 = s2;
this.s3 = s3;
this.s4 = s4;
this.s5 = s5;
this.s7 = s7;
}
public Key(String[] line) {
this(line[0], line[1], line[2], line[3], line[4], line[5], line[7]);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Key key = (Key) o;
return Objects.equals(s0, key.s0) && Objects.equals(s1, key.s1) && Objects.equals(s3, key.s3) && Objects.equals(s5, key.s5);
}
@Override
public int hashCode() {
return Objects.hash(s0, s1, s3, s5);
}
public String[] toArray(Double s6) {
return new String[]{s0, s1, s2, s3, s4, s5, String.valueOf(s6), s7};
}
}
Note:
List<String[]>
- is not the most convenient type to dial with, and it's better to avoid mixing arrays and Collections.
These Arrays should be custom Objects, to begin with, because you're expecting them to contain a particular number of elements and each to have a certain shape. If you organize them into a class, your data would have a structure, each element would become a property with an appropriate data type, instead of being a nameless String.
It's highly advisable to use BigDecimal
instead of Double
for floating-point calculations when don't want to lose precision (e.g.). Although Collector summingDouble()
is implemented to mitigate inaccuracies, double
is not a good choice for calculating prices, tax rates, etc.
And here how the stream would look like:
List<String[]> dataLines = List.of(
new String[]{"2002", "BRBTSS", "BRSTNCNTF212", "BRL", "12670012.4055", "84M", "-101.87", "0"},
new String[]{"2002", "BRBTSS", "BRSTNCNTF212", "BRL", "12670012.4055", "120M", "-102.48", "0"},
new String[]{"2002", "BRBTSS", "BRSTNCNTF212", "BRL", "12670012.4055", "60M", "-103.75", "0"},
new String[]{"2002", "BRBTSS", "BRSTNCNTF212", "BRL", "12670012.4055", "120M", "-10.8", "0"},
new String[]{"2002", "BRBTSS", "BRSTNCNTF212", "BRL", "12670012.4055", "60M", "-110.39", "0"},
new String[]{"2002", "BRBTSS", "BRSTNCNTF212", "BRL", "12670012.4055", "120M", "-10.8", "0"},
new String[]{"2002", "BRBTSS", "BRSTNCNTF212", "CZK", "12670012.4055", "60M", "-103.75", "0"},
new String[]{"2002", "BRBTSS", "BRSTNCNTF212", "BRL", "12670012.4066", "20M", "-10.8", "0"}
);
List<String[]> amountByKey = dataLines.stream()
.collect(Collectors.groupingBy(
Key::new,
Collectors.summingDouble(s -> Double.parseDouble(s[6]))
))
.entrySet().stream()
.map(entry -> entry.getKey().toArray(entry.getValue()))
.collect(Collectors.toList());
newDataLine.forEach(arr -> System.out.println(Arrays.toString(arr)));
Output:
[2002, BRBTSS, BRSTNCNTF212, BRL, 12670012.4055, 84M, -101.87, 0]
[2002, BRBTSS, BRSTNCNTF212, BRL, 12670012.4055, 60M, -214.14, 0]
[2002, BRBTSS, BRSTNCNTF212, BRL, 12670012.4055, 120M, -124.08000000000001, 0]
[2002, BRBTSS, BRSTNCNTF212, BRL, 12670012.4066, 20M, -10.8, 0]
[2002, BRBTSS, BRSTNCNTF212, CZK, 12670012.4055, 60M, -103.75, 0]