如何将与hashmap中重复出现的键关联的值相加

时间:2021-07-01 20:23:24

I want to add the values of the same keys in a hashmap. For example:

我想在hashmap中添加相同键的值。例如:

   ABC --> 123  
   DEF --> 456  
   ABC --> 123  
   XXX --> 111  
   XXX --> 222

should become:

   ABC --> 246  
   DEF --> 456  
   XXX --> 333  

Here's the code I have so far:

这是我到目前为止的代码:

public class Reading {


@SuppressWarnings("unchecked")
public static void main(String[] args) throws IOException {
    //Create hashmap to store the the string and int in the excel sheet
    HashMap<String, Integer> hm = new HashMap<String, Integer>();

    String key = null;
    int value = Integer.MIN_VALUE;
    // String chkeq; // this

    @SuppressWarnings("rawtypes")
    ArrayList list = new ArrayList();

    // File path or EXCEL file
    FileInputStream fos = new FileInputStream(
            "/Users/SG/Desktop/tester.xls");

    // Sheet is the individual sheet that the data is coming from, in this
    // case Sheet1

    try {

        // Put the XLS file into
        HSSFWorkbook workbook = new HSSFWorkbook(fos);

        // Get first sheet from the project
        HSSFSheet sheet = workbook.getSheetAt(0);

        // Go through each row
        Iterator<Row> rowIterator = sheet.iterator();
        while (rowIterator.hasNext()) {


            Row row = rowIterator.next();

            // Go through each column in the rows
            Iterator<Cell> cellIterator = row.cellIterator();
            while (cellIterator.hasNext()) {

                Cell cell = cellIterator.next();

                switch (cell.getCellType()) {
                    case Cell.CELL_TYPE_BOOLEAN:
                        //System.out.print(cell.getBooleanCellValue() + "\t\t");

                        list.add(cell.getBooleanCellValue());
                        break;
                    case Cell.CELL_TYPE_NUMERIC:
                        //System.out.print(cell.getNumericCellValue() + "\t\t");

                        value = (int) cell.getNumericCellValue();
                        list.add(cell.getNumericCellValue());
                        break;
                    case Cell.CELL_TYPE_STRING:
                        //System.out.print(cell.getStringCellValue() + "\t\t");
                        key = cell.getStringCellValue();
                        //chkeq = cell.getStringCellValue();

                       /* for (int i = 0; cellIterator.hasNext(); i++) {
                            if (chkeq == cellIterator.next().getStringCellValue()) {
                                System.out.println("same" + cell.getStringCellValue());

                            }

                        }*/

                        list.add(cell.getStringCellValue());
                        break;
                }

                if (key != null && value != Integer.MIN_VALUE) {
                    hm.put(key, value);
                    key = null;
                    value = Integer.MIN_VALUE;
                }

            }
            //System.out.println("");

        }
        for (String keys : hm.keySet())
            System.out.println(keys + ":" + hm.get(keys));
        fos.close();
        // System.out.println(list);

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
}

Note: I have used Apache POI to extract the data from an Excel sheet.

注意:我使用Apache POI从Excel工作表中提取数据。

The code outputs this:

代码输出:

DEF --> 456
ABC --> 123
XXX --> 222

All this is doing is overwriting the last cell that was put into the hashmap with equal key.

所有这一切都是用相同的密钥覆盖放入hashmap的最后一个单元格。

Is there any way to sum the values instead of writing over them?

有没有办法对值进行求和而不是写出它们?

4 个解决方案

#1


3  

Put overwrites whatever is in the map.

放弃覆盖地图中的任何内容。

You need to get the current value in the map for the key (if it exists) and add it to the value you want to store.

您需要获取键的映射中的当前值(如果存在)并将其添加到要存储的值。

if(hm.containsKey(key))
    hm.put(key, value + hm.get(key));
else
    hm.put(key, value);

#2


3  

As you observed, hm.put overwrites the previous value, if any, associated with the key. In Java 8 there is a new method that merges the incoming value with the existing one. You can use a lambda to specify how the merging is done. In this case the merge operation is addition, so we would do:

如您所见,hm.put将覆盖与该键关联的先前值(如果有)。在Java 8中,有一种新方法将传入值与现有值合并。您可以使用lambda指定合并的完成方式。在这种情况下,合并操作是添加,所以我们会这样做:

hm.merge(key, value, (oldVal, newVal) -> oldVal + newVal);

Prior to Java 8 you have to use a conditional, as in Cheruvian's answer. (+1)

在Java 8之前,你必须使用条件,就像Cheruvian的答案一样。 (1)

#3


2  

Simply if value exists for the key, retrieve value and sum it with new value and put it back to map for the same key

简单地说,如果密钥存在值,则检索值并将其与新值相加,然后将其放回映射以获取相同的密钥

#4


1  

If the data is in Excel then a PivotTable could do the addition.

如果数据在Excel中,那么数据透视表可以进行添加。

#1


3  

Put overwrites whatever is in the map.

放弃覆盖地图中的任何内容。

You need to get the current value in the map for the key (if it exists) and add it to the value you want to store.

您需要获取键的映射中的当前值(如果存在)并将其添加到要存储的值。

if(hm.containsKey(key))
    hm.put(key, value + hm.get(key));
else
    hm.put(key, value);

#2


3  

As you observed, hm.put overwrites the previous value, if any, associated with the key. In Java 8 there is a new method that merges the incoming value with the existing one. You can use a lambda to specify how the merging is done. In this case the merge operation is addition, so we would do:

如您所见,hm.put将覆盖与该键关联的先前值(如果有)。在Java 8中,有一种新方法将传入值与现有值合并。您可以使用lambda指定合并的完成方式。在这种情况下,合并操作是添加,所以我们会这样做:

hm.merge(key, value, (oldVal, newVal) -> oldVal + newVal);

Prior to Java 8 you have to use a conditional, as in Cheruvian's answer. (+1)

在Java 8之前,你必须使用条件,就像Cheruvian的答案一样。 (1)

#3


2  

Simply if value exists for the key, retrieve value and sum it with new value and put it back to map for the same key

简单地说,如果密钥存在值,则检索值并将其与新值相加,然后将其放回映射以获取相同的密钥

#4


1  

If the data is in Excel then a PivotTable could do the addition.

如果数据在Excel中,那么数据透视表可以进行添加。