I have written a custom method to use StringBuilder in java. My Requirement is to create a method which accepts any number of arguments of any type and return String by concatenating the arguments.
eg. msgBuilder("Hello ",0," how"," are"," you ",2.5) return "Hello 0 how are you 2.5"
Here is my java code. Please Someone review my code and suggest If I did anything is wrong or Can I use this further in my projects.
public class Test {
public static void main(String[] args ){
String msg = msgBuilder("Hello ",5," How ","are ","you");
System.out.println(msg);
}
private static String msgBuilder(Object... params){
StringBuilder sb = new StringBuilder();
for(Object obj:params){
sb.append(obj);
}
return sb.toString();
}
}
4 Answers 4
I had this in mind:
private static String msgBuilder(Object... params) {
StringBuilder sb = new StringBuilder();
if (params.length > 0) {
sb.append(params[0]);
}
for (int i = 1; i < params.length; ++i) {
sb.append(" ").append(params[i]);
}
return sb.toString();
}
The above version allows you not to hardcode the white space delimiting your tokens. Instead of saying
String msg = msgBuilder("Hello ", 5, " How ", "are ", "you");
you can say succintly
String msg = msgBuilder("Hello", 5, "How", "are", "you");
Hope that helps.
Your approach
As pointed out by the other answers, you are practically hard-coding whitespaces in your arguments, which can get non-standard easily, even in your example. Otherwise, the use of StringBuilder is sound, although it wouldn't deal nicely with a single null value - the for-each loop will fail as it implicitly tries to get an Iterator for it.
Java 8
An alternative is to rely on the stream-based processing that Java 8 offers:
private static String format(Object... values) {
if (values == null) {
return "";
}
return Arrays.stream(values)
.map(Objects::toString)
.collect(Collectors.joining(" "));
}
- Construct a
Stream<Object>fromvaluesusingArrays.stream(T...). map()each value usingObjects.toString(Object)as a method reference.collect()the stream into aStringbyjoining(" ")them together.
-
\$\begingroup\$ Will it be as efficient as StringBuilder() \$\endgroup\$stux_kill– stux_kill2016年05月29日 06:39:47 +00:00Commented May 29, 2016 at 6:39
-
\$\begingroup\$ Yes, it uses the new
StringJoinerclass as the underlying implementation, which in turn uses aStringBuilder. \$\endgroup\$h.j.k.– h.j.k.2016年05月29日 07:22:21 +00:00Commented May 29, 2016 at 7:22
I just decompiled the below code in java version "1.8.0_73" and found that compiler is automatically optimizing the code for strings
String hello = "a" + "b" + "c" + " hello " + " world ";
System.out.println("Hello World!!");
String a="a";
String b="b";
String c="c";
String d=a+b+c;
System.out.println(d);
System.out.println(a +" yo "+ b);
Code after decompiling
String s = "abc hello world ";
System.out.println("Hello World!!");
String s1 = "a";
String s2 = "b";
String s3 = "c";
String s4 = (new StringBuilder()).append(s1).append(s2).append(s3).toString();
System.out.println(s4);
System.out.println((new StringBuilder()).append(s1).append(" yo ").append(s2).toString());
-
\$\begingroup\$ Hi. Welcome to Code Review! This may be insightful, but how does it relate to the question? I.e. what changes in the posted code would you make? \$\endgroup\$mdfst13– mdfst132016年05月31日 11:25:16 +00:00Commented May 31, 2016 at 11:25
-
\$\begingroup\$ As per my understanding, the query asked was to create strings in an optimize way. e.g. while printing logs we append too many strings using +. So above method was appending the strings using StringBuilder() But when I decompiled the code the java compiler was doing this optimzation itself. \$\endgroup\$munish– munish2016年05月31日 13:58:44 +00:00Commented May 31, 2016 at 13:58
@coderodde has a good point about eliminating the need for white space.
I'd simply do it this way:
private static String buildString(Object... values) {
if (values.length == 0) {
return "";
}
StringBuilder result = new StringBuilder();
for (Object value : values) {
result.append(' ').append(value);
}
return result.substring(1);
}
-
\$\begingroup\$ Nice Suggestion. Thanx! \$\endgroup\$stux_kill– stux_kill2016年05月27日 15:06:40 +00:00Commented May 27, 2016 at 15:06
Stringformatting, have you checked if your logging framework of choice has it? Also, are you on Java 8? \$\endgroup\$