提问者:小点点

在Java中可识别地存储方法


我正试图想出一个问题的解决方案,在这个问题中,我希望以某种方式存储方法引用,以便在需要时调用它们,并在我的方法列表中不需要它们时移除它们。

这里的基本目标是这样的:

我有个人课:

public class Person {
    private String ref, name;
    private String fatherRef; // can be reference string (such as "#1#") or a literal text (such as "the guy next door")

    public Person(String ref, String name) {
        this.ref = ref;
        this.name = name;
    }

    public String getFatherRef() {return fatherRef;}

    public void setFatherRef(String ref) {
        fatherRef = ref;
    }

    ...
}

我创建了两个父和子的实例,并使用setFatherRef方法将父的ref设置为子的fatherRef。 我把他们两个都列在单子上。 现在假设父亲的对象从系统中删除,并且他的引用对另一个人可用。 为了确保在其父被删除后,其子的对象中不会引用其父,我想出了这样的方法:

我创建了一个接口IRefSetter{public void setRef(String ref);},并使用它创建了一个ArrayList< IRefSetter>方法(例如SetFatherRefSetMotherRef等),并使用父级的引用将该列表映射到一个HashMap上,这样,每当我摆脱任何一个人时,我都可以查看他们的引用,并查看它是否映射到一个方法列表上,我可以使用该列表将

在本例中,映射将只有一个父引用到列表的映射,该列表包含引用Person类中的SetFatherRef的单个方法。 这样就可以很好地工作了,但是假设我将fatherRef设置为其他人的ref,并以与原始father相同的方式为该新人添加方法引用。 但是现在剩下的是一个hashmap,它包含在原始父亲的ref下的一个列表,其中存储了一个方法,用于在原始父亲被删除时重置儿子的fatherRef。 但这不再是必要的,因为儿子现在有一个不同的父集合,具有不同的裁判。

我找不到一种简单的方法来识别列表中的哪个方法是Son::SetFatherRef,因为每次引用该方法时创建的lambda函数都是不同的。

从那时起,我开始研究一种非常难看的解决方案,它不是存储与我的原始iRefSetter接口匹配的lambda函数,而是存储对儿子的Person实例的Object引用以及作为String的方法名,并尝试手动将正确的方法与我的iRefSetter接口匹配(使用Classmethod类)。 但这是一个非常丑陋的解决方案,它会产生运行时错误,而不是编译器错误,这是我不喜欢的,整个事情在我看来不是非常OOP。

我是不是错过了一个更好的解决方案?


共1个答案

匿名用户

更好的解决办法是:

public class Person {
    private String ref, name;
    private Person father;
    private List<Person> children;

    ... a lot of obvious stuff here ...
}

现在,当您删除一个时,您可以查看该人的父亲,然后从的父亲列表中删除该,还可以查看已删除人的,并将每个人的父亲设置为NULL。 如果您想知道父亲的引用,只需执行father.refgetFather().getRef()即可。

我感觉到你不想这样做出于某种原因,比如它很脏或者不是OOP之类的东西。 但这是最好地利用语言和运行库功能的解决方案。

其他的解决方案往往是更复杂的方法。 在您的示例中,没有使用childress成员,而是创建了单独的hashmap,其中键是父引用,值是setter方法数组,但是您可以看到这是一样的:对于每个子-父关系,列表中都有一个条目与父关联。

如果您坚持使用setter策略,那么避免意外清除不再指向要删除的人员的问题的一个简单方法就是检查字段是否仍然指向该人员。 setter方法仍然在列表中,并且仍然会被调用,但是它不会造成任何损害。