我正在存储LOAD CSV WITH HEADERS FROM "file:///output.csv" AS line
MERGE (sub:Item {name:line.source})
MERGE (sup:Item {name:line.target})
WITH sub, sup, line
CALL apoc.create.relationship(sub, line.Relationshiptype, NULL, sup) YIELD rel
RETURN sub, rel, sup
,House
,Car
,Clothes
等类; FacialFeatures
中Person
的所有部分:
HashMap
外部使用:
public class Person {
private HashMap<String, PersonalItem> map = new HashMap<String, PersonalItem>();
public void init(){
map.put("house", new House());
map.put("car", new Car());
map.put("clothes", new Clothes());
//etc...
}
public PersonalItem getPersonalItem(String name){
return map.get(name);
}
}
如果我使用以下代码,我怎么能这样做:
public static void main(String[] args){
Person person = getPerson(args);
//if i want to use car.setColor(blue); i have to do:
((Car) person.getPersonalItem("car")).setColor(blue);
//or if i want to use house.setExterior(wooden); i have to do:
((House) person.getPersonalItem("house")).setExterior(wooden);
}
如果输入为&#34; house,它将起作用,person.getPersonalItem("house").setExterior(wooden);
将返回getPersonalItem
。&#34;我不想每次都写出一个吸气剂:
Object instanceof House
有替代方案吗?
答案 0 :(得分:4)
你可以使用的一个(脏?)技巧是使用Class
对象作为地图的键而不是任意名称,并直接在getter中向下转换:
public class Person {
private Map<Class<? extends PersonalItem>, PersonalItem> map = new HashMap<>();
public void init() {
map.put(House.class, new House());
map.put(Car.class, new Car());
map.put(Clothes.class, new Clothes());
//etc...
}
public <T extends PersonalItem> T getPersonalItem(Class<T> cls) {
return (T) map.get(cls);
}
你仍然有一个演员阵容,但它只限于一个地方,当使用 Person
类时你不必知道它:
person.getPersonalItem(House.class).setExterior(wooden);
这种方法的缺点是一个人不能拥有两个相同类型的个人物品。
答案 1 :(得分:1)
您尝试做的事情在类型安全方面并不安全 执行可能在运行时发生的强制转换以避免多重方法并不是一件好事 在你的情况下,我想知道从地图访问值是否真的有意义 如果Map定义Person类的状态,则为每个类使用相应的字段和getter 如果您有很多并且不想编写/污染您的类,您可以在编译时使用Lombok为您生成getter(以及其他样板代码)。
作为Mureinik的替代方法,您可以在getPersonalItem()
方法中使用泛型来从调用的客户端推断类型。通过这种方式,您可以在地图中有多个对象具有相同类型的条目。
@SuppressWarnings("unchecked")
public <T extends PersonalItem> T getPersonalItem(String name, Class<T> clazz){
return (T) map.get(name);
}
并调用它:
person.getPersonalItem("myHouse", House.class).setExterior(stone);
person.getPersonalItem("mySecondHouse", House.class).setExterior(wooden);
答案 2 :(得分:1)
听起来你正在使用字符串+ map方法来避免显式getter(和setter)。但是你扔掉了所有的编译时类型信息。所以编译器可以在这里给你很多帮助。实际上,其他答案中的方法不会保护您免于意外地将Car
类型与"house"
相关联。
如果需要考虑详细程度,可以使用其他选项来保留编译时类型:
代码生成(例如Immutables或Lombok)。这些都很好,但需要额外的工具和构建步骤。
使用Kotlin,特别是data classes。它们尽可能简洁,Kotlin与Java有很好的互操作性。
我强烈主张#2 - 我使用这种方法经历了高效益和低摩擦(即在Kotlin中定义类型,然后从Java代码库中消费它们)。
答案 3 :(得分:1)
我会使用一个文件或数据库表,其中存储可能的关键字,链接到类,如
人:房子,汽车,衣服;房子:车主,车库
等等,如果它是一个文件,如果它是一个数据库表,那么
表属性(id,className,propertyName)
可以提供帮助。无论输入是什么,你都可以编写一个生成类的代码,比如PersonDefinition
,其中定义了getter和setter(当然,你也可以处理属性类型,为了简单起见我省略了这个) / p>
然后确保从Person
继承PersonDefinition
,并且无论何时构建项目,预构建事件都应生成PersonDefinition
class
,因此您将拥有所有你需要的安装者和吸气剂。
答案 4 :(得分:1)
使用泛型的解决方案和类对象作为地图的关键似乎对我来说最好。但是,如果是一个类,例如House尚未添加到地图中:
person.getPersonalItem(House.class).setExterior(wooden);
可以在IDE中使用代码完成进行编程,但在运行时会给出空指针。以前有人给出了解决方案:
public <T extends PersonalItem> T getPersonalItem(String name){
return (T) map.get(name);
}
这确实只涵盖问题的代码重复部分,并且遭受同样的危险。但是,如果你需要编码:
House house = (House)person.getPersonalItem("house");
更清楚的是,你必须确定&#34; house&#34; key实际上存在于地图中。