我目前正在自学Java,实践问题的最终输出之一需要为不同的对象使用不同的名称(这是根据随机数生成器确定的)。但是,每次创建对象时,这些对象最终都会使用相同的名称。为了给出一个清晰的例子,下面是示例输出:
以下是我的输出:
正如我的输出突出显示的那样,我所有的动物都具有相同的名称,而预期的输出具有不同的名称。我已经测试了多次,可以确认这不是由于运气造成的。
下面是我的Cow
类的代码,该代码构造名称和其他信息(我省略了不相关的方法):
import java.lang.Math;
import java.util.Random;
public class Cow implements Milkable, Alive {
private String name;
private double capacity;
private double amount;
private static final String[] NAMES = new String[]{
"Anu", "Arpa", "Essi", "Heluna", "Hely",
"Hento", "Hilke", "Hilsu", "Hymy", "Ihq", "Ilme", "Ilo",
"Jaana", "Jami", "Jatta", "Laku", "Liekki",
"Mainikki", "Mella", "Mimmi", "Naatti",
"Nina", "Nyytti", "Papu", "Pullukka", "Pulu",
"Rima", "Soma", "Sylkki", "Valpu", "Virpi"};
private static final String randName = NAMES[new Random().nextInt(NAMES.length)];
// Default Constructor <- where issue is
public Cow(){
this(randName);
}
// Overloaded Constructor
public Cow(String name){
this.name = name;
this.capacity = (15.0 + new Random().nextInt(26));
this.amount = 0.0;
}
// accessors...
// milk... removes milk from cow's tank (implements Milkable interface)
// liveHour... adds milk to cow's tank (implements Alive interface)
// toString...
}
此外,这是我上面使用的主要类(同样,省略了不必要的部分):
Farm farm = new Farm("Esko", new Barn(new BulkTank()));
farm.addCow(new Cow());
farm.addCow(new Cow());
farm.addCow(new Cow());
System.out.println(farm);
This post表示,如果在构造函数上已经设置了种子,则随机数生成器最终将是确定性的。但是,我的随机数生成器必须具有特定的种子(在这种情况下,数组的长度包含随机名称)才能选择随机名称。我想知道是否有人知道让我的随机数生成器产生新值的方法。预先谢谢你。
答案 0 :(得分:8)
问题是这一行:
private static final String randName = NAMES[new Random().nextInt(NAMES.length)];
您将randName
定义为静态变量,该静态变量绑定到类而不是实例,这意味着Cow
的每个实例都具有相同的randName
。
在默认构造函数中,您应该具有:
public Cow(){
this(NAMES[new Random().nextInt(NAMES.length)]);
}
答案 1 :(得分:1)
randName 被声明为静态的,可能会导致问题。静态字段在类加载时仅加载一次。尝试将其声明为实例变量(非静态)
答案 2 :(得分:1)
除了hotzst的答案外,没有理由为您创建的Random
的每个实例创建一个新的Cow
实例。
例如,您可以如下定义名称生成器:
private static final Random random = new Random();
private static final Supplier<String> namesGenerator = () -> NAMES[random.nextInt(NAMES.length)];
现在,您可以使用以下方法实例化Cow
:
public Cow() {
this(namesGenerator.get());
}