Simple way to repeat a string

后端 未结 30 3029
清酒与你
清酒与你 2020-11-21 06:55

I\'m looking for a simple commons method or operator that allows me to repeat some string n times. I know I could write this using a for loop, but I wish to avoid f

30条回答
  •  别跟我提以往
    2020-11-21 06:59

    OOP Solution

    Nearly every answer proposes a static function as a solution, but thinking Object-Oriented (for reusability-purposes and clarity) I came up with a Solution via Delegation through the CharSequence-Interface (which also opens up usability on mutable CharSequence-Classes).

    The following Class can be used either with or without Separator-String/CharSequence and each call to "toString()" builds the final repeated String. The Input/Separator are not only limited to String-Class, but can be every Class which implements CharSequence (e.g. StringBuilder, StringBuffer, etc)!

    Source-Code:

    /**
     * Helper-Class for Repeating Strings and other CharSequence-Implementations
     * @author Maciej Schuttkowski
     */
    public class RepeatingCharSequence implements CharSequence {
        final int count;
        CharSequence internalCharSeq = "";
        CharSequence separator = "";
        /**
         * CONSTRUCTOR - RepeatingCharSequence
         * @param input CharSequence to repeat
         * @param count Repeat-Count
         */
        public RepeatingCharSequence(CharSequence input, int count) {
            if(count < 0)
                throw new IllegalArgumentException("Can not repeat String \""+input+"\" less than 0 times! count="+count);
            if(count > 0)
                internalCharSeq = input;
            this.count = count;
        }
        /**
         * CONSTRUCTOR - Strings.RepeatingCharSequence
         * @param input CharSequence to repeat
         * @param count Repeat-Count
         * @param separator Separator-Sequence to use
         */
        public RepeatingCharSequence(CharSequence input, int count, CharSequence separator) {
            this(input, count);
            this.separator = separator;
        }
    
        @Override
        public CharSequence subSequence(int start, int end) {
            checkBounds(start);
            checkBounds(end);
            int subLen = end - start;
            if (subLen < 0) {
                throw new IndexOutOfBoundsException("Illegal subSequence-Length: "+subLen);
            }
            return (start == 0 && end == length()) ? this
                        : toString().substring(start, subLen);
        }
        @Override
        public int length() {
            //We return the total length of our CharSequences with the separator 1 time less than amount of repeats:
            return count < 1 ? 0
                    : ( (internalCharSeq.length()*count) + (separator.length()*(count-1)));
        }
        @Override
        public char charAt(int index) {
            final int internalIndex = internalIndex(index);
            //Delegate to Separator-CharSequence or Input-CharSequence depending on internal index:
            if(internalIndex > internalCharSeq.length()-1) {
                return separator.charAt(internalIndex-internalCharSeq.length());
            }
            return internalCharSeq.charAt(internalIndex);
        }
        @Override
        public String toString() {
            return count < 1 ? ""
                    : new StringBuilder(this).toString();
        }
    
        private void checkBounds(int index) {
            if(index < 0 || index >= length())
                throw new IndexOutOfBoundsException("Index out of Bounds: "+index);
        }
        private int internalIndex(int index) {
            // We need to add 1 Separator-Length to total length before dividing,
            // as we subtracted one Separator-Length in "length()"
            return index % ((length()+separator.length())/count);
        }
    }
    

    Usage-Example:

    public static void main(String[] args) {
        //String input = "12345";
        //StringBuffer input = new StringBuffer("12345");
        StringBuilder input = new StringBuilder("123");
        //String separator = "<=>";
        StringBuilder separator = new StringBuilder("<=");//.append('>');
        int repeatCount = 2;
    
        CharSequence repSeq = new RepeatingCharSequence(input, repeatCount, separator);
        String repStr = repSeq.toString();
    
        System.out.println("Repeat="+repeatCount+"\tSeparator="+separator+"\tInput="+input+"\tLength="+input.length());
        System.out.println("CharSeq:\tLength="+repSeq.length()+"\tVal="+repSeq);
        System.out.println("String :\tLength="+repStr.length()+"\tVal="+repStr);
    
        //Here comes the Magic with a StringBuilder as Input, as you can append to the String-Builder
        //and at the same Time your Repeating-Sequence's toString()-Method returns the updated String :)
        input.append("ff");
        System.out.println(repSeq);
        //Same can be done with the Separator:
        separator.append("===").append('>');
        System.out.println(repSeq);
    }
    

    Example-Output:

    Repeat=2    Separator=<=    Input=123   Length=3
    CharSeq:    Length=8    Val=123<=123
    String :    Length=8    Val=123<=123
    123ff<=123ff
    123ff<====>123ff
    

提交回复
热议问题