我正在尝试创建一个程序,其中 - 我尽可能简单地使用它 - 我找到了三角形的边。
这样做的问题是可能还有另一个三角形已经找到了完全相同的边。例如:
如果程序找到一个边长为1, 2, 1
而另一个带有1, 1, 2
的三角形,那么,由于我正在做的规则,我不需要再次使用这个三角形,因为它有同样的方面,只是以不同的顺序。
我想创建一个可以输入三角形值的类,例如= new triangle(x,y,z)
,其中x,y和z都是边的整数。
这不是问题,因为我已经上课了。问题是我如何检查三角形是否已经与我输入的边相同?
感谢。
答案 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)
@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 );
}
}