Java 避免使用静态方法创建具有相同值的实例

Java 避免使用静态方法创建具有相同值的实例,java,Java,我的程序应该不能创建具有相同名称的值的新实例,但我不知道如何做。我想在代码中加入一些if语句,但不知道如何实现它 public class Smurf { private String name; public static Smurf createSmurf(String name) { System.out.println("Creating " + name + " Smurf"); return

我的程序应该不能创建具有相同名称的值的新实例,但我不知道如何做。我想在代码中加入一些if语句,但不知道如何实现它

public class Smurf {

    private String name;

    public static Smurf createSmurf(String name) {
        System.out.println("Creating " + name + " Smurf");
        return new Smurf(name);
    }

    private Smurf(String name) {
        this.name = name;
    }

    public void printName() {
        System.out.println("My name is " + name + " Smurf.");
    }

    public void eat() {
        System.out.println(name + " Smurf is eating Smurfberries.");
    }

}

不是为你做家庭作业,而是一些指导:

  • 是的,如果一个Smurf实例有一个名称,那么您需要在类中为该名称设置一个非静态字段
  • 但是:当你想确保名字是唯一的,那么你需要以某种方式跟踪所有已知/使用过的名字
一个非常简单(容易出错,不适合现实世界)的解决方案:您可以在该类中使用
私有静态最终列表usedNames=new ArrayList()

该列表是静态的,因此类的所有实例都会看到相同的列表

现在,您可以在创建方法中检查作为参数提供的名称是否已在该列表中。如果是这样,拒绝创造新的蓝精灵。否则,创建新的蓝精灵,并将新名称添加到该列表中

如果你想知道“这在现实世界中为什么行不通”:因为A)Smurf类跟踪所有Smurf的名字是一个糟糕的设计,B)也许Gargamel在某个时候吃了
粗心的Smurf
。然后需要额外的代码才能从列表中删除该名称。或者,当粗心的蓝精灵想要重新繁殖时,您不能再次使用该名称。等等


注意:在写这个答案的过程中,没有蓝精灵受伤。

可能会把你的蓝精灵放在这样一张地图上:

private static final Map<String, Smurf> smurfs = new HashMap<>();

请注意,这既不是线程安全的设计,也不是好的设计,但它可以满足您的需要。

我要感谢大家的回答,尤其是GhostCat的帮助。 最后,我刚刚创建了一个数组列表,将蓝精灵放在其中并进行检查


我还有很多东西要学,也许你很快就会看到另一个问题

在“现实生活”中你会怎么做?你需要记录哪些蓝精灵已经被创造出来,如果被要求第二次创造蓝精灵,你会“返回”已经创造出来的蓝精灵(或者拒绝这个请求)。您需要做一些类似的事情:跟踪已创建对象的名称(在数组/列表/映射等中)。从Object类重写的equals方法在您的情况下会很有用您忘记将新创建的Smurf放入映射中,因此您将始终创建一个新的Smurf。另外,我们现在有了
computeifassent
,所以
返回map.computeifassent(name,Smurf::new)
。我真傻。修正了;-)
computeIfAbsent
很简洁,但我认为对于初学者来说,老式的方法更容易阅读。请注意,您的方法名是假的。上面写着创造。但它不一定会创造出新的蓝精灵。名字应该说命名的东西,并且事情应该做的名字。也请注意:当您重命名该方法时,考虑包含<代码> alsCurrasePrimalMyTyLyCurror()/代码>…因为这取决于事物的使用方式,这是这种方法的一个大问题;-)非常棒的非代码答案,imho。有时这就是所谓的一切。
public static Smurf createSmurf(String name) {
    Smurf newSmurf = null;
    if(smurfs.containsKey(name)) {
        System.out.println("Smurf " name + " already exists.")
        newSmurf = smurfs.get(name);
    }
    else {
        System.out.println("Creating " + name + " Smurf");
        newSmurf = new Smurf(name);
        smurfs.put(name, newSmurf);
    }
    return newSmurf;
}