累积列表中重复元素的值

poo*_*jay 2 java arraylist duplicates

我的列表由具有 Type( String)、Amount( Double) 和 Quantity( Integer) 字段的元素组成,如下所示:

Type: Type A, Amount : 55.0, Quantity : 0
Type: Type A, Amount : 55.0, Quantity : 5
Type: Type A, Amount : 44.35, Quantity : 6
Type: Type A, Amount : 55.0, Quantity : 0
Type: Type B, Amount : 7.0, Quantity : 1
Type: Type B, Amount : 7.0, Quantity : 1
Type: Type C, Amount : 1613.57, Quantity : 0
Type: Type C, Amount : 1613.57, Quantity : 1
Run Code Online (Sandbox Code Playgroud)

因此,我尝试循环数组以查找重复项,如果重复则添加金额。结果会是这样的:

Type: Type A, Amount : 209.35.0, Quantity : 11
Type: Type B, Amount : 14.0, Quantity : 2
Type: Type C, Amount : 3227.14, Quantity : 1
Run Code Online (Sandbox Code Playgroud)

我尝试过创建另一个列表,将列表添加到新列表,然后比较它们,但没有用

List<Type> newList = new ArrayList();

for(int k = 0; k < typeList.size(); k++) {
    Type type= new Type();
    Double totalAmount = Double.parseDouble("0");
    type.setTypeName(typeList.get(k).getTypeName());
    type.setAmount(chargeTypeList.get(k).getAmount());

    newList.add(k, type);

    if(typeList.get(k).getChargeTypeName().equalsIgnoreCase(newList.get(k).getiTypeName())) {
        totalAmount += typeList.get(k).getAmount();
    }
}
Run Code Online (Sandbox Code Playgroud)

我不想对值进行硬编码以检查重复类型

Mar*_*unn 5

您可能应该将这些值放入 M​​ap 中,这保证每个键只有一个元素。使用地图来表示某些事物的数量是很常见的,我们将事物存储为键并跟踪我们在值中拥有多少这些事物。

您可以使用compute然后将元素添加到列表中。

您目前拥有的:

record Data(String type, Double amount, Integer quantity) {}
Run Code Online (Sandbox Code Playgroud)

什么可以更好地代表您的数据:

record Datav2(Double amount, Integer quantity) {}
Run Code Online (Sandbox Code Playgroud)

将 Datav2 存储在地图中并添加元素。

var map = new HashMap<>(Map.of("A", new Datav2( 2.0, 3)));
        
// add element to map equivalent to Data("A", 3.0, 3)
map.compute("A", (k, v) -> {
    if (v == null) {
        v = new Datav2(0.0, 0); 
    }
    return new Datav2(v.amount = 3.0, v.quantity + 3);
});
Run Code Online (Sandbox Code Playgroud)

如果出于某种原因您需要从列表开始,您可以使用StreamAPI 将列表转换为地图。具体到Map

var list = List.of(new Data("A", 2.0, 3),
       new Data("A", 3.0, 3),
       new Data("C", 2.0, 1),
       new Data("B", 10.0, 3),
       new Data("B", 2.0, 5)
);

var collected = list
         .stream()
         .collect(Collectors.toMap(
                       // what will the key be
                       Data::type,
                       // what will the value be
                       data -> new Datav2(data.amount, data.quantity),
                       // how do we combine two values if they have the same key
                       (d1, d2) -> new Datav2(d1.amount + d2.amount, d1.quantity + d2.quantity)
         ));
System.out.println(collected);
Run Code Online (Sandbox Code Playgroud)

{A=Datav2[金额=5.0,数量=6],B=Datav2[金额=12.0,数量=8],C=Datav2[金额=2.0,数量=1]}