Algoritmo palindromo e test JUnit 5

Aug 27 2020

Ho una classe "Palindrome" che ha alcune funzioni per verificare se certe cose sono palindromi. Per la verifica, ho 2 diversi algoritmi, uno ricorsivo e l'altro iterativo.

Sono soddisfatto degli algoritmi, tuttavia non sono sicuro che il modo in cui eseguo il sovraccarico e alla fine analizzi tutto alla funzione check charArray sia una cosa intelligente.

Ho anche alcuni test Junit 5 che dimostrano che tutto funziona. Qui non sono sicuro che sia un buon codice con i nidi multipli e i metodi/test che ho scelto e se praticamente avere un codice duplicato per l'algoritmo iterativo e ricorsivo sia buono. Grazie in anticipo.

Classe palindromo

package com.gr;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Lucifer Uchiha
 * @version 1.0
 */
public class Palindrome {

    /* Iterative */

    /**
     * Returns a boolean of whether the char array is a palindrome or not.
     * This is determined by using the iterative algorithm.
     *
     * @param chars char array containing the characters to be checked.
     * @return boolean of whether the char array is a palindrome or not.
     */
    public static boolean isCharArrayPalindromeIterative(char[] chars) {
        if (chars.length < 1)
            return false;
        char[] formattedChars = convertAllCharsToUpperCase(chars);
        boolean isPalindrome = true;
        for (int i = 0; i != formattedChars.length / 2; i++)
            if (formattedChars[i] != formattedChars[(formattedChars.length - 1) - i]) {
                isPalindrome = false;
                break;
            }
        return isPalindrome;
    }

    /**
     * Returns a boolean of whether the word of type String is a palindrome or not.
     * This is determined by using the iterative algorithm.
     *
     * @param word the word to be checked.
     * @return boolean of whether the word is a palindrome or not.
     */
    public static boolean isWordPalindromeIterative(String word) {
        return isCharArrayPalindromeIterative(word.toCharArray());
    }

    /**
     * Returns a boolean of whether the sentence of type String is a palindrome or not.
     * This is determined by using the iterative algorithm.
     *
     * @param sentence the sentence to be checked.
     * @return boolean of whether the sentence is a palindrome or not.
     */
    public static boolean isSentencePalindromeIterative(String sentence) {
        String newSentence = sentence.replaceAll("[^a-zA-Z]", "");
        return isWordPalindromeIterative(newSentence);
    }

    /**
     * Returns a boolean of whether the number of type byte (-128 to 127) is a palindrome or not.
     * This is determined by using the iterative algorithm.
     *
     * @param number the number to be checked.
     * @return boolean of whether the number is a palindrome or not.
     */
    public static boolean isNumberPalindromeIterative(byte number) {
        return isWordPalindromeIterative(String.valueOf(number));
    }

    /**
     * Returns a boolean of whether the number of type short (32,768 to 32,767) is a palindrome or not.
     * This is determined by using the iterative algorithm.
     *
     * @param number the number to be checked.
     * @return boolean of whether the number is a palindrome or not.
     */
    public static boolean isNumberPalindromeIterative(short number) {
        return isWordPalindromeIterative(String.valueOf(number));
    }

    /**
     * Returns a boolean of whether the number of type int (-2,147,483,648 to 2,147,483,647) is a palindrome or not.
     * This is determined by using the iterative algorithm.
     *
     * @param number the number to be checked.
     * @return boolean of whether the number is a palindrome or not.
     */
    public static boolean isNumberPalindromeIterative(int number) {
        return isWordPalindromeIterative(String.valueOf(number));
    }

    /**
     * Returns a boolean of whether the number of type long (-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807) is a palindrome or not.
     * This is determined by using the iterative algorithm.
     *
     * @param number the number to be checked.
     * @return boolean of whether the number is a palindrome or not.
     */
    public static boolean isNumberPalindromeIterative(long number) {
        return isWordPalindromeIterative(String.valueOf(number));
    }

    /**
     * Returns a List containing all the numbers that are palindromes in the range that is given from
     * start of type long to end of type long.
     * This is determined by using the iterative algorithm.
     *
     * @param start the start of the range, inclusive.
     * @param end   the end of the range, exclusive.
     * @return List containing all the numbers that are palindromes in the given range.
     */
    public static List<Long> getAllNumberPalindromesInRangeIterative(long start, long end) {
        List<Long> results = new ArrayList<>();
        for (long number = start; number != end; number++)
            if (isNumberPalindromeIterative(number))
                results.add(number);
        return results;
    }

    /**
     * Returns a List containing all the numbers that are palindromes in the range that is given from
     * start of type int to end of type int.
     * This is determined by using the iterative algorithm.
     *
     * @param start the start of the range, inclusive.
     * @param end   the end of the range, exclusive.
     * @return List containing all the numbers that are palindromes in the given range.
     */
    public static List<Integer> getAllNumberPalindromesInRangeIterative(int start, int end) {
        return convertLongListToIntegerList(getAllNumberPalindromesInRangeIterative((long) start, (long) end));
    }

    /**
     * Returns a List containing all the numbers that are palindromes in the range that is given from
     * start of type short to end of type short.
     * This is determined by using the iterative algorithm.
     *
     * @param start the start of the range, inclusive.
     * @param end   the end of the range, exclusive.
     * @return List containing all the numbers that are palindromes in the given range.
     */
    public static List<Short> getAllNumberPalindromesInRangeIterative(short start, short end) {
        return convertLongListToShortList(getAllNumberPalindromesInRangeIterative((long) start, (long) end));
    }

    /**
     * Returns a List containing all the numbers that are palindromes in the range that is given from
     * start of type byte to end of type byte.
     * This is determined by using the iterative algorithm.
     *
     * @param start the start of the range, inclusive.
     * @param end   the end of the range, exclusive.
     * @return List containing all the numbers that are palindromes in the given range.
     */
    public static List<Byte> getAllNumberPalindromesInRangeIterative(byte start, byte end) {
        return convertLongListToByteList(getAllNumberPalindromesInRangeIterative((long) start, (long) end));
    }

    /* Recursive */

    /**
     * Returns a boolean of whether the char array is a palindrome or not.
     * This is determined by using the recursive algorithm.
     *
     * @param chars char array containing the characters to be checked.
     * @return boolean of whether the char array is a palindrome or not.
     */
    public static boolean isCharArrayPalindromeRecursive(char[] chars) {
        if (chars.length < 1)
            return false;
        char[] formattedChars = convertAllCharsToUpperCase(chars);
        return recursion(formattedChars, 0, formattedChars.length - 1);
    }

    /**
     * The recursive algorithm.
     *
     * @param chars char array containing the characters to be checked.
     * @param start the left char being compared.
     * @param end   the right char being compared.
     * @return boolean of whether the char array is a palindrome or not.
     */
    private static boolean recursion(char[] chars, int start, int end) {
        if (start == end)
            return true;
        if (chars[start] != chars[end])
            return false;
        if (start < end + 1)
            return recursion(chars, ++start, --end);
        return true;
    }

    /**
     * Returns a boolean of whether the word of type String is a palindrome or not.
     * This is determined by using the recursive algorithm.
     *
     * @param word the word to be checked.
     * @return boolean of whether the word is a palindrome or not.
     */
    public static boolean isWordPalindromeRecursive(String word) {
        return isCharArrayPalindromeRecursive(word.toCharArray());
    }

    /**
     * Returns a boolean of whether the sentence of type String is a palindrome or not.
     * This is determined by using the recursive algorithm.
     *
     * @param sentence the sentence to be checked.
     * @return boolean of whether the sentence is a palindrome or not.
     */
    public static boolean isSentencePalindromeRecursive(String sentence) {
        String newSentence = sentence.replaceAll("[^a-zA-Z]", "");
        return isWordPalindromeRecursive(newSentence);
    }

    /**
     * Returns a boolean of whether the number of type byte (-128 to 127) is a palindrome or not.
     * This is determined by using the recursive algorithm.
     *
     * @param number the number to be checked.
     * @return boolean of whether the number is a palindrome or not.
     */
    public static boolean isNumberPalindromeRecursive(byte number) {
        return isWordPalindromeRecursive(String.valueOf(number));
    }

    /**
     * Returns a boolean of whether the number of type short (32,768 to 32,767) is a palindrome or not.
     * This is determined by using the recursive algorithm.
     *
     * @param number the number to be checked.
     * @return boolean of whether the number is a palindrome or not.
     */
    public static boolean isNumberPalindromeRecursive(short number) {
        return isWordPalindromeRecursive(String.valueOf(number));
    }

    /**
     * Returns a boolean of whether the number of type int (-2,147,483,648 to 2,147,483,647) is a palindrome or not.
     * This is determined by using the recursive algorithm.
     *
     * @param number the number to be checked.
     * @return boolean of whether the number is a palindrome or not.
     */
    public static boolean isNumberPalindromeRecursive(int number) {
        return isWordPalindromeRecursive(String.valueOf(number));
    }

    /**
     * Returns a boolean of whether the number of type long (-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807) is a palindrome or not.
     * This is determined by using the recursive algorithm.
     *
     * @param number the number to be checked.
     * @return boolean of whether the number is a palindrome or not.
     */
    public static boolean isNumberPalindromeRecursive(long number) {
        return isWordPalindromeRecursive(String.valueOf(number));
    }

    /**
     * Returns a List containing all the numbers that are palindromes in the range that is given from
     * start of type long to end of type long.
     * This is determined by using the recursive algorithm.
     *
     * @param start the start of the range, inclusive.
     * @param end   the end of the range, exclusive.
     * @return List containing all the numbers that are palindromes in the given range.
     */
    public static List<Long> getAllNumberPalindromesInRangeRecursive(long start, long end) {
        List<Long> results = new ArrayList<>();
        for (long number = start; number != end; number++)
            if (isNumberPalindromeRecursive(number))
                results.add(number);
        return results;
    }

    /**
     * Returns a List containing all the numbers that are palindromes in the range that is given from
     * start of type int to end of type int.
     * This is determined by using the recursive algorithm.
     *
     * @param start the start of the range, inclusive.
     * @param end   the end of the range, exclusive.
     * @return List containing all the numbers that are palindromes in the given range.
     */
    public static List<Integer> getAllNumberPalindromesInRangeRecursive(int start, int end) {
        return convertLongListToIntegerList(getAllNumberPalindromesInRangeRecursive((long) start, (long) end));
    }

    /**
     * Returns a List containing all the numbers that are palindromes in the range that is given from
     * start of type short to end of type short.
     * This is determined by using the recursive algorithm.
     *
     * @param start the start of the range, inclusive.
     * @param end   the end of the range, exclusive.
     * @return List containing all the numbers that are palindromes in the given range.
     */
    public static List<Short> getAllNumberPalindromesInRangeRecursive(short start, short end) {
        return convertLongListToShortList(getAllNumberPalindromesInRangeRecursive((long) start, (long) end));
    }

    /**
     * Returns a List containing all the numbers that are palindromes in the range that is given from
     * start of type byte to end of type byte.
     * This is determined by using the recursive algorithm.
     *
     * @param start the start of the range, inclusive.
     * @param end   the end of the range, exclusive.
     * @return List containing all the numbers that are palindromes in the given range.
     */
    public static List<Byte> getAllNumberPalindromesInRangeRecursive(byte start, byte end) {
        return convertLongListToByteList(getAllNumberPalindromesInRangeRecursive((long) start, (long) end));
    }

    /**
     * Converts all letters in the given char array to capital letters if they aren't already.
     *
     * @param chars the start of the range, inclusive.
     * @return char array with the capitalized letters.
     */
    private static char[] convertAllCharsToUpperCase(char[] chars) {
        char[] formattedChars = new char[chars.length];
        for (int i = 0; i != chars.length; i++)
            if (Character.isLetter(chars[i]) && Character.isLowerCase(chars[i]))
                formattedChars[i] = Character.toUpperCase(chars[i]);
            else
                formattedChars[i] = chars[i];
        return formattedChars;
    }

    /**
     * Converts a List containing Long values to a List of Bytes.
     *
     * @param listOfLongs the List containing the Long values
     * @return the List containing the Byte values
     */
    private static List<Byte> convertLongListToByteList(List<Long> listOfLongs) {
        List<Byte> result = new ArrayList<>();
        for (Long i : listOfLongs)
            result.add(i.byteValue());
        return result;
    }

    /**
     * Converts a List containing Long values to a List of Shorts.
     *
     * @param listOfLongs the List containing the Long values
     * @return the List containing the Shorts values
     */
    private static List<Short> convertLongListToShortList(List<Long> listOfLongs) {
        List<Short> result = new ArrayList<>();
        for (Long i : listOfLongs)
            result.add(i.shortValue());
        return result;
    }

    /**
     * Converts a List containing Long values to a List of Integers.
     *
     * @param listOfLongs the List containing the Long values
     * @return the List containing the Integers values
     */
    private static List<Integer> convertLongListToIntegerList(List<Long> listOfLongs) {
        List<Integer> result = new ArrayList<>();
        for (Long i : listOfLongs)
            result.add(i.intValue());
        return result;
    }
}

Classe di test palindromo

package com.gr;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

@DisplayName("Palindrome Class")
public class PalindromeTest {

    // Nested Iterative
    @Nested
    class Iterative {

        @Nested
        class Word {

            @Test
            void testEmptyString() {
                assertFalse(Palindrome.isWordPalindromeIterative(""));
            }

            @Test
            void testSingleLetter() {
                assertTrue(Palindrome.isWordPalindromeIterative("A"));
                assertTrue(Palindrome.isWordPalindromeIterative("a"));
            }

            @Test
            void testName() {
                assertTrue(Palindrome.isWordPalindromeIterative("ABBA"));
                assertTrue(Palindrome.isWordPalindromeIterative("Ava"));
                assertTrue(Palindrome.isWordPalindromeIterative("bob"));
                assertFalse(Palindrome.isWordPalindromeIterative("FAIL"));
                assertFalse(Palindrome.isWordPalindromeIterative("Fail"));
                assertFalse(Palindrome.isWordPalindromeIterative("fail"));
            }

            @Test
            void testWord() {
                assertTrue(Palindrome.isWordPalindromeIterative("madam"));
                assertTrue(Palindrome.isWordPalindromeIterative("Racecar"));
                assertTrue(Palindrome.isWordPalindromeIterative("RADAR"));
                assertFalse(Palindrome.isWordPalindromeIterative("FAIL"));
                assertFalse(Palindrome.isWordPalindromeIterative("Fail"));
                assertFalse(Palindrome.isWordPalindromeIterative("fail"));
            }
        }

        @Nested
        class Sentence {
            @Test
            void testEmptyString() {
                assertFalse(Palindrome.isSentencePalindromeIterative(""));
            }

            @Test
            void testSingleLetter() {
                assertTrue(Palindrome.isSentencePalindromeIterative("A"));
                assertTrue(Palindrome.isSentencePalindromeIterative("a"));
            }

            @Test
            void testSingleWord() {
                assertTrue(Palindrome.isSentencePalindromeIterative("madam"));
                assertTrue(Palindrome.isSentencePalindromeIterative("Racecar"));
                assertTrue(Palindrome.isSentencePalindromeIterative("RADAR"));
                assertFalse(Palindrome.isSentencePalindromeIterative("FAIL"));
                assertFalse(Palindrome.isSentencePalindromeIterative("Fail"));
                assertFalse(Palindrome.isSentencePalindromeIterative("fail"));
            }

            @Test
            void testSentence() {
                assertTrue(Palindrome.isSentencePalindromeIterative("Murder for a jar of red rum"));
                assertTrue(Palindrome.isSentencePalindromeIterative("Rats live on no evil star"));
                assertTrue(Palindrome.isSentencePalindromeIterative("step on no pets"));
                assertFalse(Palindrome.isSentencePalindromeIterative("This should fail"));
                assertFalse(Palindrome.isSentencePalindromeIterative("this should fail"));
            }

            @Test
            void testSentenceWithPunctuation() {
                assertTrue(Palindrome.isSentencePalindromeIterative("Do geese see God?"));
                assertTrue(Palindrome.isSentencePalindromeIterative("Live on time, emit no evil"));
                assertTrue(Palindrome.isSentencePalindromeIterative("live on time, emit no evil"));
                assertFalse(Palindrome.isSentencePalindromeIterative("Will this fail?"));
                assertFalse(Palindrome.isSentencePalindromeIterative("will this fail?"));
            }
        }

        @Nested
        class Number {

            @Test
            void testSingleLongNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative(0L));
                assertTrue(Palindrome.isNumberPalindromeIterative(1L));
                assertTrue(Palindrome.isNumberPalindromeIterative(3L));
            }

            @Test
            void testBiggerLongNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative(123454321L));
                assertTrue(Palindrome.isNumberPalindromeIterative(1234567890987654321L));
                assertFalse(Palindrome.isNumberPalindromeIterative(123456789L));
                assertFalse(Palindrome.isNumberPalindromeIterative(1234567890123456789L));
            }

            @Test
            void testNegativeLongNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative(-0L));
                assertFalse(Palindrome.isNumberPalindromeIterative(-123454321L));
                assertFalse(Palindrome.isNumberPalindromeIterative(-1234567890987654321L));
                assertFalse(Palindrome.isNumberPalindromeIterative(-123456789L));
                assertFalse(Palindrome.isNumberPalindromeIterative(-1234567890123456789L));
            }

            @Test
            void testSingleIntegerNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative(0));
                assertTrue(Palindrome.isNumberPalindromeIterative(1));
                assertTrue(Palindrome.isNumberPalindromeIterative(3));
            }

            @Test
            void testBiggerIntegerNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative(123454321));
                assertFalse(Palindrome.isNumberPalindromeIterative(123456789));
            }

            @Test
            void testNegativeIntegerNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative(-0));
                assertFalse(Palindrome.isNumberPalindromeIterative(-123454321));
                assertFalse(Palindrome.isNumberPalindromeIterative(-123456789));
            }

            @Test
            void testSingleShortNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative((short) 0));
                assertTrue(Palindrome.isNumberPalindromeIterative((short) 1));
                assertTrue(Palindrome.isNumberPalindromeIterative((short) 3));
            }

            @Test
            void testBiggerShortNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative((short) 12321));
                assertFalse(Palindrome.isNumberPalindromeIterative((short) 12345));
            }

            @Test
            void testNegativeShortNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative((short) -0));
                assertFalse(Palindrome.isNumberPalindromeIterative((short) -12321));
                assertFalse(Palindrome.isNumberPalindromeIterative((short) -12345));
            }

            @Test
            void testSingleByteNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative((byte) 0));
                assertTrue(Palindrome.isNumberPalindromeIterative((byte) 1));
                assertTrue(Palindrome.isNumberPalindromeIterative((byte) 3));
            }

            @Test
            void testBiggerByteNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative((byte) 121));
                assertFalse(Palindrome.isNumberPalindromeIterative((byte) 123));
            }

            @Test
            void testNegativeByteNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative((byte) -0));
                assertFalse(Palindrome.isNumberPalindromeIterative((byte) -121));
                assertFalse(Palindrome.isNumberPalindromeIterative((byte) -123));
            }

        }

        @Nested
        class NumberInRange {
            @Test
            void testEmptyRangeLong() {
                List<Long> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative(122L, 130L));
            }

            @Test
            void testRangeSingleLong() {
                List<Long> expected = new ArrayList<>() {
                    {
                        add(1L);
                        add(2L);
                        add(3L);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative(1L, 4L));
            }

            @Test
            void testRangeLong() {
                List<Long> expected = new ArrayList<>() {
                    {
                        add(121L);
                        add(131L);
                        add(141L);
                        add(151L);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative(120L, 155L));
            }

            @Test
            void testNegativeRangeLong() {
                List<Long> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative(-131L, 0L));
            }

            @Test
            void testEmptyRangeInteger() {
                List<Integer> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative(122, 130));
            }

            @Test
            void testRangeSingleInteger() {
                List<Integer> expected = new ArrayList<>() {
                    {
                        add(1);
                        add(2);
                        add(3);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative(1, 4));
            }

            @Test
            void testRangeInteger() {
                List<Integer> expected = new ArrayList<>() {
                    {
                        add(121);
                        add(131);
                        add(141);
                        add(151);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative(120, 155));
            }

            @Test
            void testNegativeRangeInteger() {
                List<Integer> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative(-131, 0));
            }

            @Test
            void testEmptyRangeShort() {
                List<Short> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative((short) 122, (short) 130));
            }

            @Test
            void testRangeSingleShort() {
                List<Short> expected = new ArrayList<>() {
                    {
                        add((short) 1);
                        add((short) 2);
                        add((short) 3);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative((short) 1, (short) 4));
            }

            @Test
            void testRangeShort() {
                List<Short> expected = new ArrayList<>() {
                    {
                        add((short) 121);
                        add((short) 131);
                        add((short) 141);
                        add((short) 151);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative((short) 120, (short) 155));
            }

            @Test
            void testNegativeRangeShort() {
                List<Short> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative((short) -131, (short) 0));
            }

            @Test
            void testEmptyRangeByte() {
                List<Byte> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative((byte) 122, (byte) 125));
            }

            @Test
            void testRangeSingleByte() {
                List<Byte> expected = new ArrayList<>() {
                    {
                        add((byte) 1);
                        add((byte) 2);
                        add((byte) 3);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative((byte) 1, (byte) 4));
            }

            @Test
            void testRangeByte() {
                List<Byte> expected = new ArrayList<>() {
                    {
                        add((byte) 101);
                        add((byte) 111);
                        add((byte) 121);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative((byte) 100, (byte) 125));
            }

            @Test
            void testNegativeRangeByte() {
                List<Byte> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative((byte) -125, (byte) 0));
            }
        }
    }

    @Nested
    class Recursive {
        @Nested
        class Word {

            @Test
            void testEmptyString() {
                assertFalse(Palindrome.isWordPalindromeRecursive(""));
            }

            @Test
            void testSingleLetter() {
                assertTrue(Palindrome.isWordPalindromeRecursive("A"));
                assertTrue(Palindrome.isWordPalindromeRecursive("a"));
            }

            @Test
            void testName() {
                assertTrue(Palindrome.isWordPalindromeRecursive("ABBA"));
                assertTrue(Palindrome.isWordPalindromeRecursive("Ava"));
                assertTrue(Palindrome.isWordPalindromeRecursive("bob"));
                assertFalse(Palindrome.isWordPalindromeRecursive("FAIL"));
                assertFalse(Palindrome.isWordPalindromeRecursive("Fail"));
                assertFalse(Palindrome.isWordPalindromeRecursive("fail"));
            }

            @Test
            void testWord() {
                assertTrue(Palindrome.isWordPalindromeRecursive("madam"));
                assertTrue(Palindrome.isWordPalindromeRecursive("Racecar"));
                assertTrue(Palindrome.isWordPalindromeRecursive("RADAR"));
                assertFalse(Palindrome.isWordPalindromeRecursive("FAIL"));
                assertFalse(Palindrome.isWordPalindromeRecursive("Fail"));
                assertFalse(Palindrome.isWordPalindromeRecursive("fail"));
            }
        }

        @Nested
        class Sentence {
            @Test
            void testEmptyString() {
                assertFalse(Palindrome.isSentencePalindromeRecursive(""));
            }

            @Test
            void testSingleLetter() {
                assertTrue(Palindrome.isSentencePalindromeRecursive("A"));
                assertTrue(Palindrome.isSentencePalindromeRecursive("a"));
            }

            @Test
            void testSingleWord() {
                assertTrue(Palindrome.isSentencePalindromeRecursive("madam"));
                assertTrue(Palindrome.isSentencePalindromeRecursive("Racecar"));
                assertTrue(Palindrome.isSentencePalindromeRecursive("RADAR"));
                assertFalse(Palindrome.isSentencePalindromeRecursive("FAIL"));
                assertFalse(Palindrome.isSentencePalindromeRecursive("Fail"));
                assertFalse(Palindrome.isSentencePalindromeRecursive("fail"));
            }

            @Test
            void testSentence() {
                assertTrue(Palindrome.isSentencePalindromeRecursive("Murder for a jar of red rum"));
                assertTrue(Palindrome.isSentencePalindromeRecursive("Rats live on no evil star"));
                assertTrue(Palindrome.isSentencePalindromeRecursive("step on no pets"));
                assertFalse(Palindrome.isSentencePalindromeRecursive("This should fail"));
                assertFalse(Palindrome.isSentencePalindromeRecursive("this should fail"));
            }

            @Test
            void testSentenceWithPunctuation() {
                assertTrue(Palindrome.isSentencePalindromeRecursive("Do geese see God?"));
                assertTrue(Palindrome.isSentencePalindromeRecursive("Live on time, emit no evil"));
                assertTrue(Palindrome.isSentencePalindromeRecursive("live on time, emit no evil"));
                assertFalse(Palindrome.isSentencePalindromeRecursive("Will this fail?"));
                assertFalse(Palindrome.isSentencePalindromeRecursive("will this fail?"));
            }
        }

        @Nested
        class Number {

            @Test
            void testSingleLongNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive(0L));
                assertTrue(Palindrome.isNumberPalindromeRecursive(1L));
                assertTrue(Palindrome.isNumberPalindromeRecursive(3L));
            }

            @Test
            void testBiggerLongNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive(123454321L));
                assertTrue(Palindrome.isNumberPalindromeRecursive(1234567890987654321L));
                assertFalse(Palindrome.isNumberPalindromeRecursive(123456789L));
                assertFalse(Palindrome.isNumberPalindromeRecursive(1234567890123456789L));
            }

            @Test
            void testNegativeLongNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive(-0L));
                assertFalse(Palindrome.isNumberPalindromeRecursive(-123454321L));
                assertFalse(Palindrome.isNumberPalindromeRecursive(-1234567890987654321L));
                assertFalse(Palindrome.isNumberPalindromeRecursive(-123456789L));
                assertFalse(Palindrome.isNumberPalindromeRecursive(-1234567890123456789L));
            }

            @Test
            void testSingleIntegerNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive(0));
                assertTrue(Palindrome.isNumberPalindromeRecursive(1));
                assertTrue(Palindrome.isNumberPalindromeRecursive(3));
            }

            @Test
            void testBiggerIntegerNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive(123454321));
                assertFalse(Palindrome.isNumberPalindromeRecursive(123456789));
            }

            @Test
            void testNegativeIntegerNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive(-0));
                assertFalse(Palindrome.isNumberPalindromeRecursive(-123454321));
                assertFalse(Palindrome.isNumberPalindromeRecursive(-123456789));
            }

            @Test
            void testSingleShortNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive((short) 0));
                assertTrue(Palindrome.isNumberPalindromeRecursive((short) 1));
                assertTrue(Palindrome.isNumberPalindromeRecursive((short) 3));
            }

            @Test
            void testBiggerShortNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive((short) 12321));
                assertFalse(Palindrome.isNumberPalindromeRecursive((short) 12345));
            }

            @Test
            void testNegativeShortNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive((short) -0));
                assertFalse(Palindrome.isNumberPalindromeRecursive((short) -12321));
                assertFalse(Palindrome.isNumberPalindromeRecursive((short) -12345));
            }

            @Test
            void testSingleByteNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive((byte) 0));
                assertTrue(Palindrome.isNumberPalindromeRecursive((byte) 1));
                assertTrue(Palindrome.isNumberPalindromeRecursive((byte) 3));
            }

            @Test
            void testBiggerByteNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive((byte) 121));
                assertFalse(Palindrome.isNumberPalindromeRecursive((byte) 123));
            }

            @Test
            void testNegativeByteNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive((byte) -0));
                assertFalse(Palindrome.isNumberPalindromeRecursive((byte) -121));
                assertFalse(Palindrome.isNumberPalindromeRecursive((byte) -123));
            }

        }

        @Nested
        class NumberInRange {
            @Test
            void testEmptyRangeLong() {
                List<Long> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive(122L, 130L));
            }

            @Test
            void testRangeSingleLong() {
                List<Long> expected = new ArrayList<>() {
                    {
                        add(1L);
                        add(2L);
                        add(3L);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive(1L, 4L));
            }

            @Test
            void testRangeLong() {
                List<Long> expected = new ArrayList<>() {
                    {
                        add(121L);
                        add(131L);
                        add(141L);
                        add(151L);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive(120L, 155L));
            }

            @Test
            void testNegativeRangeLong() {
                List<Long> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive(-131L, 0L));
            }

            @Test
            void testEmptyRangeInteger() {
                List<Integer> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive(122, 130));
            }

            @Test
            void testRangeSingleInteger() {
                List<Integer> expected = new ArrayList<>() {
                    {
                        add(1);
                        add(2);
                        add(3);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive(1, 4));
            }

            @Test
            void testRangeInteger() {
                List<Integer> expected = new ArrayList<>() {
                    {
                        add(121);
                        add(131);
                        add(141);
                        add(151);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive(120, 155));
            }

            @Test
            void testNegativeRangeInteger() {
                List<Integer> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive(-131, 0));
            }

            @Test
            void testEmptyRangeShort() {
                List<Short> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive((short) 122, (short) 130));
            }

            @Test
            void testRangeSingleShort() {
                List<Short> expected = new ArrayList<>() {
                    {
                        add((short) 1);
                        add((short) 2);
                        add((short) 3);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive((short) 1, (short) 4));
            }

            @Test
            void testRangeShort() {
                List<Short> expected = new ArrayList<>() {
                    {
                        add((short) 121);
                        add((short) 131);
                        add((short) 141);
                        add((short) 151);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive((short) 120, (short) 155));
            }

            @Test
            void testNegativeRangeShort() {
                List<Short> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive((short) -131, (short) 0));
            }

            @Test
            void testEmptyRangeByte() {
                List<Byte> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive((byte) 122, (byte) 125));
            }

            @Test
            void testRangeSingleByte() {
                List<Byte> expected = new ArrayList<>() {
                    {
                        add((byte) 1);
                        add((byte) 2);
                        add((byte) 3);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive((byte) 1, (byte) 4));
            }

            @Test
            void testRangeByte() {
                List<Byte> expected = new ArrayList<>() {
                    {
                        add((byte) 101);
                        add((byte) 111);
                        add((byte) 121);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive((byte) 100, (byte) 125));
            }

            @Test
            void testNegativeRangeByte() {
                List<Byte> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive((byte) -125, (byte) 0));
            }
        }
    }
}
```

Risposte

2 Bobby Aug 27 2020 at 23:51

Sembra fantastico, piacevole da leggere nonostante la ripetizione.


package com.gr;

I pacchetti dovrebbero essere associati all'autore, quindi dovrebbero essere qualcosa di simile com.github.lucifer.palindromead esempio. Ma a seconda che questo codice venga pubblicato o meno, in questo caso non ha importanza.


Questo sarebbe un ottimo esercizio per la programmazione orientata agli oggetti creando un'interfaccia e avendo due implementazioni separate:

public interface PalindromeTester;
public class IterativePalindromeTester implements PalindromeTester;
public class RecursivePalindromeTester implements PalindromeTester;

Ciò risolverebbe metà della tua domanda di sovraccarico. L'altra metà è la cosa Number// CharArray, Worddovresti eliminarla dal nome come è ovvio dai parametri accettati. L'IT pulirà anche un po 'il tuo caso di test, poiché sarebbero due diverse classi di test. Hai persino una abstractclasse di test e la estendi e imposti solo un'istanza diversa di PalindromeTesteron BeforeEach.

Un'altra cosa è che, se riesci a convivere con l'ampliamento dei valori dati, potresti fornire un solo metodo che accetti un file long. Qualsiasi short/ intverrà convertito automaticamente, ma ciò, ovviamente, richiede un'operazione di ampliamento sotto il cofano.

C'è anche Number/ BigInteger, che potresti voler includere.

In un'altra nota, potresti abbandonare char[]a favore di CharSequence. Quest'ultimo è la base per molte classi diverse (incluso String, quindi non è richiesto alcun sovraccarico) e rappresenta un po' meglio l'intento. A questo proposito, se accetti qualsiasi lettera, comprese le lingue straniere, molto probabilmente vorrai lavorare sui punti di codice ( int) invece di chars. In UTF-8/UTF-16, non tutte le lettere sono costituite da un singolo byte, ma possono essere composte da più byte (fino a quattro, quindi int).


 * Returns a boolean of whether the number of type short (32,768 to 32,767)

Non includere valori min/max come quelli nella documentazione. Innanzitutto, è ridondante come risulta evidente dal tipo utilizzato. In secondo luogo, è soggetto a errori di battitura, come in questo caso.


        List<Long> results = new ArrayList<>();
        for (long number = start; number != end; number++)
            if (isNumberPalindromeRecursive(number))
                results.add(number);

Tieni presente che si tratta di autoboxing, il che significa che una primitiva viene automaticamente convertita in Objectun'istanza.


for (int i = 0; i != formattedChars.length / 2; i++)

Innanzitutto, sono un persistente sostenitore dei nomi "reali" per le variabili di ciclo, come indexo counter.

In secondo luogo, è necessario rivedere la condizione di interruzione per renderla più robusta controllando se il valore è uguale o maggiore della metà della lunghezza.


        boolean isPalindrome = true;
        for (int i = 0; i != formattedChars.length / 2; i++)
            if (formattedChars[i] != formattedChars[(formattedChars.length - 1) - i]) {
                isPalindrome = false;
                break;
            }
        return isPalindrome;

Non memorizzare il risultato, restituiscilo direttamente.

        for (int i = 0; i != formattedChars.length / 2; i++)
            if (formattedChars[i] != formattedChars[(formattedChars.length - 1) - i])
                return false;
        
        return true;
```
1 TorbenPutkonen Aug 27 2020 at 11:14

Avere un'interfaccia comune per l'algoritmo risolverebbe la duplicazione del codice tra i test per diverse implementazioni. Si crea una serie di test che qualsiasi implementazione dell'interfaccia dovrebbe soddisfare e quindi si limita a lanciare diverse implementazioni (vedere la L in PRINCIPI SOLID ).

Per testare un ampio set di input di stringhe semplici, inserire le voci valide in un array e quelle non valide in un altro e creare due test che eseguono il ciclo su ogni array.