Programing

Java에서 Sprintf에 해당

lottogame 2020. 3. 24. 08:00
반응형

Java에서 Sprintf에 해당


Printf는 1.5 릴리스에서 Java에 추가되었지만 출력이 파일이 아닌 문자열 (Sprintf가 C에서 수행하는 것)이 아닌 문자열로 보내는 방법을 찾지 못하는 것 같습니다. 누구든지 이것을하는 방법을 알고 있습니까?


// Store the formatted string in 'result'
String result = String.format("%4d", i * j);

// Write the result to standard output
System.out.println( result );

형식구문 참조


@ 에릭슨.

문자열은 변경할 수없는 유형입니다. 그것들을 수정할 수 없으며 새로운 문자열 인스턴스 만 반환합니다.

이 때문에 "foo".format ()은 다음과 같이 호출되어야하므로 거의 의미가 없습니다.

string newString = "foo".format();

원래 Java 작성자 (및 .NET 작성자)는 "foo"를 수정하지 않고 대신 형식 메소드를 호출하고 입력 문자열을 전달하므로이 상황에서 정적 메소드가 더 의미가 있다고 결정했습니다.

편집 : Heh,이 사이트는 때때로 너무 재미있을 수 있습니다. 문자열이 불변 유형이라는 사실에 대해 언급 한 바 있습니다.

다음은 Format ()이 인스턴스 메소드로 바보가되는 이유의 예입니다. .NET (및 아마도 Java)에서 Replace ()는 인스턴스 메소드입니다.

당신은 이것을 할 수 있습니다 :

 "I Like Wine".Replace("Wine","Beer");

그러나 문자열은 변경할 수 없으므로 아무 일도 일어나지 않습니다. Replace는 새 문자열을 반환하려고 시도하지만 아무것도 할당되지 않습니다.

이로 인해 다음과 같은 일반적인 신인 실수가 많이 발생합니다.

// Contrived Example
inputText.Replace(" ","%20");

다시 말하지만 아무 일도 일어나지 않고 대신해야합니다.

inputText = inputText.Replace(" ","%20");

이제 문자열을 변경할 수 없다는 것을 이해하면 완벽하게 이해됩니다. 그렇지 않으면 혼란 스러울 수 있습니다. Replace의 올바른 위치는 Format의 위치에 String의 정적 메소드입니다.

 inputText = String.Replace(inputText," ", "%20");

이제 무슨 일이 일어나고 있는지 의심의 여지가 없습니다.

실제 질문은 왜이 프레임 워크의 작성자가 하나는 인스턴스 메소드 여야하고 다른 하나는 정적이어야한다고 결정 했습니까? 제 생각에는 둘 다 정적 메소드로보다 우아하게 표현되지만 에릭슨은 둘 다 인스턴스 메소드로 생각합니다.

당신의 의견에 관계없이, 진실은 정적 버전을 사용하여 실수하는 경향이 적고 코드를 이해하기 쉽다는 것입니다 (No Hidden Gotchas).

물론 인스턴스 메소드로서 완벽한 메소드가 있습니다. String.Length ()

int length = "123".Length();

이 상황에서 우리가 "123"을 수정하려고하지 않고 단지 검사 만하고 길이를 반환한다는 것은 명백합니다. 이것은 인스턴스 메소드의 완벽한 후보입니다.

불변 객체의 인스턴스 메소드에 대한 간단한 규칙 :

  • 동일한 유형의 새 인스턴스를 리턴해야하는 경우 정적 메소드를 사용하십시오.
  • 그렇지 않으면 인스턴스 메소드를 사용하십시오.

두 솔루션 모두 printf를 시뮬레이션하지만 다른 방식으로 작동합니다. 예를 들어, 값을 16 진 문자열로 변환하려면 다음 두 가지 솔루션이 있습니다.

  • format()가장 가까운 sprintf():

    final static String HexChars = "0123456789abcdef";
    
    public static String getHexQuad(long v) {
        String ret;
        if(v > 0xffff) ret = getHexQuad(v >> 16); else ret = "";
        ret += String.format("%c%c%c%c",
            HexChars.charAt((int) ((v >> 12) & 0x0f)),
            HexChars.charAt((int) ((v >>  8) & 0x0f)),
            HexChars.charAt((int) ((v >>  4) & 0x0f)),
            HexChars.charAt((int) ( v        & 0x0f)));
        return ret;
    }
    
  • replace(char oldchar , char newchar)다소 빠르지 만 꽤 제한적입니다.

        ...
        ret += "ABCD".
            replace('A', HexChars.charAt((int) ((v >> 12) & 0x0f))).
            replace('B', HexChars.charAt((int) ((v >>  8) & 0x0f))).
            replace('C', HexChars.charAt((int) ((v >>  4) & 0x0f))).
            replace('D', HexChars.charAt((int) ( v        & 0x0f)));
        ...
    
  • 다음과 같이 문자를 ret하나씩 추가하는 것으로 구성된 세 번째 솔루션이 있습니다 (문자는 서로 더하는 숫자입니다 !).

    ...
    ret += HexChars.charAt((int) ((v >> 12) & 0x0f)));
    ret += HexChars.charAt((int) ((v >>  8) & 0x0f)));
    ...
    

...하지만 그건 정말 못 생겼어.


PrintStream을 사용하여 OutputStream 인 무엇이든 printf를 수행 할 수 있습니다. 어떻게 든 문자열 스트림으로 인쇄합니다.

PrintStream ps = new PrintStream(baos);
ps.printf("there is a %s from %d %s", "hello", 3, "friends");
System.out.println(baos.toString());
baos.reset(); //need reset to write new string
ps.printf("there is a %s from %d %s", "flip", 5, "haters");
System.out.println(baos.toString());
baos.reset();

이 ByteArrayOutputStream과 같이 문자열 스트림을 만들 수 있습니다.

ByteArrayOutputStream baos = new ByteArrayOutputStream();

참고 URL : https://stackoverflow.com/questions/47045/sprintf-equivalent-in-java

반응형