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
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)!
/**
* 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);
}
}
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);
}
Repeat=2 Separator=<= Input=123 Length=3
CharSeq: Length=8 Val=123<=123
String : Length=8 Val=123<=123
123ff<=123ff
123ff<====>123ff