检查是否已创建对象

时间:2011-12-23 19:50:39

标签: java

我正在尝试创建一个程序,其中 - 我尽可能简单地使用它 - 我找到了三角形的边。

这样做的问题是可能还有另一个三角形已经找到了完全相同的边。例如:

如果程序找到一个边长为1, 2, 1而另一个带有1, 1, 2的三角形,那么,由于我正在做的规则,我不需要再次使用这个三角形,因为它有同样的方面,只是以不同的顺序。

我想创建一个可以输入三角形值的类,例如= new triangle(x,y,z),其中x,y和z都是边的整数。

这不是问题,因为我已经上课了。问题是我如何检查三角形是否已经与我输入的边相同?

感谢。

9 个答案:

答案 0 :(得分:2)

执行此操作的一种方法可能是将它们全部放在Set中并实施您的equals()hashCode()方法,以便边/边的顺序无关紧要。这样,如果你给它三角形(1,2,1)或三角形(1,1,2),你的equals和hashCode方法都会报告相同的值。

答案 1 :(得分:2)

覆盖equals的{​​{1}}和hashCode以检测“相同”三角形,并保留Triangle到目前为止创建的所有HashSet<Triangle>

例如,如果您想要打印没有重复的三角形,您可以这样做:

Triangle

,其中

Set<Triangle> triangles = new HashSet<Triangle>();
for (String line : file) {
    Triangle t = makeTriangle(line);
    triangles.add(t); // does nothing if an equal Triangle is already in the set
}
System.out.println("The distinct triangles are:");
for (Triangle t : triangles) {
    System.out.println(t);
}

注意:此方法要求您创建一个新的三角形以检查它是否重复。可以扩展该方法以解决对象分配问题,但这会使代码复杂化,从而获得很少的性能提升。

答案 2 :(得分:2)

1)确保在Triangle类中正确实现equals。

2)然后,创建一个三角形对象的静态集合,并将该集合存储在三角形类中。

class Triangle
{
static Set<Triangle> cache = new TreeSet<Triangle>();
...

然后将三角构造函数设为私有并使用工厂制作三角形,因此每次创建三角形时都要检查此集合中是否存在相同的三角形。

3)现在,添加一个工厂方法来创建三角形。

public static Triangle createTriangle(int x , int y, int z) 
{
   Triangle t = new Triangle(x,y,z));
   if(! cache.contains(t))
      cache.put(t);

   return cache.get(t);       
}

静态集合将持续存在指向所有已创建三角形的指针。

答案 3 :(得分:0)

在实施equals(Object o)hashcode方法时,让Triangle类使用其边长(参见http://www.javapractices.com/topic/TopicAction.do?Id=17)。然后创建一组已存在的。如果有新的三角形,请检查该集合是否已包含它。

Set<Triangle> existingTriangles = new HashSet<Triangle>();
// loop
Triangle newTriangle = new Triangle(side1, side2, side3);
// Already exists
if (existingTriangles.contains(newTriangle)) {

}
// New triangle
else {

}

答案 4 :(得分:0)

在某处您必须存储先前构造的三角形的缓存(可能是Set)。如果您的Triangle等于方法正确覆盖.hashCode().equals(Object),那么您可以在您创建的集合上使用.contains(Object)方法查看它是否已存在。

Triangle t = new Triangle(x, y, z);

if (!cache.contains(t))
{
    cache.add(t);

    // do something with new object
}
else
{
    Triangle cachedTriangle = cache.get(t);

    // do something with cached object
}

答案 5 :(得分:0)

在您的情况下,您定义两个对象是相等的,如果每个边的长度与另一个边相等。因此,解决此问题的一种方法是覆盖equals()方法。 (在这种情况下,不要忘记覆盖hashCode()。)然后你就可以了

if (triangle1.equals(triangle2))  {...}

如果您不想改变equals的行为,那么只需在类中定义您自己的方法,例如compare(anotherTrinangle),并在那里提供相同的逻辑。

然后,您所有的三角形都可以保存在您喜欢的Collection范围内。

答案 6 :(得分:0)

如果createTriangle()已经存在逻辑,如果它已经不存在,或者只是不创建,那么我能想到的最简单的方法是使用静态成员,比如 count < / strong>,在Triangle课程中。

每当你创建一个三角形时,只需增加它。如果要检查它是否实际创建,请将此计数变量的先前值与当前值进行比较。

答案 7 :(得分:0)

嗯,为什么不做一些与众不同的事情。所有其他方法都让您每次真正想知道类似的东西是否已经存在时创建一个Triangle对象。当然,GC会处理这个问题......
这是我的想法。
首先,写一个这样的测试:

@Test
public void testSimple() {
    final Triangle t1 = Triangle.create( 1, 2, 3 );
    final Triangle t2 = Triangle.create( 1, 3, 2 );

    assertNotNull( t1 );
    assertSame( t1, t2 );
}

像Side这样的类具有单个属性长度。然后实现equals()和hashCode()非常容易。然后,对您的长度参数进行排序/规范化,并以一致的方式放置/获取/检查它们。

static Map<Side, Map<Side, Map<Side, Triangle>>> triangles = new HashMap<Side, Map<Side, Map<Side, Triangle>>>();

public Triangle( final int x, final int y, final int z ) {
 // ...
}

public static Triangle create( final int x, final int y, final int z ) {
    final Side min = new Side( Math.min( Math.min( x, y ), z ) );
    final Side middle = new Side( Math.min( Math.max( x, y ), z ) );
    final Side max = new Side( Math.max( Math.max( x, y ), z ) );

    final Map<Side, Map<Side, Triangle>> middleMap;
    final Map<Side, Triangle> maxMap;
    if ( triangles.containsKey( min ) ) {
        middleMap = triangles.get( min );
    }
    else  {
        middleMap = new HashMap<Side, Map<Side, Triangle>>();
        triangles.put( min, middleMap );
    }
    if ( middleMap.containsKey( middle ) ) {
        maxMap = middleMap.get( middle );
    }
    else {
        final Triangle triangle = new Triangle( x, y, z );
        maxMap = new HashMap<Side, Triangle>();
        maxMap.put( max, triangle );
        middleMap.put( middle, maxMap );
        return triangle;
    }
    if ( maxMap.containsKey( max ) ) {
        return maxMap.get( max );
    }
    final Triangle triangle = new Triangle( x, y, z );
    maxMap.put( max, triangle );
    return triangle;
}

答案 8 :(得分:-1)

我读了你的other post并得到了你是一个新的java开发人员的印象,所以我发现需要提供一个正在运行的例子。 只需将其粘贴到IDE并运行即可。它应该运行并产生一个输出,这是一个概念证明。

我在这里使用的输入是

String[] input = new String[]{ "1,2,1" , 
                               "1,1,2", 
                               "1,2,3",
                               "1,3,1",
                               "1,1,1",
                               "1,3,3",
                               "1,1,3"};

正如你所看到的,你可以看到它有重复。 输出是

 The triangle [Triangle{sides=[1, 1, 2]}] already exists!
 The triangle [Triangle{sides=[1, 1, 3]}] already exists!
 triangles = [Triangle{sides=[1, 2, 3]}, 
              Triangle{sides=[1, 1, 3]}, 
              Triangle{sides=[1, 1, 2]}, 
              Triangle{sides=[1, 1, 1]}, 
              Triangle{sides=[1, 3, 3]}]

根据您的要求,输出没有重复。

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class Triangle
{
    private int[]sides;
    public Triangle( int x, int y, int z)
    {
        sides = new int[]{x,y,z};
        Arrays.sort( sides );
    }

    public Triangle( String ... args )
    {
        this( Integer.parseInt( args[0].trim() ), Integer.parseInt( args[1].trim() ), Integer.parseInt( args[2].trim() ));
    }

    @Override
    public boolean equals( Object o )
    {
        if ( this == o ) return true;
        if ( o == null || getClass() != o.getClass() ) return false;

        Triangle triangle = ( Triangle ) o;

        if ( !Arrays.equals( sides, triangle.sides ) ) return false;

        return true;
    }

    @Override
    public int hashCode()
    {
        return sides != null ? Arrays.hashCode( sides ) : 0;
    }

    @Override
    public String toString()
    {
        return "Triangle{" +
                       "sides=" + Arrays.toString( sides ) +
                       '}';
    }

    public static void main( String[] args ) throws IOException
    {

        String[] input = new String[]{ "1,2,1" , "1,1,2", "1,2,3","1,3,1","1,1,1","1,3,3","1,1,3"};

        Set<Triangle> triangles = new HashSet<Triangle>(  );
        for ( String s : input )
        {
            Triangle triangle = new Triangle( s.split( "," ) );
        if ( triangles.contains( triangle ))
        {
            System.out.println("The triangle [" + triangle + "] already exists!");
        }
        triangles.add( triangle );
        }
        System.out.println( "triangles = " + triangles );
    }
}