我有一个类似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)
构造函数的对象一样多。
我该如何解决?
答案 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的设计偏向于冗长而不是性能(其哲学是“购买更好的硬件比雇用更好的程序员便宜”)。如果您同意这种推理,则仅使用包装器并仅在有证据证明存在问题时进行优化才有意义;如果您不同意,使用其他答案中建议的好名字就足够了。