25

Is there a more elegant way of doing this in Java?

String value1 = "Testing";  
String test = "text goes here " + value1 + " more text";

Is it possible to put the variable directly in the string and have its value evaluated?

me_here
  • 2,329
  • 5
  • 19
  • 13

10 Answers10

63
   String test = String.format("test goes here %s more text", "Testing");

is the closest thing that you could write in Java

dfa
  • 114,442
  • 31
  • 189
  • 228
  • 4
    Thanks for the answer. I think I'll stick with concatenation, more readable with lots of variables. – me_here Apr 21 '09 at 15:11
29

A more elegant way might be:

 String value = "Testing"; 
 String template = "text goes here %s more text";
 String result = String.format(template, value);

Or alternatively using MessageFormat:

 String template = "text goes here {0} more text";
 String result = MessageFormat.format(template, value);

Note, if you're doing this for logging, then you can avoid the cost of performing this when the log line would be below the threshold. For example with SLFJ:

The following two lines will yield the exact same output. However, the second form will outperform the first form by a factor of at least 30, in case of a disabled logging statement.

logger.debug("The new entry is "+entry+".");
logger.debug("The new entry is {}.", entry);
toolkit
  • 49,809
  • 17
  • 109
  • 135
  • 2
    +1 for MessageFormat — I've been looking for that! – Avi Flax Dec 16 '10 at 20:46
  • Check out Rythm(https://github.com/greenlaw110/rythm/downloads), which allows you to do somethign like `String result = Rythm.render("text goes here @value more text", "Testing")`. Not only clearer than `String.format`, but also fast. It's 2 times faster than String.format – Gelin Luo Jul 01 '12 at 07:54
4

Rythm a java template engine now released with an new feature called String interpolation mode which allows you do something like:

String result = Rythm.render("Hello @who!", "world");

The above case shows you can pass argument to template by position. Rythm also allows you to pass arguments by name:

Map<String, Object> args = new HashMap<String, Object>();
args.put("title", "Mr.");
args.put("name", "John");
String result = Rythm.render("Hello @title @name", args);

Links:

Gelin Luo
  • 14,035
  • 27
  • 86
  • 139
1

It may be done by some template-libaries. But beware, Strings are immutable in Java. So in every case at some low level the concatenation will be done.

Mnementh
  • 50,487
  • 48
  • 148
  • 202
1

You'll always have to use some form of concatenation for this (assuming value1 isn't a constant like you show here).

The way you've written it will implicitly construct a StringBuilder and use it to concatenate the strings. Another method is String.format(String, Object...)1, which is analogous to sprintf from C. But even with format(), you can't avoid concatenation.

1 Yes, I know the anchor link is broken.

Community
  • 1
  • 1
Michael Myers
  • 188,989
  • 46
  • 291
  • 292
0

The problem is not if this is an elegant way or not. The idea behind using a template system may be that you put your template in a normal text file and don't have to change java code if you change your message (or think about i18ln).

Tom
  • 1
0

What you want is called String interpolation. It is not possible in Java, although JRuby, Groovy and probably other JVM languages do that.


Edit: as for elegance, you can use a StringBuffer or check the other poster's solution. But at the low level, this will always be concatenation, as the other posters said.

Miguel Ping
  • 18,082
  • 23
  • 88
  • 136
0

You can use this free library. It gives you sprintf like functionality. Or use String.format static method provided you use Java 5 or newer.

Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
0

Why do you think string concatenation isn't elegant?

If all you are doing is simple concatenation, I'd argue that code readability is more important and I'd leave it like you have it. It's more readable than using a StringBuilder.

Performance won't be the problem that most people think it is.

Read this from CodingHorror

A_M
  • 7,693
  • 6
  • 33
  • 37
  • I agree, I'll stick with concatenation over the .format method. I was hoping for string evaluation similar to PHP. – me_here Apr 21 '09 at 15:12
0

I would use a StringBuffer.. it's a common practise when you are dealing with strings. It may seem a bit when you see it for the first time, but you'll get quickly used to it..

String test = new StringBuffer("text goes here ").append(value1).append(" more text").toString();

Strings are immutable thus a new instance is created after every concatenation. This can cause performance issues when used in loops.

StringBuffer is mutable version of String - that means you can create one, modify it as you want and you have still only one instance. When desired you can get a String representation of the StringBuffer by calling it's toString() method.

Martin Lazar
  • 1,330
  • 16
  • 24
  • 1
    In most cases you can use StringBuilder instead. It has better performance. It's not thread-safe, but most of the time that's ok. – Sarel Botha Feb 11 '11 at 04:49
  • There's no need to use a StringBuilder/Buffer unless appending in a loop. The compiler will generate the same bytecode for new StringBuilder().append("hello").append(value1).toString() as for "hello" + value1; You can verify this by decompiling your class file with the javap command. – dnault May 31 '13 at 00:18