Added equals/hashCode contract to Vector2D/Vector3D
This commit is contained in:
parent
2144c6382c
commit
2ddf9fcd4e
@ -24,6 +24,19 @@ public interface Vector2D : Point<Double>, Vector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override operator fun iterator(): Iterator<Double> = listOf(x, y).iterator()
|
override operator fun iterator(): Iterator<Double> = listOf(x, y).iterator()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether some other vector is "equal to" this one.
|
||||||
|
* Any [Vector3D] is considered equal, if it contains the same components.
|
||||||
|
*/
|
||||||
|
override fun equals(other: Any?): Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a hash code value for this vector.
|
||||||
|
* The hash code is generated as if all the input values were placed into
|
||||||
|
* a list, and that list were hashed by calling `listOf(x, y).hashCode()`.
|
||||||
|
*/
|
||||||
|
override fun hashCode(): Int
|
||||||
}
|
}
|
||||||
|
|
||||||
public val Vector2D.r: Double
|
public val Vector2D.r: Double
|
||||||
@ -35,7 +48,16 @@ public fun Vector2D(x: Double, y: Double): Vector2D = Vector2DImpl(x, y)
|
|||||||
private data class Vector2DImpl(
|
private data class Vector2DImpl(
|
||||||
override val x: Double,
|
override val x: Double,
|
||||||
override val y: Double,
|
override val y: Double,
|
||||||
) : Vector2D
|
) : Vector2D {
|
||||||
|
|
||||||
|
override fun equals(other: Any?) = when (other) {
|
||||||
|
this -> true
|
||||||
|
is Vector2D -> x == other.x && y == other.y
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int = listOf(x, y).hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 2D Euclidean space
|
* 2D Euclidean space
|
||||||
|
@ -26,6 +26,19 @@ public interface Vector3D : Point<Double>, Vector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override operator fun iterator(): Iterator<Double> = listOf(x, y, z).iterator()
|
override operator fun iterator(): Iterator<Double> = listOf(x, y, z).iterator()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether some other vector is "equal to" this one.
|
||||||
|
* Any [Vector3D] is considered equal, if it contains the same components.
|
||||||
|
*/
|
||||||
|
override fun equals(other: Any?): Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a hash code value for this vector.
|
||||||
|
* The hash code is generated as if all the input values were placed into
|
||||||
|
* a list, and that list were hashed by calling `listOf(x, y, z).hashCode()`.
|
||||||
|
*/
|
||||||
|
override fun hashCode(): Int
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("FunctionName")
|
@Suppress("FunctionName")
|
||||||
@ -37,7 +50,16 @@ private data class Vector3DImpl(
|
|||||||
override val x: Double,
|
override val x: Double,
|
||||||
override val y: Double,
|
override val y: Double,
|
||||||
override val z: Double,
|
override val z: Double,
|
||||||
) : Vector3D
|
) : Vector3D {
|
||||||
|
|
||||||
|
override fun equals(other: Any?) = when (other) {
|
||||||
|
this -> true
|
||||||
|
is Vector3D -> x == other.x && y == other.y && z == other.z
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode() = listOf(x, y, z).hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
public object Euclidean3DSpace : GeometrySpace<Vector3D>, ScaleOperations<Vector3D> {
|
public object Euclidean3DSpace : GeometrySpace<Vector3D>, ScaleOperations<Vector3D> {
|
||||||
override val zero: Vector3D by lazy { Vector3D(0.0, 0.0, 0.0) }
|
override val zero: Vector3D by lazy { Vector3D(0.0, 0.0, 0.0) }
|
||||||
|
@ -37,4 +37,54 @@ internal class Vector2DTest {
|
|||||||
fun y() {
|
fun y() {
|
||||||
assertEquals(-7.999, vector.y)
|
assertEquals(-7.999, vector.y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun equality() {
|
||||||
|
val vector2 = AlternativeVector2D(1.0, -7.999)
|
||||||
|
|
||||||
|
// reflexive
|
||||||
|
assertEquals(vector, vector)
|
||||||
|
assertEquals(vector2, vector2)
|
||||||
|
|
||||||
|
// symmetric
|
||||||
|
assertEquals(vector, vector2)
|
||||||
|
assertEquals(vector2, vector)
|
||||||
|
|
||||||
|
// transitive
|
||||||
|
val vector3 = AlternativeVector2D(1.0, -7.999)
|
||||||
|
assertEquals(vector, vector2)
|
||||||
|
assertEquals(vector2, vector3)
|
||||||
|
assertEquals(vector3, vector)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun hash() {
|
||||||
|
val vector2 = AlternativeVector2D(1.0, -7.999)
|
||||||
|
|
||||||
|
assertEquals(vector, vector2)
|
||||||
|
assertEquals(vector.hashCode(), vector2.hashCode())
|
||||||
|
}
|
||||||
|
|
||||||
|
private data class AlternativeVector2D(
|
||||||
|
override val x: Double,
|
||||||
|
override val y: Double,
|
||||||
|
) : Vector2D {
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other == null || other !is Vector2D) return false
|
||||||
|
|
||||||
|
if (x != other.x) return false
|
||||||
|
if (y != other.y) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = 1
|
||||||
|
result = 31 * result + x.hashCode()
|
||||||
|
result = 31 * result + y.hashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,4 +43,57 @@ internal class Vector3DTest {
|
|||||||
fun z() {
|
fun z() {
|
||||||
assertEquals(0.001, vector.z)
|
assertEquals(0.001, vector.z)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun equality() {
|
||||||
|
val vector2 = AlternativeVector3D(1.0, -7.999, 0.001)
|
||||||
|
|
||||||
|
// reflexive
|
||||||
|
assertEquals(vector, vector)
|
||||||
|
assertEquals(vector2, vector2)
|
||||||
|
|
||||||
|
// symmetric
|
||||||
|
assertEquals(vector, vector2)
|
||||||
|
assertEquals(vector2, vector)
|
||||||
|
|
||||||
|
// transitive
|
||||||
|
val vector3 = AlternativeVector3D(1.0, -7.999, 0.001)
|
||||||
|
assertEquals(vector, vector2)
|
||||||
|
assertEquals(vector2, vector3)
|
||||||
|
assertEquals(vector3, vector)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun hash() {
|
||||||
|
val vector2 = AlternativeVector3D(1.0, -7.999, 0.001)
|
||||||
|
|
||||||
|
assertEquals(vector, vector2)
|
||||||
|
assertEquals(vector.hashCode(), vector2.hashCode())
|
||||||
|
}
|
||||||
|
|
||||||
|
private data class AlternativeVector3D(
|
||||||
|
override val x: Double,
|
||||||
|
override val y: Double,
|
||||||
|
override val z: Double,
|
||||||
|
) : Vector3D {
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other == null || other !is Vector3D) return false
|
||||||
|
|
||||||
|
if (x != other.x) return false
|
||||||
|
if (y != other.y) return false
|
||||||
|
if (z != other.z) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = 1
|
||||||
|
result = 31 * result + x.hashCode()
|
||||||
|
result = 31 * result + y.hashCode()
|
||||||
|
result = 31 * result + z.hashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user