字符串的值对象

时间:2018-10-18 08:39:28

标签: java string memory

我有一个类似Map idMap = new Hashhap<String, AnyClass>;的地图,其中的键是一个特定的ID(我们处理许多ID),我们将其称为MyEntityId

因此,为了便于阅读并避免使用此地图时出现问题,我想将其转换为更好的形式:Map idMap = new Hashmap<MyEntityId, AnyClass>

现在,使用lombock实现MyEntityId的方法是:

@Data
@AllArgumentsConstructor
public class MyEntityId {
    private String id; 
}

问题是,现在每当我有一个表示MyEntityId的String时,我都必须对其进行转换new MyEntityId(myString),而这样做,我就失去了String的内部表示的优点。因此,如果以前对于字符串“ 123abc”,我在JVM中只有一个对象,那么现在与调用new MyEntityId(id)构造函数的对象一样多。

我该如何解决?

3 个答案:

答案 0 :(得分:4)

解决可读性问题的另一种方法是给地图起一个“更好的”名称。

某些选项可能是:

Map anyClassValueByMyEntityIDMap = new HashMap<String, AnyClass>();

Map anyClassValueForMyEntityIDMap = new HashMap<String, AnyClass>();

Map myEntityIDToAnyClassValueMap = new HashMap<String, AnyClass>();

通过这种方式,很明显,您必须使用MyEntityID来访问地图,而又不会失去String的内部表示形式的优点。

答案 1 :(得分:0)

您必须同时覆盖hashCode()equals()方法:

public class MyEntityId {

    private String id;

    @Override
    public int hashCode() {
        return id.hashCode();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        MyEntityId that = (MyEntityId) o;

        return id.equals(that.id);
    }
}

注意:

答案 2 :(得分:0)

您始终可以执行Java对字符串的操作-保留现有实例的映射,并使用工厂方法:

public class MyEntityId {
    private static Map<String, MyEntityId> instances = new HashMap<>();
    private MyEntityId(String id) { ... }
    public static MyEntityId valueOf(String id) { /* Get or create instance for that ID */ }
}

您仍然不应该依赖==来创建字符串。

我不确定是否值得这样做。 Java的设计偏向于冗长而不是性能(其哲学是“购买更好的硬件比雇用更好的程序员便宜”)。如果您同意这种推理,则仅使用包装器并仅在有证据证明存在问题时进行优化才有意义;如果您不同意,使用其他答案中建议的好名字就足够了。