java - 泛型:如何在不强制转换的情况下获取 map 的值

标签 java generics collections casting hashmap

我有一个名为 BaseCode 的抽象类和 2 个名为 Location 的具体类和 Department :

public abstract class BaseCode {
   private Integer id;
   ...
   public Integer getId() { return id; }
   public void setId(Integer id) { this.id = id; }
   ...
}

public class Location extends BaseCode {
   ...
}

public class Department extends BaseCode {
   ...
}

我有一个名为 BaseCodeCache 的抽象类和 2 个名为 LocationCache 的具体类和 DepartmentCache . LocationCacheDepartmentCache将使用 Singleton .

public abstract class BaseCodeCache {
   ...
}

public class LocationCache extends BaseCodeCache {
   ...
}

public class DepartmentCache extends BaseCodeCache {
   ...
}

  1. BaseCodeCache , 我想要一个 java.util.Map谁的值(value)可以 是任何类型的 BaseCodeLocation对象或 Department 对象。
    LocationCache , 我想要 java.util.Map存储Location对象。
    DepartmentCache , 我想要 java.util.Map存储Department对象。

为此,我将此代码放在 BaseCodeCache 中:

private Map<Integer, BaseCode> idMap = new HashMap<Integer, BaseCode>();

  1. 我想有一个方法来存储一个值 java.util.Map .

为此,我将此代码放在 BaseCodeCache 中:

public void add(BaseCode baseCode) {
   if (baseCode != null) {
      idMap.put(baseCode.getId(), baseCode);
   }
}

这就是我将它用于 Location 的方式:

Location location = new Location(); ...
LocationCache.getInstance().add(location);

这就是我将它用于 Department 的方式:

Department department = new Department(); ...
DepartmentCache.getInstance().add(department);

  1. 我想要一个方法来获取 java.util.Map 中的所有值作为 一个java.util.List .
    LocationCache此方法应返回 List<Location> .
    DepartmentCache此方法应返回 List<Department> .

这就是我卡住的地方。我想在 BaseCodeCache 中创建这个方法但是当通过 LocationCache 调用此方法时然后返回 List<Location>当通过 DepartmentCache 调用相同的方法时然后返回 List<Department> . 这可能吗?

我把这段代码放在 BaseCodeCache 中:

public List<BaseCode> getList() {
   return new ArrayList<BaseCode>(idMap.values());
}

但是上面的代码返回List<BaseCode> .当我这样调用它时:

List<Location> allLocations = LocationCache.getInstance().getList();

然后java就不让它编译了,给出这个错误信息:

Type mismatch: cannot convert from List<BaseCode> to List<Location>

我可以通过获取 List<BaseCode> 来修复它然后将其转换为 List<Location>通过循环,但这看起来不正确。

可以吗?

最佳答案

使用泛型实现如下:

public abstract class BaseCodeCache<T extends BaseCode> {
    private Map<Integer, T> idMap = new HashMap<>();

    public void add(T baseCode) {
        if (baseCode != null) {
            idMap.put(baseCode.getId(), baseCode);
        }
    }

    public List<T> getList() {
        return new ArrayList<>(idMap.values());
    }
}

public class LocationCache extends BaseCodeCache<Location> {}

public class DepartmentCache extends BaseCodeCache<Department> {}

这将使您能够执行以下操作而不会出现任何编译错误:

LocationCache locationCache = new LocationCache();
locationCache.add(new Location());

List<Location> locations = locationCache.getList();

更好的是,如果您尝试添加或检索错误类型的对象,您得到编译错误:

locationCache.add(new Department()); // won't compile
List<Department> departments = locationCache.getList(); // won't compile

关于java - 泛型:如何在不强制转换的情况下获取 map 的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45318195/

相关文章:

.net - 使用lambda而不是字符串属性名称选择模型属性

java - 有效地迭代 2 个具有相同对象类型的不同列表(Java8)

java - Spring Boot LDAP 组和受限端点

java - 使用 Java 在 Google Analytics 上进行分页

java - 在 Swagger 中使用泛型处理特殊情况

java - 从类型参数枚举 Enum 类

Java Collection-Within-Collection 并发

C# MongoDB 和更新项目列表

java - 在 Java 中创建从 .txt 文件读取和写入二维数组的程序时遇到困难

java - android手机 hibernate 时保持wifi连接