我有一个字符串数组List<String[]>
的列表,看起来像这样:
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[]>
newDataLine
,其中0th
,1st
,3rd
和5th
元素相同,并将它们的6th
元素相加。
预期输出:
["2002","BRBTSS","BRSTNCNTF212","BRL","12670012.4055","84M","-101.87","0"],
["2002","BRBTSS","BRSTNCNTF212","BRL","12670012.4055","120M","-124.08000000000001","0"],
["2002","BRBTSS","BRSTNCNTF212","BRL","12670012.4055","60M","-214.14","0"],
["2002","BRBTSS","BRSTNCNTF212","CZK","12670012.4055","60M","-103.75","0"],
["2002","BRBTSS","BRSTNCNTF212","BRL","12670012.4066","20M","-10.8","0"]
我试过以下方法:
Map<String, Map<String, Map<String, Map<String, Double>>>> map =
dataLines.stream()
.collect(Collectors.groupingBy(
s -> s[0],
Collectors.groupingBy(s -> s[1],
Collectors.groupingBy(s -> s[3],
Collectors.groupingBy(s -> s[5],
Collectors.summingDouble(s -> Double.valueOf(s[6])))))
));
输出如下:
{2002={BRBTSS={BRL={84M=-101.87, 60M=-214.14, 120M=-124.08000000000001}}}}
如何以上述方式对数据进行分组?
我想要新的列表list <String[]>newDataLine,如果第0,第1,第3,第5是相同的,则添加第6个元素
要以所需的方式对这些数组进行分组并合并它们的数据,可以使用HashMap
,非嵌套的。嵌套映射,就像你代码中的那样,很麻烦,很难处理。
record
,但它也可以实现class
。
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};
}
}
如果我们把它翻译成class
,这是它的样子:
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};
}
}
注意:
List<String[]>
-不是最方便拨号的类型,最好避免将数组和集合混合使用。这些数组应该是自定义对象首先,因为你希望它们包含特定数量的元素,每个元素都有特定的形状。如果您将它们组织到一个类中,您的数据将具有一个结构,每个元素将成为具有适当数据类型的属性,而不是一个无名的String。
当不想失去精度(例如)时,非常建议使用
BigDecimal
而不是Double
进行浮点计算。虽然summingDouble()
是为了减少不准确性而实现的,但double
不是计算价格、税率等的好选择。
流应该是这样的:
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)));
输出:
[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]