Java 使用泛型映射.put
我发现以下代码有错误(如下代码片段所述):Java 使用泛型映射.put,java,generics,inheritance,covariance,Java,Generics,Inheritance,Covariance,我发现以下代码有错误(如下代码片段所述): 公共类MyClass{ 私有地图mapToSubclass1; 私有地图mapToSubclass2; 公共空间更新( 最终布尔更新ResubClass1, 最终列表解决此问题的最佳方法是创建两个更新方法。一个用于子类1,另一个用于子类2。原因很简单,最好有两个单独的方法做一件事,而不是一个带布尔参数的方法做两件事 这段代码看起来不错,而且更易于测试 public void update1(final List<Subclass1> upd
公共类MyClass{
私有地图mapToSubclass1;
私有地图mapToSubclass2;
公共空间更新(
最终布尔更新ResubClass1,
最终列表解决此问题的最佳方法是创建两个更新方法。一个用于子类1
,另一个用于子类2
。原因很简单,最好有两个单独的方法做一件事,而不是一个带布尔参数的方法做两件事
这段代码看起来不错,而且更易于测试
public void update1(final List<Subclass1> updates) {
updates.stream().forEach((entity) -> {
mapToSubclass1.put(entity.getId(), entity);
});
}
public void update2(final List<Subclass2> updates) {
updates.stream().forEach((entity) -> {
mapToSubclass2.put(entity.getId(), entity);
});
}
public void update1(最终列表更新){
updates.stream().forEach((实体)->{
mapToSubclass1.put(entity.getId(),entity);
});
}
公共无效更新2(最终列表更新){
updates.stream().forEach((实体)->{
mapToSubclass2.put(entity.getId(),entity);
});
}
我想解决这个问题的最好方法是创建两个更新方法。一个用于子类1
和一个用于子类2
。原因很简单,最好有两个单独的方法做一件事,而不是一个带有布尔参数的方法做两件事
这段代码看起来不错,而且更易于测试
public void update1(final List<Subclass1> updates) {
updates.stream().forEach((entity) -> {
mapToSubclass1.put(entity.getId(), entity);
});
}
public void update2(final List<Subclass2> updates) {
updates.stream().forEach((entity) -> {
mapToSubclass2.put(entity.getId(), entity);
});
}
public void update1(最终列表更新){
updates.stream().forEach((实体)->{
mapToSubclass1.put(entity.getId(),entity);
});
}
公共无效更新2(最终列表更新){
updates.stream().forEach((实体)->{
mapToSubclass2.put(entity.getId(),entity);
});
}
普通继承在泛型中不起作用。因此,Map
不从Map
扩展
您可以选择显式地强制转换对象
if (updatesAreSubclass1) {
updates.stream().forEach((entity) -> {
mapToSubclass1.put(entity.getId(), (SubClass1) entity);
});
} else {
updates.stream().forEach((entity) -> {
mapToSubclass2.put(entity.getId(), (SubClass2) entity);
});
}
普通继承在泛型中不起作用。因此,Map
不从Map
扩展
您可以选择显式地强制转换对象
if (updatesAreSubclass1) {
updates.stream().forEach((entity) -> {
mapToSubclass1.put(entity.getId(), (SubClass1) entity);
});
} else {
updates.stream().forEach((entity) -> {
mapToSubclass2.put(entity.getId(), (SubClass2) entity);
});
}
您的方法在继承方面没有多大意义。您有两个独立的子类映射,并且希望在其中任何一个中添加超类实例。我建议您考虑一种更合适的方法来处理此用例
但是,如果您想保持现状,这将实现以下目的:
public void update(
final boolean updatesAreSubclass1,
final List<? extends Superclass> updates) {
updates.stream().forEach((entity) -> {
if(updatesAreSubclass1)
mapToSubclass1.put(entity.getId(), (Subclass1) entity);
else
mapToSubclass2.put(entity.getId(), (Subclass2) entity);
});
}
公共作废更新(
最终布尔更新ResubClass1,
最终列表您的方法在继承方面没有多大意义。您有两个独立的子类映射,并且希望在其中任何一个中添加超类实例。我建议您考虑一种更合适的方法来处理此用例
但是,如果您想保持现状,这将实现以下目的:
public void update(
final boolean updatesAreSubclass1,
final List<? extends Superclass> updates) {
updates.stream().forEach((entity) -> {
if(updatesAreSubclass1)
mapToSubclass1.put(entity.getId(), (Subclass1) entity);
else
mapToSubclass2.put(entity.getId(), (Subclass2) entity);
});
}
公共作废更新(
最终布尔更新ResubClass1,
最后一个列表这里有一个解决方案,可以处理无限多的可能的子类,因为据我所知,您只是在创建一个class加Id->Superclass的映射
private Map<Class,Map<String,Superclass>> map = new HashMap<>();
void update(List<? extends Superclass> l) {
l.stream().forEach(o -> put(o));
}
public void put(Superclass obj) {
String id = obj.getId();
Map<String,Superclass> submap = map.get(obj.getClass());
if(null == submap) {
submap = new HashMap<>();
map.put(obj.getClass(), submap);
}
submap.put(id, obj);
}
public Superclass get(Class clss, String id) {
return Optional.ofNullable(map)
.map(m -> m.get(clss))
.map(m2 -> m2.get(id))
.orElse(null);
}
private Map=new HashMap();
void update(List这里有一个解决方案,它可以处理无限多个可能的子类,因为据我所知,您只是在创建一个class plus Id->Superclass的映射
private Map<Class,Map<String,Superclass>> map = new HashMap<>();
void update(List<? extends Superclass> l) {
l.stream().forEach(o -> put(o));
}
public void put(Superclass obj) {
String id = obj.getId();
Map<String,Superclass> submap = map.get(obj.getClass());
if(null == submap) {
submap = new HashMap<>();
map.put(obj.getClass(), submap);
}
submap.put(id, obj);
}
public Superclass get(Class clss, String id) {
return Optional.ofNullable(map)
.map(m -> m.get(clss))
.map(m2 -> m2.get(id))
.orElse(null);
}
private Map=new HashMap();
无效更新(列表您不能执行此操作:
mapToUpdate = mapToSubclass1;
因为这样,您的代码可能会继续将非子类1
对象添加到mapToUpdate
,编译器将无法标记它(即,它将无法提供类型安全性)
解决此问题的一种方法是告诉编译器“我知道我在做什么”,而不是对mapToUpdate
变量使用泛型。如下所示:
@SuppressWarnings("unchecked")
public void update(final boolean updatesAreSubclass1,
final List<? extends Superclass> updates) {
if (updates.size() == 0) {
return;
}
Map mapToUpdate;
if (updatesAreSubclass1) {
mapToUpdate = Collections.checkedMap(mapToSubclass1, Integer.class,
Subclass1.class);
} else {
mapToUpdate = Collections.checkedMap(mapToSubclass2, Integer.class,
Subclass2.class);
}
updates.stream().forEach(
(entity) -> {
System.out.println("Adding..." + entity.toString()
+ " to map " + mapToUpdate.toString());
mapToUpdate.put(entity.getId(), entity);
});
}
@SuppressWarnings(“未选中”)
公共无效更新(最终布尔更新ResubClass1,
最终列表您不能这样做:
mapToUpdate = mapToSubclass1;
因为这样,您的代码可能会继续将非子类1
对象添加到mapToUpdate
,编译器将无法标记它(即,它将无法提供类型安全性)
解决此问题的一种方法是告诉编译器“我知道我在做什么”,而不是对mapToUpdate
变量使用泛型。如下所示:
@SuppressWarnings("unchecked")
public void update(final boolean updatesAreSubclass1,
final List<? extends Superclass> updates) {
if (updates.size() == 0) {
return;
}
Map mapToUpdate;
if (updatesAreSubclass1) {
mapToUpdate = Collections.checkedMap(mapToSubclass1, Integer.class,
Subclass1.class);
} else {
mapToUpdate = Collections.checkedMap(mapToSubclass2, Integer.class,
Subclass2.class);
}
updates.stream().forEach(
(entity) -> {
System.out.println("Adding..." + entity.toString()
+ " to map " + mapToUpdate.toString());
mapToUpdate.put(entity.getId(), entity);
});
}
@SuppressWarnings(“未选中”)
公共无效更新(最终布尔更新ResubClass1,
最终列表我不知道我是否理解正确,但是将子类映射转换为mapToUpdate是否可以?mapToUpdate=(HashMap)(map)mapToSubclass1;我不知道我是否理解正确,但是将子类映射转换为mapToUpdate是否可以?mapToUpdate=(HashMap)(map)mapToSubclass1;如果update
检查列表,而不是依赖调用者告诉它正在获取什么类型的列表,这种方法会更安全。如果update
检查列表,而不是依赖调用者告诉它正在获取什么类型的列表,这种方法会更安全。