You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HashMap的putAll方法无法传入ArrayList的Android开发问题求助

问题:使用HashMap和ArrayList存储多组数据到SharedPreferences报错

尝试用HashMap和ArrayList将多组数据存储到SharedPreferences时,Android Studio返回以下编译错误:

putAll(java.util.Map<? extends java.lang.String,?>) in java.util.HashMap 
cannot be applied to (java.util.ArrayList<java.util.HashMap<java.lang.String,java.lang.Object>>)

刚接触HashMap,不清楚问题根源,尝试强制转换:

map.putAll((Map<? extends String, ?>) listmap);

但应用运行时直接崩溃。需求是存储用户输入的多组问答数据,完整代码如下:

package com.prgr.quizards.canary;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.widget.AppCompatButton;

import com.google.android.material.textfield.TextInputEditText;
import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Objects;


public class question extends Activity {

    private AppCompatButton btn;
    private SharedPreferences jshared2;
    private int val;
    private SharedPreferences jshared;
    private ArrayList<HashMap<String, Object>> listmap = new ArrayList<>();
    private HashMap<String, Object> map = new HashMap<>();
    @Override
    protected void onCreate(Bundle _savedInstanceState) {
        super.onCreate(_savedInstanceState);
        setContentView(R.layout.activity_question);
        initializedata();
        AppCompatButton btn2 = findViewById(R.id.button3);
        btn = findViewById(R.id.button);
        btn2.setOnClickListener(v -> gotoback());
        btn.setOnClickListener(view -> logicg());
        val = 0;

    }
    public void gotoback(){
        Intent intent = new Intent(question.this, activity_home_screen.class);
        startActivity(intent);
    }

    private void initializedata(){
        jshared = getSharedPreferences("j", Activity.MODE_PRIVATE);
        jshared2 = getSharedPreferences("j2", Activity.MODE_PRIVATE);

    }
    @SuppressLint("ApplySharedPref")
    private void logicg() {
        btn = findViewById(R.id.button);
        EditText inop = findViewById(R.id.inop);
        TextInputEditText ans = findViewById(R.id.ans);
        TextView text = findViewById(R.id.text3);

        String mount = jshared.getString("amount", "");
        int amounts = Integer.parseInt(mount);

        boolean b = val == amounts;
        Toast.makeText(getApplicationContext(), "Start", Toast.LENGTH_SHORT).show();
        if(b){
            jshared2.edit().putString("data", new Gson().toJson(listmap)).commit();
            Intent intent = new Intent(question.this, answerscrn.class);
            startActivity(intent);
            Toast.makeText(getApplicationContext(), "if", Toast.LENGTH_SHORT).show();
        }else{
            map.put("answer", Objects.requireNonNull(ans.getText()).toString());
            map.put("question", inop.getText().toString());
            map.putAll(listmap);
            map.clear();
            ans.setText(null);
            inop.setText(null);
            val++;
            String f = Integer.toString(val);
            String amt = f + " / " + mount;
            text.setText(amt);
        }

    }

}

问题分析与修复

1. 编译错误根源

map.putAll(listmap)这行代码完全错误:HashMap的putAll()方法要求传入Map类型的参数,但你传入的是ArrayList<HashMap>,两者类型完全不兼容,这就是编译报错的原因。强制转换只是骗过了编译器,运行时因为类型不匹配直接抛出异常崩溃。

2. 逻辑错误

你的需求是把每一组问答数据(一个HashMap)存入ArrayList,但原代码的逻辑是:填充map后错误调用putAll,然后立刻clear,根本没把数据添加到listmap里,等于白存。

3. 修正后的代码

重点修改logicg()方法的else块:

@SuppressLint("ApplySharedPref")
private void logicg() {
    EditText inop = findViewById(R.id.inop);
    TextInputEditText ans = findViewById(R.id.ans);
    TextView text = findViewById(R.id.text3);

    String mount = jshared.getString("amount", "");
    int amounts = 0;
    // 处理数字转换异常,避免崩溃
    if (!mount.isEmpty()) {
        try {
            amounts = Integer.parseInt(mount);
        } catch (NumberFormatException e) {
            e.printStackTrace();
            Toast.makeText(this, "无效的数量设置", Toast.LENGTH_SHORT).show();
            return;
        }
    }

    boolean b = val == amounts;
    Toast.makeText(getApplicationContext(), "Start", Toast.LENGTH_SHORT).show();
    if(b){
        // 改用apply()异步提交,比commit()更安全
        jshared2.edit().putString("data", new Gson().toJson(listmap)).apply();
        Intent intent = new Intent(question.this, answerscrn.class);
        startActivity(intent);
        Toast.makeText(getApplicationContext(), "数据已保存", Toast.LENGTH_SHORT).show();
    }else{
        // 每次创建新的HashMap,避免复用同一个对象导致数据覆盖
        HashMap<String, Object> singleQuestion = new HashMap<>();
        singleQuestion.put("answer", Objects.requireNonNull(ans.getText()).toString());
        singleQuestion.put("question", inop.getText().toString());
        // 将单组数据添加到ArrayList中
        listmap.add(singleQuestion);
        
        // 清空输入框
        ans.setText(null);
        inop.setText(null);
        val++;
        String amt = val + " / " + mount;
        text.setText(amt);
    }
}

4. 额外优化建议

  • 减少findViewById调用:把inop、ans、text等View变量提升为成员变量,在onCreate()里初始化一次,不要每次点击按钮都重新查找。
  • 替换commit()为apply():commit()是同步写入磁盘,可能阻塞主线程;apply()是异步提交,更适合UI线程操作。
  • 添加异常处理:处理Integer.parseInt()的转换异常,避免因非法输入导致崩溃。

内容的提问来源于stack exchange,提问作者Harleythetech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 15:05:13