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
检查列表,而不是依赖调用者告诉它正在获取什么类型的列表,这种方法会更安全。