2016-09-21 154 views
-3

此对象是一包口香糖。每种口香糖都是独一无二的。我们建立了一个可容纳12颗牙龈的包。我们用新的口香糖填充包装。我们必须检查包装,看看这种口香糖是否已经装入包装中。包装中的每个口香糖必须是独特的。Java嵌套循环防止重复

public PackOfGum() 
{ 
    pack = new Gum[12]; 
    // Successfully populate pack with gum 
    for (int i=0; i<12; i++) { 
    pack[i] = new Gum(); 


    // Failure preventing duplicate gums. Idea is to look in the pack 
    // at all of the gums that came before this one, and see if this one 
    // matches any of them. While yes and it is a duplicate, then choose 
    // a new gum. 
    for (j=0; j<i; j++) { 
     while (pack[i] == pack[j]) { 
     pack[i] = new Gum(); 
     } 
    } 
    } 
} 

我未能正确地检查所有以前的牙龈,并将它们与当前口香糖比较。这应该如何正确完成?

+2

我不知道我是否正确理解您的问题。但是如果你只是想存储一个非重复的枪支集合,那么你可以使用java.util.Set来存储它。您需要在Gum类中实现equals方法来定义相等条件。 –

+0

一个问题:你如何比较胶质物体?使用其内存地址或其值? – MaxZoom

+0

口香糖“种类”的定义是什么?您现在正在比较两个Gum引用是否指向相同的Gum对象实例。鉴于你正在为数组中的每个元素创建一个新的Gum实例,它总是会有所不同。 –

回答

1

您需要在Gum class中提供您自己的equals()实施。

@Override 
public boolean equals(Object other) 
{ 
    if (!(other instanceof GumClass)) 
    { 
     return false; 
    } 
    GumClass that = (GumClass) other; 
    // Custom equality check here. 
    return this.field1.equals(that.field1) 
    && this.field2.equals(that.field2); 
} 

如果您的对象有任何机会在哈希表中使用,您还应该覆盖hashCode()。一个合理的实现将是该对象的字段的哈希码的东西,如结合:

@Override 
public int hashCode() 
{ 
    int hashCode = 1; 
    hashCode = hashCode * 37 + this.field1.hashCode(); 
    hashCode = hashCode * 37 + this.field2.hashCode(); 
    return hashCode; 
} 

this question,详细了解实施的哈希函数

+1

@Hector实现'hashCode'而不实现'equals'不会破坏合约。虽然它有点傻。 – ajb

0

有许多的东西从你的问题遗漏。首先,由于您没有给我们提供Gum课程,所以我无法弄清楚每个new Gum()将如何创建一个独特的GumGum是否有某种flavor实例变量被初始化为随机味道?也许,但你没有给我们这些信息。另外,正如其他答案指出的那样,使用==来比较牙龈是行不通的。假设每个Gum都有一个flavor,您需要提供一个equals()方法,该方法比较flavor字段的相等性(和hashCode函数,该函数返回具有相同风格的任何Gum对象的相同散列值)。

我最想指出的问题是你的循环逻辑中的缺陷。您正在浏览一组现有的Gum对象,并且每当发现重复对象时,都会创建一个新的Gum。这不会完成工作。假设你的数组由A,B,C,D,E组成。假设new Gum()生成一个口香糖C的口香糖。你通过这个数组,你发现它匹配pack[2]。所以,你生成另一个Gum - 你的随机Gum发电机产生一个Gum香味B.现在你的循环不会找到它,因为你仍然向前通过阵列,你只会看D和E.所以你最终会在你的包里有一个副本。

那么你会怎么做?一种选择是,无论何时发现重复,都会生成一个新的Gum,然后在数组的开头重新开始。这是一个非常缓慢的方式来做事,但它会起作用。一些更好的选择:

  • 维护所有Gum的那些已经在包的Set。现在,不要通过数组来查看Gum是否是重复的,只需查看该集合是否包含它即可。如果你使用HashSet,你可以在恒定的时间内完成这个测试,而不是搜索数组。 (如果您使用的是HashSet,则您肯定需要使用hashCode功能。)

  • 保留所有尚未使用的Gum口味的数组。如果您从12种口味开始,那么第一个new Gum()将使用从0到11的随机数,第二个将使用从0到10的随机数,从0到9的第三个,等等。每次,您将使用数组和随机数来选择正确的风味,然后进行交换以将该风味移动到数组的末尾。例如,如果数组开始出现A,B,C,D,E,F,G,H,I,J,K,L和你的随机数是4,那就是E的味道,然后你用L替换你的数组A,B,C,D,L,F,G,H,I,J,K,E。下一个随机数只会从0到11,所以它不会选择E.无论它选择什么,都会用K替换。等等。