예를 들어 다음과 같이 String으로 만이 작업을 수행 할 수 있습니다.
String str="";
for(int i=0;i<100;i++){
str=i+str;
}
StringBuilder로 이것을 달성하는 방법이 있습니까? 감사.
예를 들어 다음과 같이 String으로 만이 작업을 수행 할 수 있습니다.
String str="";
for(int i=0;i<100;i++){
str=i+str;
}
StringBuilder로 이것을 달성하는 방법이 있습니까? 감사.
답변:
StringBuilder sb = new StringBuilder();
for(int i=0;i<100;i++){
sb.insert(0, Integer.toString(i));
}
경고 : 의 목적에 위배StringBuilder
되지만 요청한대로 수행됩니다.
더 나은 기술 (아직 이상적이지는 않지만) :
StringBuilder
.StringBuilder
작업을 완료 할 때.이것은 O ( n ²) 솔루션을 O ( n ) 으로 바꿉니다 .
아마도 내가 뭔가를 놓치고 있지만 다음과 같은 문자열로 마무리하고 싶 "999897969594...543210"
습니까?, 맞습니까?
StringBuilder sb = new StringBuilder();
for(int i=99;i>=0;i--){
sb.append(String.valueOf(i));
}
대체 솔루션으로 LIFO 구조 (예 : 스택)를 사용하여 모든 문자열을 저장하고 완료되면 모두 꺼내서 StringBuilder에 넣을 수 있습니다. 자연스럽게 배치 된 항목 (문자열)의 순서를 반대로합니다.
Stack<String> textStack = new Stack<String>();
// push the strings to the stack
while(!isReadingTextDone()) {
String text = readText();
textStack.push(text);
}
// pop the strings and add to the text builder
String builder = new StringBuilder();
while (!textStack.empty()) {
builder.append(textStack.pop());
}
// get the final string
String finalText = builder.toString();
ArrayDeque
대신을 사용해야합니다 Stack
. "보다 완전하고 일관된 LIFO 스택 작업 세트가 {@link Deque} 인터페이스 및 해당 구현에서 제공되며,이 클래스보다 우선적으로 사용해야합니다."
이 스레드는 꽤 오래되었지만 StringBuilder를 전달하여 채우는 재귀 솔루션에 대해 생각할 수도 있습니다. 이렇게하면 역 처리 등을 방지 할 수 있습니다. 반복을 사용하여 반복을 설계하고 종료 조건을 신중하게 결정하면됩니다.
public class Test {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
doRecursive(sb, 100, 0);
System.out.println(sb.toString());
}
public static void doRecursive(StringBuilder sb, int limit, int index) {
if (index < limit) {
doRecursive(sb, limit, index + 1);
sb.append(Integer.toString(index));
}
}
}
이 게시물을 우연히 발견했을 때 비슷한 요구 사항이있었습니다. 나는 양쪽에서 성장할 수있는 문자열을 만드는 빠른 방법을 원했습니다. 앞면과 뒷면에 임의로 새 문자를 추가합니다. 나는 이것이 오래된 게시물이라는 것을 알고 있지만, 문자열을 만드는 몇 가지 방법을 시도하도록 영감을 받았고 내 발견을 공유 할 것이라고 생각했습니다. 또한 여기에 일부 Java 8 구조를 사용하고 있는데, 이는 사례 4와 5에서 속도를 최적화 할 수있었습니다.
https://gist.github.com/SidWagz/e41e836dec65ff24f78afdf8669e6420
위의 요점에는 누구나 실행할 수있는 자세한 코드가 있습니다. 나는 이것에서 몇 가지 방법으로 끈을 키웠다. 1) StringBuilder에 추가, 2) @Mehrdad와 같이 StringBuilder 앞에 삽입, 3) StringBuilder의 앞과 끝에서 부분적으로 삽입, 4) 목록을 사용하여 끝에서 추가, 5) Deque를 사용하여 앞에서 추가합니다.
// Case 2
StringBuilder build3 = new StringBuilder();
IntStream.range(0, MAX_STR)
.sequential()
.forEach(i -> {
if (i%2 == 0) build3.append(Integer.toString(i)); else build3.insert(0, Integer.toString(i));
});
String build3Out = build3.toString();
//Case 5
Deque<String> deque = new ArrayDeque<>();
IntStream.range(0, MAX_STR)
.sequential()
.forEach(i -> {
if (i%2 == 0) deque.addLast(Integer.toString(i)); else deque.addFirst(Integer.toString(i));
});
String dequeOut = deque.stream().collect(Collectors.joining(""));
나는 전면 추가 사례에만 집중할 것입니다. case 2 및 case 5. StringBuilder의 구현은 내부 버퍼가 증가하는 방식을 내부적으로 결정하며, 전면 추가의 경우 모든 버퍼를 왼쪽에서 오른쪽으로 이동하는 것 외에 속도를 제한합니다. @Mehrdad에서 볼 수 있듯이 StringBuilder의 전면에 직접 삽입 할 때 걸리는 시간이 매우 높은 값으로 증가하는 동안 필요한 경우 길이가 90k 자 미만 (여전히 많음) 인 문자열 만 있어야하는 경우 전면 삽입은 끝에 추가하여 동일한 길이의 문자열을 작성하는 데 걸리는 시간과 동시에 문자열을 작성하십시오. 내가 말하는 것은 시간 페널티가 실제로 걷어차 고 엄청나게 크다는 것입니다.하지만 정말 거대한 스트링을 만들어야 할 때만 가능합니다. 데크를 사용하고 내 예제와 같이 끝에 문자열을 결합 할 수 있습니다.
실제로 케이스 2의 성능은 케이스 1보다 훨씬 빠르지 만 이해하지 못하는 것 같습니다. StringBuilder의 내부 버퍼의 성장은 전면 추가 및 후면 추가의 경우 동일하다고 가정합니다. 역할을했다면 힙 증가 지연을 피하기 위해 최소 힙을 매우 큰 양으로 설정하기도했습니다. 더 잘 이해하는 사람이 아래에 댓글을 달 수 있습니다.
Difference Between String, StringBuilder And StringBuffer Classes
String
String is immutable ( once created can not be changed )object. The object created as a
String is stored in the Constant String Pool.
Every immutable object in Java is thread-safe, which implies String is also thread-safe. String
can not be used by two threads simultaneously.
String once assigned can not be changed.
StringBuffer
StringBuffer is mutable means one can change the value of the object. The object created
through StringBuffer is stored in the heap. StringBuffer has the same methods as the
StringBuilder , but each method in StringBuffer is synchronized that is StringBuffer is thread
safe .
Due to this, it does not allow two threads to simultaneously access the same method. Each
method can be accessed by one thread at a time.
But being thread-safe has disadvantages too as the performance of the StringBuffer hits due
to thread-safe property. Thus StringBuilder is faster than the StringBuffer when calling the
same methods of each class.
String Buffer can be converted to the string by using
toString() method.
StringBuffer demo1 = new StringBuffer("Hello") ;
// The above object stored in heap and its value can be changed.
/
// Above statement is right as it modifies the value which is allowed in the StringBuffer
StringBuilder
StringBuilder is the same as the StringBuffer, that is it stores the object in heap and it can also
be modified. The main difference between the StringBuffer and StringBuilder is
that StringBuilder is also not thread-safe.
StringBuilder is fast as it is not thread-safe.
/
// The above object is stored in the heap and its value can be modified
/
// Above statement is right as it modifies the value which is allowed in the StringBuilder
어때 :
StringBuilder builder = new StringBuilder();
for(int i=99;i>=0;i--){
builder.append(Integer.toString(i));
}
builder.toString();
또는
StringBuilder builder = new StringBuilder();
for(int i=0;i<100;i++){
builder.insert(0, Integer.toString(i));
}
builder.toString();
그러나 이것으로 O (N) 대신 O (N ^ 2) 연산을하고 있습니다.
자바 문서의 스 니펫 :
Object 인수의 문자열 표현을이 문자 시퀀스에 삽입합니다. 전체적인 효과는 마치 두 번째 인수가 메서드에 의해 문자열로 변환되고 해당 문자열
String.valueOf(Object)
의 문자가 표시된 오프셋에서이 문자 시퀀스에 삽입 된 것과 똑같습니다 .
AbstractStringBuilder
삽입 된 내용을위한 공간을 찾기 위해 삽입 색인을지나 모든 내용 을 이동하기 때문입니다. 그러나 이것은 구현 세부 사항이지 원칙 중 하나가 아닙니다.