如何在散列映射中对与重复出现的键相关联的值求和

时间:2014-07-08 17:53:36

标签: java excel hashmap sum apache-poi

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

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

应该成为:

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

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

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();
    }
}
}

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

代码输出:

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

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

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

4 个答案:

答案 0 :(得分:3)

覆盖地图中的任何内容。

您需要获取密钥的地图中的当前值(如果存在)并将其添加到您要存储的值。

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

答案 1 :(得分:3)

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

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

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

答案 2 :(得分:2)

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

答案 3 :(得分:1)

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