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

TinyDB存储自定义Restaurant对象报错及缓存方案咨询

解决TinyDB存储自定义对象的泛型兼容问题

首先,你遇到的错误核心是Java泛型的类型不兼容:ArrayList<Restaurant>并不是ArrayList<Object>的子类(Java泛型是不变的),所以直接传入putListObject方法会触发编译错误。下面给你两种直接可行的解决办法:

方法1:类型转换绕过编译检查

既然TinyDB底层是通过Gson序列化对象,本质上不关心泛型的具体类型,你可以通过通配符转换来解决:

ArrayList<Restaurant> restaurants = new ArrayList<>();
// 添加@SuppressWarnings消除unchecked警告
@SuppressWarnings("unchecked")
ArrayList<Object> objList = (ArrayList<Object>) (ArrayList<?>) restaurants;
tinydb.putListObject("restaurantsObject", objList);

读取的时候你的原有代码完全可以正常工作,因为getListObject会通过传入的Restaurant.class来反序列化回正确的类型:

ArrayList<Restaurant> restaurants = tinydb.getListObject("restaurantsObject", Restaurant.class);

方法2:给TinyDB添加泛型重载方法

更优雅的方式是修改TinyDB类,添加一个支持泛型的putListObject重载方法,这样后续使用就不用每次转换了:

import com.google.gson.Gson;
import java.util.ArrayList;
import java.lang.reflect.Type;
import com.google.gson.reflect.TypeToken;

public class TinyDB {
    // 保留原有方法
    public void putListObject(String key, ArrayList<Object> list) {
        Gson gson = new Gson();
        putString(key, gson.toJson(list));
    }

    // 添加泛型重载方法
    public <T> void putListObject(String key, ArrayList<T> list) {
        Gson gson = new Gson();
        putString(key, gson.toJson(list));
    }

    // 确保你的getListObject方法支持泛型(如果原有方法不支持可以替换)
    public <T> ArrayList<T> getListObject(String key, Class<T> clazz) {
        String json = getString(key);
        if (json == null) {
            return new ArrayList<>();
        }
        Gson gson = new Gson();
        Type type = new TypeToken<ArrayList<T>>() {}.getType();
        return gson.fromJson(json, type);
    }
}

之后你就可以直接调用tinydb.putListObject("restaurantsObject", restaurants),完全不需要类型转换。


适配该结构的简易缓存方案

如果需要兼顾内存读写速度和持久化,推荐内存缓存+TinyDB持久化的双层缓存方案,实现起来很简单:

import android.content.Context;
import androidx.collection.LruCache;
import java.util.ArrayList;

public class RestaurantCache {
    private static RestaurantCache instance;
    private final TinyDB tinyDB;
    private final LruCache<String, ArrayList<Restaurant>> memoryCache;

    private RestaurantCache(Context context) {
        tinyDB = new TinyDB(context);
        // 设置内存缓存大小,比如最多存5个列表(可根据需求调整)
        memoryCache = new LruCache<>(5);
    }

    public static synchronized RestaurantCache getInstance(Context context) {
        if (instance == null) {
            instance = new RestaurantCache(context.getApplicationContext());
        }
        return instance;
    }

    // 保存餐厅列表,同时更新内存和持久化存储
    public void saveRestaurants(String key, ArrayList<Restaurant> restaurants) {
        memoryCache.put(key, restaurants);
        tinyDB.putListObject(key, restaurants);
    }

    // 获取餐厅列表,优先从内存读取,没有再从TinyDB加载
    public ArrayList<Restaurant> getRestaurants(String key) {
        ArrayList<Restaurant> restaurants = memoryCache.get(key);
        if (restaurants == null) {
            restaurants = tinyDB.getListObject(key, Restaurant.class);
            if (restaurants != null) {
                memoryCache.put(key, restaurants);
            }
        }
        return restaurants == null ? new ArrayList<>() : restaurants;
    }

    // 清空指定缓存
    public void clearCache(String key) {
        memoryCache.remove(key);
        tinyDB.remove(key);
    }

    // 清空所有缓存
    public void clearAllCache() {
        memoryCache.evictAll();
        tinyDB.clear();
    }
}

使用的时候直接调用单例方法:

// 保存
ArrayList<Restaurant> restaurants = new ArrayList<>();
// 添加数据...
RestaurantCache.getInstance(context).saveRestaurants("restaurantsObject", restaurants);

// 获取
ArrayList<Restaurant> cachedRestaurants = RestaurantCache.getInstance(context).getRestaurants("restaurantsObject");

这个方案既利用了LruCache的快速内存读写,又通过TinyDB实现了数据持久化,完美适配你的自定义对象存储需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:25:13