Suppose I have a Point class with fields x,y,z,name. Objects of this class must be inserted in a Hash Set in two different ways depending on the user choice:
So I wonder what is the better way to organize such equals() redefinition on the fly during program execution?
If you can change from using HashSet
to a TreeSet
and add a custom comparator:
public class Point implements Comparable<Point> {
private double x;
private double y;
private double z;
private String name;
public Point( final double x, final double y, final double z, final String name ) {
setX( x );
setY( y );
setZ( z );
setName( name );
}
public boolean equals( final Point point ){
final boolean isEqual =
( this.getX() == point.getX()
&& this.getY() == point.getY()
&& this.getZ() == point.getZ() )
|| ( this.getName().equals( point.getName() ) );
// System.out.println( this.toString() + " == " + point.toString() + " = " + isEqual );
return isEqual;
}
/// @return the x
public double getX() { return x; }
/// @return the y
public double getY() { return y; }
/// @return the z
public double getZ() { return z; }
/// @return the name
public String getName() { return name; }
/// @param x the x to set
public void setX(final double x) { this.x = x; }
/// @param y the y to set
public void setY(final double y) { this.y = y; }
/// @param z the z to set
public void setZ(final double z) { this.z = z; }
/// @param name the name to set
public void setName(final String name) { this.name = name; }
public String toString() {
final StringBuffer str = new StringBuffer();
str.append( '(' );
str.append( getX() );
str.append( ',' );
str.append( getY() );
str.append( ',' );
str.append( getZ() );
str.append( ',' );
str.append( getName() );
str.append( ')' );
return str.toString();
}
public double distanceFromOriginSquared(){
return this.getX()*this.getX()
+ this.getY()*this.getY()
+ this.getZ()*this.getZ();
}
@Override
public int compareTo( final Point point ) {
if ( this.getName().equals( point.getName() ) )
return 0;
final double td = this.distanceFromOriginSquared();
final double pd = point.distanceFromOriginSquared();
if ( td < pd ) return -1;
if ( td > pd ) return +1;
if ( this.getX() < point.getX() ) return -1;
if ( this.getX() > point.getX() ) return +1;
if ( this.getY() < point.getY() ) return -1;
if ( this.getY() > point.getY() ) return +1;
return 0;
}
}
Running this:
public static void main( final String[] args ){
Point[] pts = {
new Point( 1, 1, 1, "1" ),
new Point( 2, 2, 2, "2" ),
new Point( 3, 3, 3, "3" ),
new Point( 1, 1, 1, "4" ),
new Point( 4, 4, 4, "2" )
};
TreeSet<Point> ps = new TreeSet<Point>();
for ( Point p : pts )
ps.add( p );
System.out.println( ps );
}
Gives an output of
[(1.0,1.0,1.0,1), (2.0,2.0,2.0,2), (3.0,3.0,3.0,3)]
So the last two values are not entered into the TreeSet
as they are rejected by the comparator.