4
\$\begingroup\$

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(); } } 
\$\endgroup\$
3
  • 1
    \$\begingroup\$Any particular reason why you are reinventing-the-wheel?\$\endgroup\$
    – h.j.k.
    CommentedMay 27, 2016 at 12:39
  • \$\begingroup\$Some logging frameworks allow parameterized String formatting, have you checked if your logging framework of choice has it? Also, are you on Java 8?\$\endgroup\$
    – h.j.k.
    CommentedMay 27, 2016 at 15:22
  • \$\begingroup\$Yes I am using java 8 and using apache4j Logger\$\endgroup\$
    – stux_kill
    CommentedMay 27, 2016 at 15:30

4 Answers 4

1
\$\begingroup\$

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.

\$\endgroup\$
    5
    \$\begingroup\$

    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(" ")); } 
    1. Construct a Stream<Object> from values using Arrays.stream(T...).
    2. map() each value using Objects.toString(Object) as a method reference.
    3. collect() the stream into a String by joining(" ") them together.
    \$\endgroup\$
    2
    • \$\begingroup\$Will it be as efficient as StringBuilder()\$\endgroup\$
      – stux_kill
      CommentedMay 29, 2016 at 6:39
    • \$\begingroup\$Yes, it uses the new StringJoiner class as the underlying implementation, which in turn uses a StringBuilder.\$\endgroup\$
      – h.j.k.
      CommentedMay 29, 2016 at 7:22
    2
    \$\begingroup\$

    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()); 
    \$\endgroup\$
    2
    • \$\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
      CommentedMay 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
      CommentedMay 31, 2016 at 13:58
    1
    \$\begingroup\$

    @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); } 
    \$\endgroup\$
    1
    • \$\begingroup\$Nice Suggestion. Thanx!\$\endgroup\$
      – stux_kill
      CommentedMay 27, 2016 at 15:06

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.