Duplicate characters in a String oneliner + method + tests (Java)


Hello everyone, just in case you need to give it a quick shot:

Example (for quick testing in jshell): 

"test".chars().mapToObj( c -> "" + (char)c +(char)c ).reduce("", String::concat)

> tteesstt


If you need it as a method:


public class DuplicateCharacters {

    public static String duplicateChars(String inputString) {
        return inputString.chars()
                .mapToObj(c -> "" + (char) c + (char) c)
                .reduce("", String::concat);
    }

    public static void main(String[] args) {
        String text = "Hello";
        String result = duplicateChars(text);
        System.out.println(result); // Prints HHeelllloo
    }
}

In case you need a slightly more optimal solution for larger strings with cycle unrolling and some tests (depends on org.junit.jupiter:junit-jupiter:5.11.4):

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class DuplicateCharactersUnrolledOptimized {

    public static String duplicateCharactersUnrolledOptimized(final String inputString) {
        if (inputString == null || inputString.isEmpty()) {
            return inputString;
        }

        final int length = inputString.length();
        final StringBuilder sb = new StringBuilder(length << 1);

        int i = 0;
        while (i + 7 < length) {
            char c;

            c = inputString.charAt(i++);
            sb.append(c).append(c);

            c = inputString.charAt(i++);
            sb.append(c).append(c);

            c = inputString.charAt(i++);
            sb.append(c).append(c);

            c = inputString.charAt(i++);
            sb.append(c).append(c);

            c = inputString.charAt(i++);
            sb.append(c).append(c);

            c = inputString.charAt(i++);
            sb.append(c).append(c);

            c = inputString.charAt(i++);
            sb.append(c).append(c);

            c = inputString.charAt(i++);
            sb.append(c).append(c);
        }
        while(i < length) {
            final char c = inputString.charAt(i++);
            sb.append(c).append(c);
        }

        return sb.toString();
    }

    //Tests
    @Test
    public void testEmptyString() {
        assertEquals("", duplicateCharactersUnrolledOptimized(""));
    }

    @Test
    public void testNullString() {
        assertEquals(null, duplicateCharactersUnrolledOptimized(null));
    }

    @Test
    public void testShortStringEven() {
        assertEquals("HHeelllloo", duplicateCharactersUnrolledOptimized("Hello"));
    }

    @Test
    public void testShortStringOdd() {
        assertEquals("HHeellllooWW", duplicateCharactersUnrolledOptimized("HelloW"));
    }

    @Test
    public void testLongStringMultipleOf8() {
        assertEquals("AAaaBBbbCCccDDdd", duplicateCharactersUnrolledOptimized("AaBbCcDd"));
    }

    @Test
    public void testLongStringNotMultipleOf8() {
        assertEquals("AAaaBBbbCCccDDddee", duplicateCharactersUnrolledOptimized("AaBbCcDde"));
    }
}

I hope it is of use.

Comments