Printf добавлен в Java с выпуском версии 1.5, но я не могу найти способ отправки вывода в строку, а не в файл (что и делает sprintf на C). Кто-нибудь знает как это сделать?
Эквивалент Sprintf в Java
Ответ 1
// Store the formatted string in 'result'
String result = String.format("%4d", i * j);
// Write the result to standard output
System.out.println( result );
Ответ 2
@erickson.
Строки - это неизменные типы. Вы не можете их изменять, только возвращаете новые экземпляры строк.
Из-за этого "foo".format() имеет мало смысла, поскольку его нужно было бы называть как
string newString = "foo".format();
Оригинальные авторы java (и авторы .NET) решили, что статический метод имеет больше смысла в этой ситуации, поскольку вы не изменяете "foo", а вместо этого вызываете метод format и передаете входную строку.
EDIT: Хех, этот сайт может быть настолько забавным иногда. Я получил downvoted за упоминание того факта, что строки являются неизменяемыми типами.
Вот пример того, почему Format() будет немым как метод экземпляра. В .NET(и, вероятно, в Java) Replace() - это метод экземпляра.
Вы можете сделать это:
"I Like Wine".Replace("Wine","Beer");
Однако ничего не происходит, потому что Строки неизменяемы. Заменить пытается вернуть новую строку, но ей ничего не назначено.
Это вызывает множество распространенных ошибок новобранец, например:
// 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", мы просто проверяем его и возвращаем его длину... Это идеальный кандидат для метода экземпляра.
Мои простые правила для методов экземпляра на неизменяемых объектах:
- Если вам нужно вернуть новый экземпляр того же типа, используйте статический метод.
- В противном случае используйте метод экземпляра.
Ответ 3
Оба решения работают для моделирования printf, но по-другому. Например, чтобы преобразовать значение в шестую строку, у вас есть два следующих решения:
-
с
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))); ...
-
Существует третье решение, состоящее только из простого добавления char в
ret
(char - числа, которые добавляют друг к другу!), например, в:... ret += HexChars.charAt((int) ((v >> 12) & 0x0f))); ret += HexChars.charAt((int) ((v >> 8) & 0x0f))); ...
... но это будет действительно уродливо.
Ответ 4
Вы можете сделать printf для всего, что является OutputStream с PrintStream. Как-то так, печать в потоке строки:
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();