Java 如何使用T和List来泛化类<;T>;
我正在尝试概括我的班级结构。Java 如何使用T和List来泛化类<;T>;,java,android,generics,caching,robospice,Java,Android,Generics,Caching,Robospice,我正在尝试概括我的班级结构。 我将更具体地展示我的真实结构 我正在编写支持脱机模式的应用程序,所以我决定使用Robospice和GreenDao ORM实现我的ETag缓存机制 我只需要缓存获取请求 首先,我的请求应该扩展基本请求(不是我的),在我的情况下request 问题是,默认情况下,返回类型不是T类型列表,我需要创建扩展T对象数组并将其用作返回类型的子类 像这样的 public class City { .... .... .... public static class Lis
我将更具体地展示我的真实结构 我正在编写支持脱机模式的应用程序,所以我决定使用Robospice和GreenDao ORM实现我的ETag缓存机制 我只需要缓存获取请求 首先,我的请求应该扩展基本请求(不是我的),在我的情况下
request
问题是,默认情况下,返回类型不是T类型列表,我需要创建扩展T对象数组并将其用作返回类型的子类
像这样的
public class City {
....
....
....
public static class List extends ArrayList<City> {
.....
.....
}
}
public AbastractDao<T,Long> getRequestDao() {
}
在每个请求中
请分享你的想法
谢谢。我最终得到了以下解决方案。它并没有我想要的那么好,但它工作起来比复制代码更好 我的基本请求类
public abstract class BaseGetRequest<L extends List<T>, T, V> extends RetrofitSpiceRequest<L, V> implements FilterableRequest {
// Context
protected Context mContext;
// Filter used in request and in queries
protected Map<Property, String> mFilterMap;
// Session provided Singletone
protected DaoSessionProvider mSessionProvider;
public BaseGetRequest(Class<L> clazz, Class<V> retrofitedInterfaceClass, Context context, Map<Property, String> filterMap) {
super(clazz, retrofitedInterfaceClass);
mContext = context;
mFilterMap = filterMap;
mSessionProvider = ((DaoSessionProvider) mContext.getApplicationContext());
// TODO determine required retry count
setRetryPolicy(new RetryPolicy() {
@Override
public int getRetryCount() {
return 0;
}
@Override
public void retry(SpiceException e) {
}
@Override
public long getDelayBeforeRetry() {
return 0;
}
});
}
protected WhereCondition[] getWhereConditions() {
return QueryUtils.convertPropertyMapToConditionalArray(mFilterMap);
}
public BaseGetRequestV2(Class<L> clazz, Class<V> retrofitedInterfaceClass, Context context) {
this(clazz, retrofitedInterfaceClass, context, null);
}
public abstract AbstractDao<T, Long> getDao();
public abstract L createDataList(List<T> list);
public L getCachedData() {
if (mFilterMap != null && mFilterMap.size() > 0) {
WhereCondition[] whereConditions = getWhereConditions();
return createDataList(getDao().queryBuilder().where(whereConditions[0], Arrays.copyOfRange(whereConditions, 1, whereConditions.length)).list());
} else {
return createDataList(getDao().loadAll());
}
}
public abstract L getData();
@Override
public Map<Property, String> getFilterMap() {
return mFilterMap;
}
public Map<String, String> getStringMap() {
return QueryUtils.convertPropertyMapToString(mFilterMap);
}
@Override
public L loadDataFromNetwork() throws Exception {
L receivedData = null;
try {
receivedData = getData();
WhereCondition[] conditions = getWhereConditions();
getDao().queryBuilder().where(conditions[0],Arrays.copyOfRange(conditions, 1, conditions.length)).buildDelete().executeDeleteWithoutDetachingEntities();
getDao().insertOrReplaceInTx(receivedData);
} catch (Exception ex) {
receivedData = getCachedData();
}
return receivedData;
}
}
公共抽象类BaseGetRequest扩展了该请求,该请求实现了FilterableRequest{
//上下文
保护上下文mContext;
//在请求和查询中使用的筛选器
受保护地图;
//会话提供单音
受保护的DaoSessionProvider mSessionProvider;
public BaseGetRequest(类clazz、类RegeneratedInterfaceClass、上下文上下文、映射过滤器映射){
超级(clazz,改装接口级);
mContext=上下文;
mFilterMap=过滤器映射;
mSessionProvider=((DaoSessionProvider)mContext.getApplicationContext());
//TODO确定所需的重试次数
setRetryPolicy(新RetryPolicy(){
@凌驾
public int getRetryCount(){
返回0;
}
@凌驾
公共无效重试(SPICE例外){
}
@凌驾
public long getDelayBeforeRetry()函数{
返回0;
}
});
}
受保护的Where条件[]GetWhere条件(){
返回QueryUtils.convertPropertyMattoConditionAlarray(mFilterMap);
}
public BaseGetRequestV2(类clazz、类RegeneratedInterfaceClass、上下文){
这(clazz,改型接口类,上下文,null);
}
公共抽象抽象dao getDao();
公共摘要L createDataList(列表列表);
公共L getCachedData(){
if(mFilterMap!=null&&mFilterMap.size()>0){
WhereCondition[]whereConditions=getWhereConditions();
返回createDataList(getDao().queryBuilder().where(whereConditions[0],Arrays.copyOfRange(whereConditions,1,whereConditions.length)).list());
}否则{
返回createDataList(getDao().loadAll());
}
}
公共摘要L getData();
@凌驾
公共映射getFilterMap(){
返回mFilterMap;
}
公共映射getStringMap(){
返回QueryUtils.convertPropertyMapToString(mFilterMap);
}
@凌驾
public L loadDataFromNetwork()引发异常{
L receivedData=null;
试一试{
receivedData=getData();
WhereCondition[]条件=getWhereConditions();
getDao().queryBuilder().where(条件[0],数组.copyOfRange(条件,1,条件.length)).buildDelete().ExecutedEleteWithoutDetachIngeneties();
getDao().insertoreplaceintx(receivedData);
}捕获(例外情况除外){
receivedData=getCachedData();
}
返回接收数据;
}
}
我可以这样扩展这个类:
public class NewsRequest extends BaseGetRequest<NewsArticle.List, NewsArticle, API> {
public static final String TARGET_URL = "/news";
NewsArticleDao mNewsArticleDao;
public NewsRequest(Context context) {
this(context, null);
}
public NewsRequest(Context context, Map<Property, String> filterMap) {
super(NewsArticle.List.class, API.class, context, filterMap);
mNewsArticleDao = mSessionProvider.getDaoSession().getNewsArticleDao();
}
@Override
public AbstractDao<NewsArticle, Long> getDao() {
return mNewsArticleDao;
}
@Override
public NewsArticle.List createDataList(List<NewsArticle> list) {
return new NewsArticle.List(list);
}
@Override
public NewsArticle.List getData() {
return getService().getNews(getStringMap());
}
}
公共类NewsRequest扩展了BaseGetRequest{
公共静态最终字符串TARGET_URL=“/news”;
NewsArticleDao-mNewsArticleDao;
公共新闻请求(上下文){
这个(上下文,空);
}
公共新闻请求(上下文、映射筛选器映射){
super(newarticle.List.class、API.class、context、filterMap);
mNewsArticleDao=mSessionProvider.getDaoSession().getNewsArticleDao();
}
@凌驾
公共抽象dao getDao(){
返回mnewsactiondao;
}
@凌驾
公共新闻文章.列表createDataList(列表列表){
返回新的新闻文章.List(List);
}
@凌驾
PublicNewsArticle.List getData(){
返回getService().getNews(getStringMap());
}
}
我是否理解这一点,您希望您的服务自动注入并调用适当的Dao?是的,但问题是Dao是extend AbstractDao,主要用作AbstractDao,其中T是映射到我的案例city中的表的类型,但我需要获取城市列表,就请求返回类T的对象而言,我必须创建自定义类MyCityList扩展ArrayList,这就是问题所在。
@Override
public void insertReceivedData(City.List received) {
mCityDao.insertOrReplaceInTx(received);
}
@Override
public City.List getCachedData() {
if (mFilterMap != null && mFilterMap.size() > 0) {
return (City.List) mCityDao.loadAll();
} else {
WhereCondition[] whereConditions = QueryUtils.convertPropertyMapToConditionalArray(mFilterMap);
return (City.List) mCityDao.queryBuilder().where(whereConditions[0], Arrays.copyOfRange(whereConditions, 1, whereConditions.length)).list();
}
}
public abstract class BaseGetRequest<L extends List<T>, T, V> extends RetrofitSpiceRequest<L, V> implements FilterableRequest {
// Context
protected Context mContext;
// Filter used in request and in queries
protected Map<Property, String> mFilterMap;
// Session provided Singletone
protected DaoSessionProvider mSessionProvider;
public BaseGetRequest(Class<L> clazz, Class<V> retrofitedInterfaceClass, Context context, Map<Property, String> filterMap) {
super(clazz, retrofitedInterfaceClass);
mContext = context;
mFilterMap = filterMap;
mSessionProvider = ((DaoSessionProvider) mContext.getApplicationContext());
// TODO determine required retry count
setRetryPolicy(new RetryPolicy() {
@Override
public int getRetryCount() {
return 0;
}
@Override
public void retry(SpiceException e) {
}
@Override
public long getDelayBeforeRetry() {
return 0;
}
});
}
protected WhereCondition[] getWhereConditions() {
return QueryUtils.convertPropertyMapToConditionalArray(mFilterMap);
}
public BaseGetRequestV2(Class<L> clazz, Class<V> retrofitedInterfaceClass, Context context) {
this(clazz, retrofitedInterfaceClass, context, null);
}
public abstract AbstractDao<T, Long> getDao();
public abstract L createDataList(List<T> list);
public L getCachedData() {
if (mFilterMap != null && mFilterMap.size() > 0) {
WhereCondition[] whereConditions = getWhereConditions();
return createDataList(getDao().queryBuilder().where(whereConditions[0], Arrays.copyOfRange(whereConditions, 1, whereConditions.length)).list());
} else {
return createDataList(getDao().loadAll());
}
}
public abstract L getData();
@Override
public Map<Property, String> getFilterMap() {
return mFilterMap;
}
public Map<String, String> getStringMap() {
return QueryUtils.convertPropertyMapToString(mFilterMap);
}
@Override
public L loadDataFromNetwork() throws Exception {
L receivedData = null;
try {
receivedData = getData();
WhereCondition[] conditions = getWhereConditions();
getDao().queryBuilder().where(conditions[0],Arrays.copyOfRange(conditions, 1, conditions.length)).buildDelete().executeDeleteWithoutDetachingEntities();
getDao().insertOrReplaceInTx(receivedData);
} catch (Exception ex) {
receivedData = getCachedData();
}
return receivedData;
}
}
public class NewsRequest extends BaseGetRequest<NewsArticle.List, NewsArticle, API> {
public static final String TARGET_URL = "/news";
NewsArticleDao mNewsArticleDao;
public NewsRequest(Context context) {
this(context, null);
}
public NewsRequest(Context context, Map<Property, String> filterMap) {
super(NewsArticle.List.class, API.class, context, filterMap);
mNewsArticleDao = mSessionProvider.getDaoSession().getNewsArticleDao();
}
@Override
public AbstractDao<NewsArticle, Long> getDao() {
return mNewsArticleDao;
}
@Override
public NewsArticle.List createDataList(List<NewsArticle> list) {
return new NewsArticle.List(list);
}
@Override
public NewsArticle.List getData() {
return getService().getNews(getStringMap());
}
}