Implement equals and hashCode
csisy opened this issue · 3 comments
It would be nice if the equals
and hashCode
would be implemented especially for the CronDefinition
.
Example use case: We need to figure out if a given cron definition is one of the pre-defined ones (QUARTZ, for example). In the following code eq == false
, because the mentioned methods are not implemented at all.
final var a = instanceDefinitionFor(CronType.QUARTZ);
final var b = instanceDefinitionFor(CronType.QUARTZ);
final var eq = a.equals(b); // false
Or is there any other way to find whether a given cron definition matches another one?
@csisy thank you for using cron-utils, and the feedback provided. We will work on it. Contributions are always welcome! 😄 If you could provide some tests to highlight this functionality, we will be glad to merge them. Best!
Thank you for the library! :)
Didn't have the time to create it as a pull request, but the test code would be something like this:
package com.cronutils.model.definition;
// ...
public class CronDefinitionTest {
// ...
@ParameterizedTest
@EnumSource(CronType.class)
public void testBuiltInDefinitionsAreEqual(CronType cronType) {
final var definition1 = instanceDefinitionFor(cronType);
final var definition2 = instanceDefinitionFor(cronType);
assertEquals(definition1, definition2);
}
@Test
public void testCustomDefinitionEqualsToBuiltIn() {
final var builtIn = instanceDefinitionFor(CronType.QUARTZ);
final var custom = CronDefinitionBuilder.defineCron()
.withSeconds().withValidRange(0, 59).and()
.withMinutes().withValidRange(0, 59).and()
.withHours().withValidRange(0, 23).and()
.withDayOfMonth().withValidRange(1, 31).supportsL().supportsW().supportsLW().supportsQuestionMark().and()
.withMonth().withValidRange(1, 12).and()
.withDayOfWeek().withValidRange(1, 7).withMondayDoWValue(2).supportsHash().supportsL().supportsQuestionMark().and()
.withYear().withValidRange(1970, 2099).withStrictRange().optional().and()
.withCronValidation(CronConstraintsFactory.ensureEitherDayOfWeekOrDayOfMonth())
.instance();
assertEquals(builtIn, custom);
}
Implementing equals
and hashCode
can be a bit tricky however, not sure what would be the correct implementation.
Instead of implementing equals
and hashCode
on the CronDefinition
itself, a helper method could be created, something like boolean isDefinitionOf(CronType cronType)
, maybe on the CronDefinition
itself.
@ParameterizedTest
@EnumSource(CronType.class)
public void testWhetherBuiltInOrNot(CronType cronType) {
final var definition = instanceDefinitionFor(cronType);
assertTrue(definition.isDefinitionOf(cronType));
}
Without equals
, its implementation would be redundant with the definition itself. However, we could make the built-in definitions singletons and a simple reference equals would be enough in this case. Another option would be a package-private CronDefinition
constructor that has an additional CronType
parameter. When a built-in instanceDefinitionFor
is used, it could pass the appropriate CronType
to the constructor.
However, none of these would work with custom-built cron definitions that are actually equal to one of the built-in definition, but since it's built by the user code, the above methods would not work properly. This is not a use-case for us, but added for the sake of completeness.
The use-case is that we'd like to store some data that contains a CronDefinition
. The data must be serialized (into a string) and it would be nice if the serialized data would only contain "QUARTZ"
instead of the fully serialized CronDefinition
object, since we can easily restore a CronDefinition
from a name (using instanceDefinitionFor
).
What do you think, what would be an easy way to determine whether a CronDefinition
is a built-in one or not? Or better, how to serialize (and deserialize) a built-in CronDefinition
in a more compact way?
Thanks