我有以下Java代码来获取与多个位置的对象相关的多个集合:
Map<String, List<? extends BaseView>> additionalCollections = deployEnvironmentService.getInputPageInfo(getProjectOid());
List<MachineView> machineViews = (List<MachineView>) additionalCollections.get("machineViewCollection");
List<LevelView> levelViews = (List<LevelView>) additionalCollections.get("levelViewCollection");
List<ToolView> toolViews = (List<ToolView>) additionalCollections.get("toolViewCollection");
List<BuildEnvironmentView> buildEnvironmentViews = (List<BuildEnvironmentView>) additionalCollections
.get("buildEnvironmentViewCollection");
集合的名称和数量根据我使用的服务而有所不同,但是集合始终继承自BaseView。可以使用类似于以下方法的方法来检索集合:
public Map<String,List<? extends BaseView>> getInputPageInfo(Integer projectOid) {
Map<String,List<? extends BaseView>> allInfoMap = new HashMap<String,List<? extends BaseView>>();
PersistenceBroker broker = PersistenceBrokerFactory.createPersistenceBroker();
try {
allInfoMap.put("levelViewCollection", getLevelViewCollection(broker, projectOid));
allInfoMap.put("machineViewCollection", getMachineViewCollection(broker));
allInfoMap.put("toolViewCollection", getToolViewCollection(broker, projectOid));
allInfoMap.put("buildEnvironmentViewCollection", getBuildEnvironments(broker, projectOid));
} finally {
broker.close();
}
return allInfoMap;
}
我遇到的问题是,我总是在第一个代码段的Map.get()方法上收到警告,说Type safety: Unchecked cast from List<capture#1-of ? extends BaseView> to Collection<LevelView>
。有没有办法解决这个警告?我尝试定义类型<T extends BaseView>
,但后来找不到在函数调用本身中使用该类型T的方法。
答案 0 :(得分:0)
不,你不能。
您只能安全地强制转换为=IF(E2="",C1,CHAR(COUNTIF($E$2:E2,E2)+64))
,因为您可以确保地图中的每个列表都包含BaseView
可以对其进行扩展。
根据{{3}}的建议,您可以创建一个包含所有必要列表的类。
如果您绝对需要使用BaseView
作为键,则可以通过自己进行类型检查来实例化一个不可修改的映射,而只是取消警告。
答案 1 :(得分:0)
将地图包装在“查找”对象中,然后键入密钥:
public final class PageInfoKey<T extends BaseView> {
public static final PageInfoKey<MachineView> MACHINE_VIEWS
= new PageInfoKey<>("machineViews", MachineView.class);
/*... more static final keys defined here ...*/
/* Adding the 'name' and 'type' fields,
* and equals() and hashCode() as below,
* allow us to have multiple instances of keys
* defined elsewhere if desired, which should still
* work with the lookup.
*
* If all keys are defined statically inside this class
* (i.e. constructor is made private), then these fields
* and methods are unnecessary.
*/
private final String name;
private final Class<T> type;
public PageInfoKey(String name, Class<T> type) {
this.name = name;
this.type = type;
}
@Override
public int hashCode() {
return Objects.hash(name, type);
}
@Override
public boolean equals(Object other) {
if(other==this) return true;
if(other instanceof PageInfoKey) {
PageInfoKey<?> o = (PageInfoKey<?>)other;
return Objects.equals(this.name, o.name) &&
Objects.equals(this.type, o.type);
}
return false;
}
}
public class PageInfoLookup {
private final Map<PageInfoKey<?>, List<? extends BaseView>> data = new HashMap<>();
public <T extends BaseView> void put(PageInfoKey<T> key, List<T> value) {
data.put(key, value);
}
@SuppressWarnings("unchecked")
public <T extends BaseView> List<T> get(PageInfoKey<T> key) {
return (List<T>) data.get(key);
}
}
现在,您可以通过传入静态定义的键来获取视图:
List<MachineView> machineViews = lookup.get(PageInfoKey.MACHINE_VIEWS);
所有内容都是类型安全的,并在编译时进行检查,前提是您只能通过lookup类中的公共方法修改/访问地图。也不需要只在PageInfoKey
类内定义键-只要该类上有明智定义的equals
和hashCode
方法,您就可以在任意位置定义新实例,包括在依赖库中。
正如Aleksander所指出的那样,如果您知道地图中最多只会有一个特定类型的列表,那么您可以只使用Class
本身作为键。 / p>