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

Transformations.distinctUntilChanged()配合重写equals()不生效如何解决

问题根因

  • 你在MainActivity中全局复用了同一个MyInteger实例,每次点击仅修改该实例的内部数值后直接传给LiveData。distinctUntilChanged比较新旧值时会首先触发equals方法的if (this == o) return true判断,直接判定两个值完全相同,因此从第二次点击开始就不会触发回调。
  • 现有equals方法的边界判断逻辑存在缺陷,无法正确实现“数值超过5后判定为相同”的需求。

修复方案

1. 修改MainActivity逻辑,每次传入新的MyInteger实例

不要复用同一个MyInteger对象,每次点击都创建新实例传递给LiveData,避免引用相等直接判定为相同:

public class MainActivity extends AppCompatActivity {

    private MainActivityViewModel mMainActivityViewModel;
    Button button;
    // 改用基础类型存储当前计数,避免复用自定义对象
    private int currentCount = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = findViewById(R.id.my_button);
        mMainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                currentCount++;
                // 每次创建新的MyInteger实例传入
                mMainActivityViewModel.getLiveData().setValue(new MyInteger(currentCount));
            }
        });

        Transformations.distinctUntilChanged(mMainActivityViewModel.getLiveData()).observe(this, new Observer<MyInteger>() {
            @Override
            public void onChanged(MyInteger myInteger) {
                Log.wtf("Transformations onChanged:", String.valueOf(myInteger.integer));
                Toast.makeText(MainActivity.this, "Transformations onChanged:"+String.valueOf(myInteger.integer), Toast.LENGTH_SHORT).show();
            }
        });
    }
}

2. 重写MyInteger的equals方法,匹配需求逻辑

调整equals实现,满足:只要任意一个实例数值超过5,就判定为相同;否则仅当数值相等时判定为相同:

public class MyInteger {
    
    public int integer;
    
    public MyInteger(Integer integer) {
        this.integer = integer;
    }

    public void incrementByOne() {
        integer++;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        MyInteger myInteger = (MyInteger) o;
        // 只要任意一个值超过5,就判定为相同,不再触发回调
        if (this.integer > 5 || myInteger.integer > 5) {
            return true;
        }
        // 5及以下仅当数值相等时判定为相同
        return this.integer == myInteger.integer;
    }

    @Override
    public int hashCode() {
        return Objects.hash(integer);
    }
}

效果验证

修改后运行效果完全匹配预期:

  • 点击1-5次时,每次数值都≤5且前后值不同,equals返回false,触发Toast弹出
  • 第6次及以后点击时,数值超过5,equals返回true,不再触发Toast

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 03:15:02