Integer类型遇到的坑(关于Integer的不可变性)

文章讲述了作者在Java项目中遇到的计数问题,由于在方法间传递Integer类型的计数变量,导致值无法更新。解决方法是将Integer改为基本数据类型int,或使用可变对象AtomicInteger。
摘要由CSDN通过智能技术生成

今天遇到一个非常低级的BUG简直了,是这样的我原本想做一个计数的操作,我先定义好类型

 public AjaxResult importUserTable(MultipartFile zipFile) {
        //检查文件是否为空
        Optional.ofNullable(zipFile).orElseThrow(() -> new IllegalArgumentException("上传的文件为空"));

        // 检查文件扩展名是否为.zip
        if (!zipFile.getOriginalFilename().toLowerCase().endsWith(ZIP_FILE_EXTENSION)) {
            throw new IllegalArgumentException("上传的文件必须是.zip格式");
        }
        //总计导入的文件个数
        Integer importCount = 0;
        //新增个数
        Integer addCount = 0;
        //更新个数
        Integer updateCount = 0;
        //不符合要求的文档以及不符合的原因
        StringBuilder errorMessage = new StringBuilder();

        // 解压ZIP文件
        String relativePath = "profile"; // 相对于项目根目录的路径
        Path uploadDirPath = Paths.get(relativePath);
        unzip(zipFile, uploadDirPath.toString(), importCount, addCount, updateCount, errorMessage);
        log.info("解压成功到:" + uploadDirPath);
        // 上传解压后的文件
        File destDir = new File(uploadDirPath.toString());
        uploadUnzippedFiles(destDir);

        Map<String, Object> map = new HashMap<>();
        map.put("importCount",importCount);
        map.put("addCount",addCount);
        map.put("updateCount",updateCount);
        map.put("errorMessage",errorMessage.toString());
        map.put("message","导入成功");

        if (ObjectUtil.isNotEmpty(errorMessage.toString())){
            return AjaxResult.error(errorMessage.toString());
        }else {
            return AjaxResult.success(map);
        }
    }

然后在调用解压方法进行解压 计数也传过去

// 定义一个方法来解压ZIP文件
    public void unzip(MultipartFile zipFile, String destDirPath, Integer importCount, Integer addCount, Integer updateCount, StringBuilder errorMessage) {
        try {
            // 创建目标目录
            // 使用当前日期创建目录结构
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
            String currentDateStr = dateFormat.format(new Date());
            String uploadPath = Paths.get(destDirPath, currentDateStr).toString();
            File destDir = new File(uploadPath);
            if (!destDir.exists()) {
                destDir.mkdir();
            }
            // 使用 Apache Commons Compress 来解压 ZIP 文件
            try (InputStream is = zipFile.getInputStream();
                 ZipArchiveInputStream zis = new ZipArchiveInputStream(is)) {
                ZipArchiveEntry entry = zis.getNextZipEntry();
                while (entry != null) {
                    // Assuming file name format is "行业-类别-方案名称-图表名称.docx"
                    String fileName = entry.getName();
                    // 使用正则表达式检查文件名是否以.doc结尾
                    Pattern pattern = Pattern.compile("\\.docx$");
                    Matcher matcher = pattern.matcher(fileName);

                    if (!matcher.find()) {
                        // 如果文件不是.doc文件,抛出异常
                        errorMessage.append(fileName).append("文件格式有误,请导入.docx文件\n");

                    }
                    File filePath = new File(destDir, entry.getName());
                    if (entry.isDirectory()) {
                        filePath.mkdirs();
                    } else {
                        // 如果文件已存在,则删除
                        if (filePath.exists()) {
                            filePath.delete();
                        }
                        File parent = filePath.getParentFile();
                        if (!parent.exists()) {
                            parent.mkdirs();
                        }
                        try (OutputStream outputStream = new FileOutputStream(filePath)) {
                            IOUtils.copy(zis, outputStream);
                        }
                    }

                    String[] parts = fileName.split("-");
                    if (parts.length == 4) {
                        String industry = parts[0];
                        String tableType = parts[1];
                        String bidName = parts[2];
                        String chartName = parts[3].substring(0, parts[3].lastIndexOf(".docx"));
                        //保存到数据库中
                        saveToDatabase(industry, tableType, bidName, chartName, filePath.getPath(), importCount, addCount, updateCount);
                    }else {
                        errorMessage.append(fileName).append("文件名称格式有误导入失败\n");
                    }
                    entry = zis.getNextZipEntry();
                }
            }
        } catch (IOException e) {
            log.error("IO error: " + e.getMessage());
            // 处理其他可能的I/O错误
        }
    }

同样的存到数据库也是传递过去累计,想法总是美好的,现实总是残酷的,捣鼓了半天发现不管怎么样结果都是0,怎么都不加上去.

开始百度大法后才知道:

importCount、addCount 和 updateCount 被声明为 Integer 类型的参数,并在 unzip 方法中传递给 saveToDatabase 方法。尽管您在 saveToDatabase 方法内部尝试修改这些参数的值,但由于 Integer 对象是不可变的,这些修改实际上并没有改变传递给 saveToDatabase 方法的 Integer 对象的值。

解决办法:

使用基本数据类型:将 importCount、addCount 和 updateCount 声明为基本数据类型 int,而不是对象类型 Integer。这样,传递的是值的副本,而不是对象的引用。
使用可变对象:如果需要使用对象类型,您可以使用可变对象,例如 AtomicInteger,它提供了原子操作来更新值。

得,今天又长记性了! 

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值