如何对与哈希图中重复出现的键关联的值求和

Let*_*ale 3 java excel sum hashmap apache-poi

我想在哈希图中添加相同键的值。例如:

   ABC --> 123  
   DEF --> 456  
   ABC --> 123  
   XXX --> 111  
   XXX --> 222
Run Code Online (Sandbox Code Playgroud)

应该变成:

   ABC --> 246  
   DEF --> 456  
   XXX --> 333  
Run Code Online (Sandbox Code Playgroud)

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

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();
    }
}
}
Run Code Online (Sandbox Code Playgroud)

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

代码输出如下:

DEF --> 456
ABC --> 123
XXX --> 222
Run Code Online (Sandbox Code Playgroud)

所有这些都是用相同的键覆盖放入哈希图中的最后一个单元格。

有什么方法可以对值求和而不是覆盖它们?

Stu*_*rks 6

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

hm.merge(key, value, (oldVal, newVal) -> oldVal + newVal);
Run Code Online (Sandbox Code Playgroud)

在 Java 8 之前,您必须使用条件,如Cheruvian's answer 中所示。(+1)


Che*_*ian 5

Put 会覆盖地图中的所有内容。

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

if(hm.containsKey(key))
    hm.put(key, value + hm.get(key));
else
    hm.put(key, value);
Run Code Online (Sandbox Code Playgroud)