2011-10-15 9 views
9

나는 자바를 사용하여 순간에 머드 (텍스트 기반 게임)를 쓰고있다. MUD의 주요 측면 중 하나는 문자열을 서식 지정하고이를 사용자에게 다시 보내는 것입니다. 이 최선의 방법은 무엇입니까? 자바 문자열 또는 형식을 구축하기 위해 연결

내가 다음 문자열 보내려는 말 : "안녕하세요"

당신은 누군가에게 말을 - "Someone", "say"및 "Hello!" 모든 변수입니다. 가장 현명한 성과는 무엇입니까?

"You " + verb + " to " + user + " \"" + text + "\""

또는

String.format("You %1$s to %2$s \"%3$s\"", verb, user, text)

또는 다른 옵션

?

마지막으로 사용하기가 더 쉬울 것이라는 점은 확실하지 않지만 (이는 어디에서나 볼 수 있기 때문에 중요합니다), +와 연결하기 때문에이 시점에서 생각하고 있습니다. 조금 더 큰 선들과 혼란스러워. 이 경우 StringBuilder를 사용하면 간단하게 읽을 수 없게됩니다.

여기에 어떤 제안이 있습니까?

+7

문제가 있거나 병목 현상이 아닌 이상 성능을 걱정하지 마십시오. 가장 가독성 있고 관리하기 쉬운 코드로 이어질 것이라고 생각하는 모든 것을하십시오. –

답변

17

문자열이 단일 연결 식을 사용하여 작성된 경우. 예 :

String s = "You " + verb + " to " + user + " \"" + text + "\""; 

는 다음이 더 긴 호흡에 더 많거나 적은 것과 같습니다

StringBuilder sb = new StringBuilder(); 
sb.append("You"); 
sb.append(verb); 
sb.append(" to "); 
sb.append(user); 
sb.append(" \""); 
sb.append(text); 
sb.append('"'); 
String s = sb.toString(); 

(사실, 자바 컴파일러는 거의 ... 후자에 전자를 컴파일합니다.)

+= 등을 사용하여 중간 문자열 생성 또는 문자열 작성을 시작할 때 효율성 문제가 발생합니다. 이 시점에서 StringBuilder은 생성되어 버려진 중간 문자열의 수를 줄이기 때문에 더 효율적입니다.

이제 String.format()을 사용할 때 후드 아래에 StringBuilder을 사용해야합니다. 그러나 format은 호출 할 때마다 형식 문자열을 구문 분석해야하며, 최적의 문자열 작성을 수행하지 않으면 오버 헤드가 발생합니다.


이렇게 말하면 내 조언은 가장 읽기 쉬운 방식으로 코드를 작성하는 것입니다. 프로파일이 인 경우 문자열을 작성하는 가장 효율적인 방법에 대해서만 걱정하면 실제 성능에 문제가 있음을 알 수 있습니다. (지금은 중요하지 않거나 관련성이없는 성능 문제를 해결할 방법을 생각하는 데 많은 시간을 할애하고 있습니다.)

또 다른 대답은 형식 문자열을 사용하면 여러 언어에 대한 지원이 단순해질 수 있다는 것입니다. 복수형, 성별 등과 같은 것에 관해서 당신이 할 수있는 것에 대한 한계가 있음에도 불구하고 이것은 사실입니다.

+1

자세한 설명을 주셔서 감사합니다. String.format은 a) 해결책으로 구축하고 b) 문자열을 훨씬 쉽게 읽을 수있게 만들어서 b) 이미 내 인생을 편하게 해줍니다. – two13

-1

String.format이 더 깨끗해 보입니다. 그러나 StringBuilder를 사용하고 추가 함수를 사용하여 원하는 문자열을 만들 수 있습니다.

1

plus와 함께 연결하면 컴파일러가 코드를 실행 방식으로 변형 할 수 있습니다. 문자열 형식으로 나는 모른다.

나는 플러스와 코카 테이션을 선호합니다. 나는 그것이 언더 앤드라고 생각합니다.

0

나는 정직하게 생각하고, 더 적은 타이핑을 원한다면 첫 번째 의견을 제시하거나, 더 많은 C 스타일의 방법을 찾고 싶다면 후자를 제안하십시오.

나는 여기에 1 ~ 2 분 동안 문제가 될 수 있다는 생각을 품었다. 그러나 나는 당신이 입력하고 싶은 정도에 달려 있다고 생각한다.

다른 사람이 생각 나세요?

+0

내 이유는 가독성에 관한 것입니다. 나는 "물건"+ "다른 물건"을 타이핑하는 것에 꽤 익숙해 있으며 다른 옵션을 사용하면 그 습관에서 벗어날 것입니다. 내가 원래 생각했던 것은 "You [verb] to [user] [text]"와 같은 것이었고 replaceall (class driven)을했기 때문에 setElement ("동사", 동사)와 같은 변수를 추가하면 침을 뱉었습니다 포맷 된 문자열을 되 돌린다). 그러나 .format를 우연히 발견하고 내 독창적 아이디어가 성능에 끔찍할 것이라고 생각했다. – two13

0

당신이 기본 스트링은 종종

문자열을 MyString = "당신 $ 1 $ 2 \"$ \ 3 ""

그리고 단지 대체 사본을 얻을 할 $ X처럼 템플릿을 저장 재사용하려한다면 네가 원하는대로

이것은 리소스 파일에도 적용됩니다.

+1

또한 여러 언어를 지원할 수 있습니다. http://download.oracle.com/javase/tutorial/i18n/resbundle/concept.html –

-2

성능면에서 최선의 방법은 아마도 StringBuffer를 사용하는 것입니다.

+1

동의하지 않습니다. ['StringBuilder'] (http://download.oracle.com/javase/1.5.0/docs/api/java/lang/StringBuilder.html) javadoc : 가능하면이 클래스를에서 사용하는 것이 좋습니다 대부분의 구현에서는 빠르기 때문에'StringBuffer'에 우선합니다. --- Btw., 문자열 연결이 그러한 응용 프로그램에서 병목 현상이라는 것을 나는 의심합니다. – michael667

+1

같은 차이점, 하나는 동기화 됨, 다른 하나는 동기화되지 않음. 동기화가 제대로 구현되면 경쟁이 없다면 그 차이는 무시해도됩니다.(그리고 분명히 경합이있을 경우 StringBuilder를 사용하고 싶지 않을 것입니다.) –

1

간단하게 유지하는 열쇠는 결코 그것을 보지 않는 것입니다. 다음은 의미하는 바입니다.

Joiner join = Joiner.on(" "); 

public void constructMessage(StringBuilder sb, Iterable<String> words) { 
    join.appendTo(sb, words); 
} 

가독성을 높이기 위해 Guava Joiner 클래스를 사용하고 있습니다. "가입"보다 더 명확 할 수있는 것은 무엇입니까? 연결에 관한 모든 불쾌한 비트는 멋지게 숨겨져 있습니다. Iterable을 사용하여 모든 종류의 데이터 구조에서이 메서드를 사용할 수 있습니다. List가 가장 명백합니다.

다음은 Guava ImmutableList를 사용하는 호출의 예입니다. 일반 목록보다 효율적입니다. 목록을 수정하는 모든 메소드가 예외를 throw하기 때문에 constructMessage()가 목록을 변경할 수 없기 때문에 올바르게 나타냅니다. 즉, 그냥)를 소비 :

StringBuilder outputMessage = new StringBuilder(); 
constructMessage(outputMessage, 
     new ImmutableList.Builder<String>() 
      .add("You", verb, "to", user, "\"", text, "\"") 
      .build()); 
0

내가 +와 그 연결이 String.format을 사용하는 것보다 더 읽을 생각합니다.

String.format은 숫자와 날짜를 형식화해야 할 때 유용합니다.