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

手动实现Realm数据库自增ID添加数据时触发NumberFormatException问题求助

解决Realm自增ID实现中的NumberFormatException错误

嘿,我一眼就看出问题出在哪了——你遇到的java.lang.NumberFormatException,是因为你错误地把Realm查询返回的Results<UserInfo>对象直接转成字符串去解析成整数,而那个字符串其实是Realm对象的调试描述文本(就是你看到的[UserInfo = [{Id:null},{username:null},{password:null},{type:null}]]),这根本不是数字,肯定转失败呀!

先分析你代码里的核心问题:

  • 你先创建了UserInfo对象,但此时它的Id是null,用endsWith("Id", userInfo.Id)查询完全没有意义,而且Realm的findAll()永远不会返回null,哪怕没数据也会返回空的Results对象。
  • 试图把Results对象直接转成字符串来获取最大ID,这完全是错误的实现方式。

正确的自增ID实现方案

我推荐把Id字段改成Integer类型(更适合自增逻辑,还能避免字符串转数字的各种坑),同时加上@PrimaryKey注解确保ID唯一,下面是完整的修改方案:

1. 修改UserInfo实体类

public class UserInfo extends RealmObject {
    @PrimaryKey // 标记为主键,保证ID唯一
    private Integer id; // 改成Integer类型,更适合自增场景
    private String username;
    private String password;
    private String type;

    // Getter & Setter 方法
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

2. 修改添加按钮的点击事件代码

add.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        realm.beginTransaction();
        
        // 查询当前表中最大的ID值
        Number maxId = realm.where(UserInfo.class).max("id");
        // 计算新ID:如果表为空就从0开始,否则在最大ID基础上加1
        int newId = (maxId == null) ? 0 : maxId.intValue() + 1;

        // 直接用带主键的方式创建对象(Realm支持这种写法)
        UserInfo userInfo = realm.createObject(UserInfo.class, newId);
        
        // 设置其他字段值
        userInfo.setUsername(username.getText().toString());
        userInfo.setPassword(password.getText().toString());
        userInfo.setType(dropdown.getSelectedItem().toString());
        
        realm.commitTransaction();
        
        Toast.makeText(Add.this,"Username and Password Saved",Toast.LENGTH_LONG).show();
        Intent toMain = new Intent(Add.this, List.class);
        startActivity(toMain);
    }
});

如果你坚持要用String类型的ID(不推荐)

如果因为某些原因必须保留String类型的ID,那可以这样修改点击事件,避免异常:

add.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        realm.beginTransaction();
        
        // 按ID降序排序,取最后一条数据(也就是ID最大的那条)
        UserInfo lastUser = realm.where(UserInfo.class).sort("Id", Sort.DESCENDING).findFirst();
        int newIdInt;
        if (lastUser == null) {
            newIdInt = 0;
        } else {
            try {
                // 把String类型的ID转成整数再加1
                newIdInt = Integer.parseInt(lastUser.getId()) + 1;
            } catch (NumberFormatException e) {
                // 处理ID不是有效数字的异常,这里可以给个默认值或者提示用户
                newIdInt = 0;
                e.printStackTrace();
            }
        }
        String newId = String.valueOf(newIdInt);

        UserInfo userInfo = realm.createObject(UserInfo.class);
        userInfo.setId(newId);
        userInfo.setUsername(username.getText().toString());
        userInfo.setPassword(password.getText().toString());
        userInfo.setType(dropdown.getSelectedItem().toString());
        
        realm.commitTransaction();
        
        Toast.makeText(Add.this,"Username and Password Saved",Toast.LENGTH_LONG).show();
        Intent toMain = new Intent(Add.this, List.class);
        startActivity(toMain);
    }
});

最后提醒

使用数字类型的主键是更合理的选择:既避免了字符串转数字的异常风险,也能让Realm的查询和主键操作更高效,还能保证ID的唯一性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:26:59