How to check whether a String is eligible Palindrome or not?

This is the complete solution to check whether a given String is eligible for a Palindrome or not. This solution is designed to solve the problem using an interface, super class and three derived classes implementing the interface.

package pack1;

public interface EligiblePalindromeIntf {

	/* Define the functional interface with SAM 'RdInput' */
	public Boolean RdInput(String strInpVal);

	/* Define the static method 'displayMsg' */
	static void displayMsg(String strInpVal, boolean isEligible) {

		String res = isEligible ? "" : "Not ";
		System.out.println("The String " + strInpVal + " can " + res + "become a Palindrome");

		System.out.println();
	}
}
package pack1;

import java.util.HashMap;
import java.util.Optional;
import java.util.logging.Logger;

class InputTheString {

	private String inputStringValue;

	/* Declare the logger object for the class to display the log messages */
	static Logger logger = Logger.getLogger(InputTheString.class.getName());

	public boolean validateInputs(String inputStringValue) {

		/* Fetch the class object's name from which this method is called */
		String cName = Thread.currentThread().getStackTrace()[2].getClassName();
		String mName = "validateInputs()";
		logger.info("This method '" + mName + "' called from the Class '" + cName + "'");

		/* Validating the function parameters using Optional Integer Array data type */
		Optional<String> inputVal = Optional.ofNullable(inputStringValue);

		/*
		 * Fetch the value of the Optional Integer inputStringValue using 'isPresent'
		 * condition check. If the value is available use 'get' method otherwise simply
		 * return 'false' to stop the program execution without proceeding further.
		 */
		if (inputVal.isPresent()) {
			setInputStringValue(inputVal.get());
			System.out.println("The given input String is " + getInputStringValue());
		} else
			return false;

		logger.info("The provided Input validated Successfully");
		return true;
	}

	/* Define getter and setters for an inputStringValue String variable */
	public String getInputStringValue() {
		return inputStringValue;
	}

	public void setInputStringValue(String inputStringValue) {
		this.inputStringValue = inputStringValue;
	}

}

class PalindromEligibility_Using_CoreLogic extends InputTheString implements EligiblePalindromeIntf {

	public Boolean RdInput(String palinStr) {

		/* Fetch the class object's name from which this method is called */
		String cName = Thread.currentThread().getStackTrace()[2].getClassName();
		String mName = "RdInput";
		logger.info("This method '" + mName + "' called from the Class '" + cName + "'");

		/*
		 * Initialize isEligibleForPalindrome to false , and HashMap of Character and
		 * Integer
		 */
		boolean isEligibleForPalindrome = false;
		HashMap<Character, Integer> hmCharsCount = new HashMap<Character, Integer>();

		if (validateInputs(palinStr)) {

			// Use the Hash Map collection to find the count each character occurrences
			for (int i = 0; i < getInputStringValue().length(); i++)
				if (!hmCharsCount.containsKey(getInputStringValue().charAt(i)))
					hmCharsCount.put(getInputStringValue().charAt(i), 1);
				else
					hmCharsCount.put(getInputStringValue().charAt(i),
							hmCharsCount.get(getInputStringValue().charAt(i)) + 1);

			System.out.println("The Hashmap of each character occurences are: " + hmCharsCount);

			Character[] charKeys = new Character[hmCharsCount.size()];
			int[] charCnts = new int[hmCharsCount.size()];
			int i = 0;

			// Separate the Character keys and their respective counts into separate arrays
			for (HashMap.Entry<Character, Integer> entry : hmCharsCount.entrySet()) {
				charKeys[i] = entry.getKey();
				charCnts[i++] = entry.getValue();
			}
			for (i = 0; i < hmCharsCount.size(); i++)
				System.out.println(
						"The respective Character key=" + charKeys[i] + " and number of occurances is=" + charCnts[i]);

			// Get the odd Character counts and even Character Counts
			int oddCntOfChars = 0, evnCntOfChars = 0;
			for (int k = 0; k < charCnts.length; k++) {

				if (charCnts[k] % 2 == 0)
					evnCntOfChars++;
				else
					oddCntOfChars++;
			}
			System.out.println("The Even count of Character keys are=" + evnCntOfChars);
			System.out.println("The Odd count of Character keys are=" + oddCntOfChars);

			/*
			 * There must be one and only one character key in the input string with odd
			 * number of times. Any number of character keys with even number of count are
			 * allowed. Hence the, below condition check is the eligibility criteria to form
			 * the successful Palindrome
			 */

			if (oddCntOfChars <= 1)
				isEligibleForPalindrome = true;
		} else
			logger.info("The given Input number is null");

		EligiblePalindromeIntf.displayMsg(palinStr, isEligibleForPalindrome);
		return isEligibleForPalindrome;
	}
}

class PalindromEligibility_Using_Hashmap extends InputTheString implements EligiblePalindromeIntf {

	public Boolean RdInput(String palinStr) {

		/* Fetch the class object's name from which this method is called */
		String cName = Thread.currentThread().getStackTrace()[2].getClassName();
		String mName = "RdInput";
		logger.info("This method '" + mName + "' called from the Class '" + cName + "'");

		/*
		 * Initialize isEligibleForPalindrome to false , and HashMap of Character and
		 * Integer
		 */
		boolean isEligibleForPalindrome = false;
		HashMap<Character, Integer> hmCharsCount = new HashMap<Character, Integer>();

		if (validateInputs(palinStr)) {

			/*
			 * Add each character occurrence of the string to the Hash map, If same
			 * character appears delete it from the Hash map, continue this process until
			 * the entire input string processed
			 */
			for (int i = 0; i < getInputStringValue().length(); i++)
				if (!hmCharsCount.containsKey(getInputStringValue().charAt(i)))
					hmCharsCount.put(getInputStringValue().charAt(i), 1);
				else
					hmCharsCount.remove(getInputStringValue().charAt(i));

			/*
			 * As per the logic Hash map must contains 0 or 1 character, to form the
			 * Palindrome string from the given string
			 */
			if (hmCharsCount.size() <= 1)
				isEligibleForPalindrome = true;
		} else
			logger.info("The given Input number is null");

		EligiblePalindromeIntf.displayMsg(palinStr, isEligibleForPalindrome);
		return isEligibleForPalindrome;
	}
}

class PalindromEligibility_Using_StringBuffer extends InputTheString implements EligiblePalindromeIntf {

	public Boolean RdInput(String palinStr) {

		/* Fetch the class object's name from which this method is called */
		String cName = Thread.currentThread().getStackTrace()[2].getClassName();
		String mName = "RdInput";
		logger.info("This method '" + mName + "' called from the Class '" + cName + "'");

		/* Initialize isEligibleForPalindrome , and an Empty StringBuffer */
		boolean isEligibleForPalindrome = false;
		StringBuffer targetStr = new StringBuffer("");

		if (validateInputs(palinStr)) {

			/*
			 * Add each character of the string to the String Buffer, If same character
			 * appears again delete from the String Buffer, continue this process until the
			 * entire input string processed
			 */
			for (int i = 0; i < palinStr.length(); i++) {
				int indexVal = targetStr.indexOf(String.valueOf(getInputStringValue().charAt(i)));
				if (indexVal >= 0)
					targetStr.deleteCharAt(indexVal);
				else
					targetStr.append(getInputStringValue().charAt(i));
			}
			/*
			 * As per the logic String Buffer must contains 0 or 1 character, to form the
			 * Palindrome string from the given string
			 */
			if (targetStr.length() <= 1)
				isEligibleForPalindrome = true;
		} else
			logger.info("The given Input number is null");

		EligiblePalindromeIntf.displayMsg(getInputStringValue(), isEligibleForPalindrome);
		return isEligibleForPalindrome;
	}
}

public class EligiblePalindromeJ8 {

	public static void main(String args[]) {

		/*
		 * create the class object PalindromEligibility_Using_CoreLogic, and call the
		 * method RdInput
		 */

		PalindromEligibility_Using_CoreLogic PEUCL = new PalindromEligibility_Using_CoreLogic();
		PEUCL.RdInput("bbbbaaac");
		PEUCL.RdInput(null);

		/*
		 * create the class object PalindromEligibility_Using_Hashmap, and call the
		 * method RdInput
		 */

		PalindromEligibility_Using_Hashmap PEUCHM = new PalindromEligibility_Using_Hashmap();
		PEUCHM.RdInput("bbbbaac");
		PEUCHM.RdInput(null);

		/*
		 * create the class object PalindromEligibility_Using_Hashmap, and call the
		 * method RdInput
		 */

		PalindromEligibility_Using_StringBuffer PEUCSB = new PalindromEligibility_Using_StringBuffer();
		PEUCSB.RdInput("kkllpphhh");
		PEUCSB.RdInput(null);

	}
}
OUTPUT:
Apr 09, 2023 3:22:10 PM pack1.PalindromEligibility_Using_CoreLogic RdInput
INFO: This method 'RdInput' called from the Class 'pack1.EligiblePalindromeJ8'
Apr 09, 2023 3:22:10 PM pack1.InputTheString validateInputs
INFO: This method 'validateInputs()' called from the Class 'pack1.PalindromEligibility_Using_CoreLogic'
The given input String is bbbbaaac
Apr 09, 2023 3:22:10 PM pack1.InputTheString validateInputs
INFO: The provided Input validated Successfully
The Hashmap of each character occurences are: {a=3, b=4, c=1}
The respective Character key=a and number of occurances is=3
The respective Character key=b and number of occurances is=4
The respective Character key=c and number of occurances is=1
The Even count of Character keys are=1
The Odd count of Character keys are=2
The String bbbbaaac can Not become a Palindrome

Apr 09, 2023 3:22:10 PM pack1.PalindromEligibility_Using_CoreLogic RdInput
INFO: This method 'RdInput' called from the Class 'pack1.EligiblePalindromeJ8'
Apr 09, 2023 3:22:10 PM pack1.InputTheString validateInputs
INFO: This method 'validateInputs()' called from the Class 'pack1.PalindromEligibility_Using_CoreLogic'
Apr 09, 2023 3:22:10 PM pack1.PalindromEligibility_Using_CoreLogic RdInput
INFO: The given Input number is null
The String null can Not become a Palindrome

Apr 09, 2023 3:22:10 PM pack1.PalindromEligibility_Using_Hashmap RdInput
INFO: This method 'RdInput' called from the Class 'pack1.EligiblePalindromeJ8'
Apr 09, 2023 3:22:10 PM pack1.InputTheString validateInputs
INFO: This method 'validateInputs()' called from the Class 'pack1.PalindromEligibility_Using_Hashmap'
The given input String is bbbbaac
Apr 09, 2023 3:22:10 PM pack1.InputTheString validateInputs
INFO: The provided Input validated Successfully
The String bbbbaac can become a Palindrome

Apr 09, 2023 3:22:10 PM pack1.PalindromEligibility_Using_Hashmap RdInput
INFO: This method 'RdInput' called from the Class 'pack1.EligiblePalindromeJ8'
Apr 09, 2023 3:22:10 PM pack1.InputTheString validateInputs
INFO: This method 'validateInputs()' called from the Class 'pack1.PalindromEligibility_Using_Hashmap'
Apr 09, 2023 3:22:10 PM pack1.PalindromEligibility_Using_Hashmap RdInput
INFO: The given Input number is null
The String null can Not become a Palindrome

Apr 09, 2023 3:22:10 PM pack1.PalindromEligibility_Using_StringBuffer RdInput
INFO: This method 'RdInput' called from the Class 'pack1.EligiblePalindromeJ8'
Apr 09, 2023 3:22:10 PM pack1.InputTheString validateInputs
INFO: This method 'validateInputs()' called from the Class 'pack1.PalindromEligibility_Using_StringBuffer'
The given input String is kkllpphhh
Apr 09, 2023 3:22:10 PM pack1.InputTheString validateInputs
INFO: The provided Input validated Successfully
The String kkllpphhh can become a Palindrome

Apr 09, 2023 3:22:10 PM pack1.PalindromEligibility_Using_StringBuffer RdInput
INFO: This method 'RdInput' called from the Class 'pack1.EligiblePalindromeJ8'
Apr 09, 2023 3:22:10 PM pack1.InputTheString validateInputs
INFO: This method 'validateInputs()' called from the Class 'pack1.PalindromEligibility_Using_StringBuffer'
Apr 09, 2023 3:22:10 PM pack1.PalindromEligibility_Using_StringBuffer RdInput
INFO: The given Input number is null
The String kkllpphhh can Not become a Palindrome

The link to the JUnit5 test for this solution is here – https://atomic-temporary-185308886.wpcomstaging.com/2023/04/10/junit-test-eligible-for-palindrome/