简体   繁体   English

创建不可变通用对象的哈希映射

[英]Create a hashmap of immutable generic objects

I don't think that there is a way that is efficient (if at all) of doing this, but I figured I'd ask in case someone else knows otherwise. 我不认为有这样做的方式是有效的(如果有的话),但我想我会问,以防其他人知道。 I'm looking to create my own Cache/lookup table. 我正在寻找创建自己的缓存/查找表。 To make it as useful as possible, I'd like it to be able to store generic objects. 为了使它尽可能有用,我希望它能够存储通用对象。 The problem with this approach is that even though you can make a Collections.unmodifiableMap, immutableMap, etc , these implementations only prevent you from changing the Map itself. 这种方法的问题在于,即使您可以创建Collections.unmodifiableMap, immutableMap, etc ,这些实现也只会阻止您更改Map本身。 They don't prevent you from getting the value from the map and modifying its underlying values. 它们不会阻止您从地图中获取值并修改其基础值。 Essentially what I'd need is for something to the effect of HashMap<K, ? extends Immutable> 基本上我需要的是HashMap<K, ? extends Immutable>的效果HashMap<K, ? extends Immutable> HashMap<K, ? extends Immutable> , but to my knowledge nothing like this exists. HashMap<K, ? extends Immutable> ,但据我所知,这样的事情HashMap<K, ? extends Immutable>存在了。

I had originally thought that I could just return a copy of the values in the cache in the get method, but since Java's Cloneable interface is jacked up, you cannot simple call 我原本以为我只能在get方法中返回缓存中的值的副本,但是由于Java的Cloneable接口被抬起,你不能简单地调用

public V getItem(K key){
    return (V) map.get(k).clone();
}

Your thinking is good, and you're right that there's no built-in way of handling immutability. 你的想法很好,而且你没有内置的处理不变性的方法。

However, you could try this: 但是,你可以试试这个:

interface Copyable<T> {
    T getCopy();
}

Then override the get() method to return copies instead of the value itself; 然后重写get()方法以返回副本而不是值本身;

class CopyMap<K, V extends Copyable<V>> extends HashMap<K, V> {
    @Override
    public V get(Object key) {
        return super.get(key).getCopy();
    }
}

Then it's up to the implementation to return a copy of itself, rather than this (unless the class itself is immutable). 然后由实现来返回自身的副本,而不是this (除非类本身是不可变的)。 Although you can't enforce that in code, you would be within your rights to publicly humiliate the programmer that doesn't conform. 虽然你不能在代码中强制执行,但你有权公开羞辱那些不符合的程序员。

I'm looking to create my own Cache/lookup table. 我正在寻找创建自己的缓存/查找表。

Why not use Guava's cache ? 为什么不使用Guava的缓存

The problem with this approach is that even though you can make a Collections.unmodifiableMap, immutableMap, etc, these implementations only prevent you from changing the Map itself. 这种方法的问题在于,即使您可以创建Collections.unmodifiableMap,immutableMap等,这些实现也只会阻止您更改Map本身。 They don't prevent you from getting the value from the map and modifying its underlying values. 它们不会阻止您从地图中获取值并修改其基础值。

This is not something any collection can enforce for you. 这不是任何集合可以为您强制执行的操作。 You need to make the classes themselves immutable. 您需要使类本身不可变。 There is a hacky approach using Reflection (which can also be used to make a class mutable!), but really, you should avoid this and simply create classes that are immutable. 使用反射哈克的方法(也可用于制造一类可变!),但实际上,你应该避免这一点,只需创建是不可变的类。

There are other options for object cloning in Java: Making a copy of an object Dynamically? Java中的对象克隆还有其他选项: 动态制作对象的副本?

Be aware though that deep cloning any object might be dangerous. 请注意,深度克隆任何对象可能都很危险。 The objects stored in this map must be ie isolated from each other, to make sure that whole object graph won't be copied when returning a single entry. 存储在此映射中的对象必须彼此隔离,以确保在返回单个条目时不会复制整个对象图。

There is no formal concept of "mutability" or "immutability" in the language. 该语言中没有“可变性”或“不变性”的正式概念。 The compiler cannot tell whether a type is "mutable" or "immutable". 编译器无法判断类型是“可变”还是“不可变”。 To determine whether something is immutable, we humans have to examine every field and method of the class, and reason through the behavior of the methods to discover that none of them will alter the state of the object, then we call it "immutable". 为了确定某些东西是不可变的,我们人类必须检查类的每个字段和方法,并通过方法的行为来推断它们都不会改变对象的状态,然后我们称之为“不可变”。 But there is no difference from the perspective of the language. 但是从语言的角度来看没有区别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM