자바에서 문자열을 반복하는 간단한 방법
나는 String n 번 반복 할 수있는 간단한 commons 메소드 또는 연산자를 찾고 있습니다 . 나는 for 루프를 사용하여 이것을 작성할 수 있다는 것을 알고 있지만 필요할 때마다 for 루프를 피하고 간단한 직접 방법이 어딘가에 있어야합니다.
String str = "abc";
String repeated = str.repeat(3);
repeated.equals("abcabcabc");
와 연관되다:
문자열 자바 스크립트 반복 주어진 횟수만큼 다른 문자열을 반복하여 NSString 생성
편집
루프가 완전히 필요하지 않은 경우 for 루프를 피하려고합니다.
그들은 다른 함수에 얽혀 있어도 코드 줄 수에 추가합니다.
내 코드를 읽는 사람은 for 루프에서 내가하는 일을 알아야합니다. 주석을 달고 의미있는 변수 이름을 가지고 있더라도 여전히 "영리한"작업을 수행하지 않아야합니다.
프로그래머는 "루프를 위해 의도 한 대로만"한다고 쓰더라도 영리한 것을 for 루프에 넣는 것을 좋아합니다.
그들은 종종 잘못되기 쉽습니다. 인덱스와 관련된 루프는 하나의 버그로 생성되는 경향이 있습니다.
For 루프는 종종 같은 변수를 재사용하므로 범위 지정 버그를 찾기가 매우 어려워집니다.
For 루프는 버그 사냥꾼이 찾아야하는 장소의 수를 늘립니다.
String::repeat
". ".repeat( 7 ) // Seven period-with-space pairs: . . . . . . .
Java 11의 새로운 기능은String::repeat
요청한 내용을 정확하게 수행 하는 방법 입니다.
String str = "abc";
String repeated = str.repeat(3);
repeated.equals("abcabcabc");
자사의 자바 독은 말합니다 :
/**
* Returns a string whose value is the concatenation of this
* string repeated {@code count} times.
* <p>
* If this string is empty or count is zero then the empty
* string is returned.
*
* @param count number of times to repeat
*
* @return A string composed of this string repeated
* {@code count} times or the empty string if this
* string is empty or count is zero
*
* @throws IllegalArgumentException if the {@code count} is
* negative.
*
* @since 11
*/
가장 짧은 버전은 다음과 같습니다 (Java 1.5 이상 필요).
repeated = new String(new char[n]).replace("\0", s);
n
문자열을 반복하려는 횟수는 어디 이며 반복 할 문자열 s
입니다.
가져 오기 또는 라이브러리가 필요하지 않습니다.
Commons Lang StringUtils.repeat ()
용법:
String str = "abc";
String repeated = StringUtils.repeat(str, 3);
repeated.equals("abcabcabc");
Java <= 7을 사용하는 경우 다음과 같이 간단합니다.
// create a string made up of n copies of string s
String.format("%0" + n + "d", 0).replace("0", s);
에서 자바 8 위 쉬운 방법이있다 :
// create a string made up of n copies of string s
String.join("", Collections.nCopies(n, s));
Java 11repeat(int count)
은 이것을 위해 특별히 새로운 방법을 추가했습니다 ( link )
int n = 3;
"abc".repeat(n);
Java 8 String.join
은 다음과 관련하여 깔끔한 방법을 제공합니다 Collections.nCopies
.
// say hello 100 times
System.out.println(String.join("", Collections.nCopies(100, "hello")));
표준 String 함수 만 사용하고 명시적인 루프를 사용하지 않는 방법은 다음과 같습니다.
// create a string made up of n copies of s
repeated = String.format(String.format("%%%ds", n), " ").replace(" ",s);
나와 같고 Apache Commons가 아닌 Google Guava를 사용하려는 경우. Guava Strings 클래스에서 repeat 메소드를 사용할 수 있습니다 .
Strings.repeat("-", 60);
함께 자바-8 , 당신은 또한 사용할 수 있습니다 Stream.generate
.
import static java.util.stream.Collectors.joining;
...
String repeated = Stream.generate(() -> "abc").limit(3).collect(joining()); //"abcabcabc"
필요한 경우 간단한 유틸리티 방법으로 래핑 할 수 있습니다.
public static String repeat(String str, int times) {
return Stream.generate(() -> str).limit(times).collect(joining());
}
루프를 피하고 싶습니까?
여기 있습니다 :
public static String repeat(String s, int times) {
if (times <= 0) return "";
else return s + repeat(s, times-1);
}
(물론 이것은 추악하고 비효율적이지만 루프가 없습니다 :-p)
더 단순하고 예쁘기를 원하십니까? 자이 썬 사용 :
s * 3
편집 : 조금 최적화 해 봅시다 :-D
public static String repeat(String s, int times) {
if (times <= 0) return "";
else if (times % 2 == 0) return repeat(s+s, times/2);
else return s + repeat(s+s, times/2);
}
Edit2 : 4 가지 주요 대안에 대해 빠르고 더러운 벤치 마크를 수행했지만 평균을 얻기 위해 여러 번 실행하고 여러 입력에 대한 시간을 계획 할 시간이 없습니다 ... 그래서 누군가가 원하는 경우 코드는 다음과 같습니다. 시도해보십시오.
public class Repeat {
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
String s = args[1];
int l = s.length();
long start, end;
start = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
if(repeatLog2(s,i).length()!=i*l) throw new RuntimeException();
}
end = System.currentTimeMillis();
System.out.println("RecLog2Concat: " + (end-start) + "ms");
start = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
if(repeatR(s,i).length()!=i*l) throw new RuntimeException();
}
end = System.currentTimeMillis();
System.out.println("RecLinConcat: " + (end-start) + "ms");
start = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
if(repeatIc(s,i).length()!=i*l) throw new RuntimeException();
}
end = System.currentTimeMillis();
System.out.println("IterConcat: " + (end-start) + "ms");
start = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
if(repeatSb(s,i).length()!=i*l) throw new RuntimeException();
}
end = System.currentTimeMillis();
System.out.println("IterStrB: " + (end-start) + "ms");
}
public static String repeatLog2(String s, int times) {
if (times <= 0) {
return "";
}
else if (times % 2 == 0) {
return repeatLog2(s+s, times/2);
}
else {
return s + repeatLog2(s+s, times/2);
}
}
public static String repeatR(String s, int times) {
if (times <= 0) {
return "";
}
else {
return s + repeatR(s, times-1);
}
}
public static String repeatIc(String s, int times) {
String tmp = "";
for (int i = 0; i < times; i++) {
tmp += s;
}
return tmp;
}
public static String repeatSb(String s, int n) {
final StringBuilder sb = new StringBuilder();
for(int i = 0; i < n; i++) {
sb.append(s);
}
return sb.toString();
}
}
두 개의 인수가 필요합니다. 첫 번째는 반복 횟수 (각 함수는 1..n의 반복 시간으로 실행 됨)이고 두 번째는 반복 할 문자열입니다.
지금까지 다른 입력으로 실행되는 시간을 빠르게 검사하면 다음과 같은 순위가 유지됩니다.
- 반복적 인 StringBuilder 추가 (1x).
- 재귀 연결 log2 호출 (~ 3x).
- 재귀 연결 선형 호출 (~ 30x).
- 반복 연결 선형 (~ 45x).
재귀 함수가 for
루프 보다 빠르다고 추측하지 못했습니다 .
재미있게 보내십시오 (actal xD).
질문보다 문자가 적습니다.
public static String repeat(String s, int n) {
if(s == null) {
return null;
}
final StringBuilder sb = new StringBuilder(s.length() * n);
for(int i = 0; i < n; i++) {
sb.append(s);
}
return sb.toString();
}
를 기반으로 포트란의 대답은 , 이것은 모두 StringBuilder를 사용하는 recusive 버전입니다 :
public static void repeat(StringBuilder stringBuilder, String s, int times) {
if (times > 0) {
repeat(stringBuilder.append(s), s, times - 1);
}
}
public static String repeat(String s, int times) {
StringBuilder stringBuilder = new StringBuilder(s.length() * times);
repeat(stringBuilder, s, times);
return stringBuilder.toString();
}
달러를 사용하는 것은 입력하는 것만 큼 간단합니다.
@Test
public void repeatString() {
String string = "abc";
assertThat($(string).repeat(3).toString(), is("abcabcabc"));
}
추신 : 반복 은 배열, 목록, 설정 등에 대해서도 작동합니다 .
JDBC 목적으로 쉼표로 구분 된 물음표 목록을 만드는 기능을 원했고이 게시물을 찾았습니다. 그래서 나는 두 가지 변형을 취하고 어느 것이 더 잘 수행되는지 확인하기로 결정했습니다. 백만 번의 반복 후에 정원 다양성 StringBuilder는 2 초 (fun1)가 걸리고 암호는 아마도 더 최적의 버전 (fun2)이 30 초가 걸렸습니다. 다시 비밀스러운 점은 무엇입니까?
private static String fun1(int size) {
StringBuilder sb = new StringBuilder(size * 2);
for (int i = 0; i < size; i++) {
sb.append(",?");
}
return sb.substring(1);
}
private static String fun2(int size) {
return new String(new char[size]).replaceAll("\0", ",?").substring(1);
}
OOP 솔루션
거의 모든 대답은 솔루션으로 정적 함수를 제안하지만 Object-Oriented (재사용 목적 및 명확성을 위해) 생각하는 CharSequence-Interface (변형 가능한 CharSequence-Classes에 대한 유용성을 열어주는)를 통해 위임을 통해 솔루션을 생각해 냈습니다.
다음 클래스는 Separator-String / CharSequence와 함께 또는없이 사용할 수 있으며 "toString ()"에 대한 각 호출은 최종 반복 문자열을 빌드합니다. Input / Separator는 String-Class로 제한 될뿐만 아니라 CharSequence를 구현하는 모든 Class가 될 수 있습니다 (예 : StringBuilder, StringBuffer 등)!
소스 코드:
/**
* 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
JRE 클래스 ( System.arraycopy ) 만 사용 하고 다음과 같이 작성할 수있는 임시 객체 수 를 최소화하려고합니다 .
public static String repeat(String toRepeat, int times) {
if (toRepeat == null) {
toRepeat = "";
}
if (times < 0) {
times = 0;
}
final int length = toRepeat.length();
final int total = length * times;
final char[] src = toRepeat.toCharArray();
char[] dst = new char[total];
for (int i = 0; i < total; i += length) {
System.arraycopy(src, 0, dst, i, length);
}
return String.copyValueOf(dst);
}
편집하다
그리고 루프없이 당신은 시도 할 수 있습니다 :
public static String repeat2(String toRepeat, int times) {
if (toRepeat == null) {
toRepeat = "";
}
if (times < 0) {
times = 0;
}
String[] copies = new String[times];
Arrays.fill(copies, toRepeat);
return Arrays.toString(copies).
replace("[", "").
replace("]", "").
replaceAll(", ", "");
}
편집 2
컬렉션 사용 이 더 짧습니다.
public static String repeat3(String toRepeat, int times) {
return Collections.nCopies(times, toRepeat).
toString().
replace("[", "").
replace("]", "").
replaceAll(", ", "");
}
그러나 나는 여전히 첫 번째 버전을 좋아합니다.
속도가 우려되는 경우 가능한 적은 메모리 복사를 사용해야합니다. 따라서 문자 배열로 작업해야합니다.
public static String repeatString(String what, int howmany) {
char[] pattern = what.toCharArray();
char[] res = new char[howmany * pattern.length];
int length = pattern.length;
for (int i = 0; i < howmany; i++)
System.arraycopy(pattern, 0, res, i * length, length);
return new String(res);
}
속도를 테스트하기 위해 StirngBuilder를 사용하는 유사한 최적의 방법은 다음과 같습니다.
public static String repeatStringSB(String what, int howmany) {
StringBuilder out = new StringBuilder(what.length() * howmany);
for (int i = 0; i < howmany; i++)
out.append(what);
return out.toString();
}
그것을 테스트하는 코드 :
public static void main(String... args) {
String res;
long time;
for (int j = 0; j < 1000; j++) {
res = repeatString("123", 100000);
res = repeatStringSB("123", 100000);
}
time = System.nanoTime();
res = repeatString("123", 1000000);
time = System.nanoTime() - time;
System.out.println("elapsed repeatString: " + time);
time = System.nanoTime();
res = repeatStringSB("123", 1000000);
time = System.nanoTime() - time;
System.out.println("elapsed repeatStringSB: " + time);
}
그리고 여기 내 시스템의 실행 결과 :
elapsed repeatString: 6006571
elapsed repeatStringSB: 9064937
루프 테스트는 JIT에서 시작하여 최적의 결과를 얻는 것입니다.
아니 짧은,하지만 (내가 생각하는) 가장 빠른 방법은 모두 StringBuilder를 사용하는 것입니다 :
/**
* Repeat a String as many times you need.
*
* @param i - Number of Repeating the String.
* @param s - The String wich you want repeated.
* @return The string n - times.
*/
public static String repeate(int i, String s) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < i; j++)
sb.append(s);
return sb.toString();
}
가독성과 이식성을 위해 :
public String repeat(String str, int count){
if(count <= 0) {return "";}
return new String(new char[count]).replace("\0", str);
}
성능이 걱정된다면 루프 내부에서 StringBuilder를 사용하고 루프 종료시 .toString ()을 수행하십시오. Util Class를 작성하여 재사용하십시오. 최대 5 줄의 코드
나는이 질문을 정말로 즐긴다. 많은 지식과 스타일이 있습니다. 그래서 나는 내 로큰롤을 보여주지 않고 그것을 떠날 수 없다.)
{
String string = repeat("1234567890", 4);
System.out.println(string);
System.out.println("=======");
repeatWithoutCopySample(string, 100000);
System.out.println(string);// This take time, try it without printing
System.out.println(string.length());
}
/**
* The core of the task.
*/
@SuppressWarnings("AssignmentToMethodParameter")
public static char[] repeat(char[] sample, int times) {
char[] r = new char[sample.length * times];
while (--times > -1) {
System.arraycopy(sample, 0, r, times * sample.length, sample.length);
}
return r;
}
/**
* Java classic style.
*/
public static String repeat(String sample, int times) {
return new String(repeat(sample.toCharArray(), times));
}
/**
* Java extreme memory style.
*/
@SuppressWarnings("UseSpecificCatch")
public static void repeatWithoutCopySample(String sample, int times) {
try {
Field valueStringField = String.class.getDeclaredField("value");
valueStringField.setAccessible(true);
valueStringField.set(sample, repeat((char[]) valueStringField.get(sample), times));
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
당신은 그것을 좋아합니까?
public static String repeat(String str, int times) {
int length = str.length();
int size = length * times;
char[] c = new char[size];
for (int i = 0; i < size; i++) {
c[i] = str.charAt(i % length);
}
return new String(c);
}
간단한 루프
public static String repeat(String string, int times) {
StringBuilder out = new StringBuilder();
while (times-- > 0) {
out.append(string);
}
return out.toString();
}
이것을 시도하십시오 :
public static char[] myABCs = {'a', 'b', 'c'};
public static int numInput;
static Scanner in = new Scanner(System.in);
public static void main(String[] args) {
System.out.print("Enter Number of Times to repeat: ");
numInput = in.nextInt();
repeatArray(numInput);
}
public static int repeatArray(int y) {
for (int a = 0; a < y; a++) {
for (int b = 0; b < myABCs.length; b++) {
System.out.print(myABCs[b]);
}
System.out.print(" ");
}
return y;
}
재귀를 사용하여 다음을 수행 할 수 있습니다 (삼항 연산자를 사용하여 최대 한 줄 최대).
public static final String repeat(String string, long number) {
return number == 1 ? string : (number % 2 == 0 ? repeat(string + string, number / 2) : string + repeat(string + string, (number - 1) / 2));
}
나는 추악하고 아마도 효율적이지 않지만 한 줄입니다!
루프를 사용하지 않기를 원하지만 루프를 사용해야한다고 생각합니다.
String repeatString(String s, int repetitions)
{
if(repetitions < 0) throw SomeException();
else if(s == null) return null;
StringBuilder stringBuilder = new StringBuilder(s.length() * repetitions);
for(int i = 0; i < repetitions; i++)
stringBuilder.append(s);
return stringBuilder.toString();
}
for 루프를 사용하지 않는 이유는 좋지 않습니다. 당신의 비판에 대한 응답으로 :
- 어떤 솔루션을 사용하든 거의 이보다 더 길 것입니다. 사전 구축 된 기능을 사용하면 더 많은 기능을 사용할 수 있습니다.
- 코드를 읽는 사람은 비 루프에서 수행중인 작업을 파악해야합니다. for-loop가이를 수행하는 관용적 방법 인 경우 for-loop로 수행했는지 파악하는 것이 훨씬 쉽습니다.
- 네 사람이 영리한 뭔가를 추가 할 수 있지만 루프를 피함으로써 수도 당신이 하는 영리한 뭔가를하고 . 그것은 실수로 발로 자신을 쏘지 않도록 의도적으로 발로 자신을 쏘는 것과 같습니다.
- 한 번의 테스트로 한 번에 한 가지 오류를 쉽게 파악할 수 있습니다. 코드를 테스트해야한다고 생각하면, 한 번에 하나씩 오류를 수정하고 파악하기 쉬워야합니다. 그리고 주목할 가치가 있습니다. 위의 코드에는 1 개씩의 오류가 없습니다. For 루프는 똑같이 쉽게 얻을 수 있습니다.
- 따라서 변수를 재사용하지 마십시오. 그것은 for-loop의 잘못이 아닙니다.
- 다시 말하지만 사용하는 모든 솔루션도 마찬가지입니다. 그리고 내가 전에 언급했듯이; 버그 헌터는 아마도 for 루프로 이것을 할 것으로 예상 할 것이므로, for 루프를 사용하면 버그를 쉽게 찾을 수 있습니다.
다음은 최신 Stringutils.java입니다. StringUtils.java
public static String repeat(String str, int repeat) {
// Performance tuned for 2.0 (JDK1.4)
if (str == null) {
return null;
}
if (repeat <= 0) {
return EMPTY;
}
int inputLength = str.length();
if (repeat == 1 || inputLength == 0) {
return str;
}
if (inputLength == 1 && repeat <= PAD_LIMIT) {
return repeat(str.charAt(0), repeat);
}
int outputLength = inputLength * repeat;
switch (inputLength) {
case 1 :
return repeat(str.charAt(0), repeat);
case 2 :
char ch0 = str.charAt(0);
char ch1 = str.charAt(1);
char[] output2 = new char[outputLength];
for (int i = repeat * 2 - 2; i >= 0; i--, i--) {
output2[i] = ch0;
output2[i + 1] = ch1;
}
return new String(output2);
default :
StringBuilder buf = new StringBuilder(outputLength);
for (int i = 0; i < repeat; i++) {
buf.append(str);
}
return buf.toString();
}
}
이 크기 일 필요도없고, 만들 수도 있고, 프로젝트의 유틸리티 클래스에 복사하여 붙여 넣을 수도 있습니다.
public static String repeat(String str, int num) {
int len = num * str.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < times; i++) {
sb.append(str);
}
return sb.toString();
}
e5,이 작업을 수행하는 가장 좋은 방법은 위에서 언급 한 코드 또는 여기에 대한 답변을 사용하는 것입니다. 그러나 작은 프로젝트라면 커먼즈 랭이 너무 큽니다.
나는 당신이 원하는 것과 같은 일을하는 재귀 적 방법을 만들었습니다.
public String repeat(String str, int count) {
return count > 0 ? repeat(str, count -1) + str: "";
}
난에 같은 대답이 반복 시퀀스에 자바 캔 I 다중 문자열을?
public static String rep(int a,String k)
{
if(a<=0)
return "";
else
{a--;
return k+rep(a,k);
}
이 재귀 방법을 원하는 목표에 사용할 수 있습니다.
repeated = str + str + str;
때로는 단순하다. 코드를 읽는 사람은 무슨 일이 일어나고 있는지 볼 수 있습니다.
그리고 컴파일러는 StringBuilder
당신을 위해 무대 뒤에서 멋진 것을 할 것입니다.
참고 URL : https://stackoverflow.com/questions/1235179/simple-way-to-repeat-a-string-in-java
'Programming' 카테고리의 다른 글
build.gradle 파일에 로컬 .jar 파일 종속을 추가하는 방법? (0) | 2020.02.10 |
---|---|
RecyclerView onClick (0) | 2020.02.10 |
jQuery Selector (“parent > child”) (0) | 2018.03.11 |
jQuery Selector :checked (0) | 2018.03.11 |
jQuery Selector :animated (0) | 2018.03.11 |