类Java的多个通用类型

发布于 2025-02-07 11:08:27 字数 857 浏览 1 评论 0原文

有没有一种方法可以使用具有通用类型的类,而没有设置最大数字? 我有此类

public class Repository<V> {
    private Map<String, HashSet<V>> repo = new HashMap<>();
    private static Repository instance = null;

    private Repository() {}
    
    public static synchronized Repository getInstance() {
        if(instance == null) {
            instance = new Repository();
        }
        
        return instance;
    }
    
    public void addRepository(String key) throws ClassNotFoundException, IOException {
        repo.put(key, new HashSet<>());
    }

    .....
}

这是一个“通用存储库”,hashmap包含标识符作为键,而作为值则具有hashset&lt; v&gt;和数据。

我希望Hashmap中的每个hashset都包含不同的类类型。更确切地说,我希望通用类型vhashmap中对每个hashset

不同达到这个结果?

is there a way to use a class, with generic types, without setting the maximum number?
I have this class

public class Repository<V> {
    private Map<String, HashSet<V>> repo = new HashMap<>();
    private static Repository instance = null;

    private Repository() {}
    
    public static synchronized Repository getInstance() {
        if(instance == null) {
            instance = new Repository();
        }
        
        return instance;
    }
    
    public void addRepository(String key) throws ClassNotFoundException, IOException {
        repo.put(key, new HashSet<>());
    }

    .....
}

this is a "general repository", the HashMap contains an identifier as a key while as a value have HashSet<V> with the data.

I would like each HashSet in the HashMap to contain different class types. More precisely, I would like the generic type V to be different for each HashSet within the HashMap

how can i fix the code to be able to achieve this result?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓝颜夕 2025-02-14 11:08:27

您不能添加类参数,例如存储库&lt; v&gt;,并期望v在地图中的每种类型的条目都不同。

但是,您可能会执行类似的操作:

从存储库中删除通用类型:

public class Repository {
}

GERTISE repository映射,以便将class&lt;?&gt;作为键(而不是字符串)和set&lt;?&gt;作为值):

private final Map<Class<?>, Set<?>> repo = new HashMap<>();

然后,创建一种添加新存储库的方法和一种获取现有存储库的方法:

public <T> void addRepository(Class<T> key) {
    Set<?> existing = repo.putIfAbsent(key, new HashSet<>());
    if (existing != null) {
        throw new IllegalArgumentException("Key " + key + " is already associated to a repository");
    }
}

public <T> Set<T> getRepository(Class<T> key) {
    Set<?> subRepo = repo.get(key);
    if (subRepo == null) {
        throw new IllegalArgumentException("No repository found for key " + key);
    }
    return (Set<T>) subRepo; //unchecked cast
}

注意:getrepository()将执行不受组织的演员阵容,但这是“安全”的未检查的演员,因为在地图中添加新条目的唯一方法是通过&lt; t&gt; void addrepository(class&lt; t&gt; key),您将无法在返回的set&lt; t&gt;中插入不t的值。

示例用法:

Repository repository = Repository.getInstance();
repository.addRepository(String.class);
repository.addRepository(Integer.class);
Set<String> stringRepo = repository.getRepository(String.class);
stringRepo.add("Hey");
stringRepo.add("Jude");
Set<Integer> intRepo = repository.getRepository(Integer.class);
intRepo.add(1);
intRepo.add(4);

但是,我认为您每种类型都有一个存储库,它将更加干净,因为使用上述解决方案,您基本上根本不利用Java Generics(除了方法&lt; t&gt; 在getRepository方法中使用,无论如何您都需要执行未检查的铸件)。

You can't add a class parameter such as Repository<V> and expect V to be different for each type of entry in the map.

However, you may do something like this:

Remove the generic type from Repository:

public class Repository {
}

Generify the repository map so that it takes a Class<?> as key (instead of a String) and a Set<?> as value):

private final Map<Class<?>, Set<?>> repo = new HashMap<>();

Then, create one method to add a new repository and a method to get an existing repository as such:

public <T> void addRepository(Class<T> key) {
    Set<?> existing = repo.putIfAbsent(key, new HashSet<>());
    if (existing != null) {
        throw new IllegalArgumentException("Key " + key + " is already associated to a repository");
    }
}

public <T> Set<T> getRepository(Class<T> key) {
    Set<?> subRepo = repo.get(key);
    if (subRepo == null) {
        throw new IllegalArgumentException("No repository found for key " + key);
    }
    return (Set<T>) subRepo; //unchecked cast
}

Note: the getRepository() will perform an unchecked cast, but it is a "safe" unchecked cast since the only way to add a new entry into your map is passing through <T> void addRepository(Class<T> key) and you won't be able to insert values that are not T inside the returned Set<T>.

Sample usage:

Repository repository = Repository.getInstance();
repository.addRepository(String.class);
repository.addRepository(Integer.class);
Set<String> stringRepo = repository.getRepository(String.class);
stringRepo.add("Hey");
stringRepo.add("Jude");
Set<Integer> intRepo = repository.getRepository(Integer.class);
intRepo.add(1);
intRepo.add(4);

However, I think you should have one repository per type, it would be cleaner because with the above solution, you're basically not leveraging at all on Java generics (except for the method <T> used in the getRepository method, for which you need to perform an unchecked cast anyway).

柠檬色的秋千 2025-02-14 11:08:27

无法干净地实现这一目标。您可以为所拥有的每种类型创建一个存储库,但是您不能使用此设置将它们团结到一个存储库中。

There's no way to achieve that cleanly. You can create a repository for each type you have, but you can not unite them into one repository with this setup.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文