I came across this below code in my code base where we just want to toggle the enum value. If it is DEBIT return CREDIT, if CREDIT return DEBIT like below.
This method is excellent and works as expected.
enum DebitCreditCode implements Toggleable<DebitCreditCode> { DEBIT, CREDIT
}
public static DebitCreditCode getReverseOfPaymentDebitCreditCode(DebitCreditCode debitOrCreditFromSummary) { if (debitOrCreditFromSummary != null && debitOrCreditFromSummary .equals(DebitCreditCode.CREDIT)) { return DebitCreditCode.DEBIT; } else if (debitOrCreditFromSummary != null && debitOrCreditFromSummary .equals(DebitCreditCode.DEBIT)) { return DebitCreditCode.CREDIT; } return null; }
This method is excellent and works as expected.
But…
If we want such requirement for any other enum,
If we want such requirement for any other enum,
- we have to define similar utility method for each enum and it is a repetitive job
- we will be landed up with duplicate code
Step – 1 : Define this below interface in your common module. This is a one time job.
interface Toggleable<T extends Enum<T>> { default T toggle() { final T[] enumConstants = (T[]) this.getClass().getEnumConstants(); if (enumConstants == null) { throw new UnsupportedOperationException("Only enum can support toggling"); } if (enumConstants.length != 2) { throw new UnsupportedOperationException("Enum must have 2 objects to support toggling"); } return enumConstants[0] == this ? enumConstants[1] : enumConstants[0]; } }
Step – 2 : Just implement the above interface to your enum class where you want this toggle/reverse feature like below :
enum DebitCreditCode implements Toggleable<DebitCreditCode> { DEBIT, CREDIT
}
Step – 3 : Call method toggle() on the enum object like
final DebitCreditCode toggled = DebitCreditCode.DEBIT.toggle(); Assert.assertEquals(DebitCreditCode.CREDIT, toggled); final DebitCreditCode original = toggled.toggle(); Assert.assertEquals(DebitCreditCode.DEBIT, original);
Find complete code here