How to including variables within strings? [duplicate]
Asked Answered
T

6

186

So, we all should know that you can include variables into strings by doing:

String string = "A string " + aVariable;

Is there a way to do it like:

String string = "A string {aVariable}";

In other words: Without having to close the quotation marks and adding plus signs. It's very unattractive.

Trapezohedron answered 10/3, 2012 at 3:9 Comment(9)
@Chandra Please don't ask why, but rather explain if possible. It's just how I'd prefer to do it. Thanks.Trapezohedron
Use Groovy, then you'll be able to do "A string ${aVariable}" all you want.Aboard
There's a whole variety of techniques for similar things discussed in this question, but String.format() is built-in to the language.Chalybeate
@KalebBrasee That sounds perfect, but I am always hesitant when it comes to modifying languages. I don't want to set myself back.Trapezohedron
@GrayAdams Groovy doesn't set you back, it sets you free! :DAboard
tutorial hereBrowse
@owlstead: actually the best reference for this is the java.util.Formatter API since it gives all the dirty details needed to make the format Strings sing.Entanglement
@HovercraftFullOfEels It was the first hit that google "print variable in string java" turned up.Browse
But why do you prefer it that way? WHy do you want another syntax for the same thing? And what's the basis for your expectation that Java syntax should exist just the way you like it?Choke
E
187

You can always use String.format(....). i.e.,

String string = String.format("A String %s %2d", aStringVar, anIntVar);

I'm not sure if that is attractive enough for you, but it can be quite handy. The syntax is the same as for printf and java.util.Formatter. I've used it much especially if I want to show tabular numeric data.

Entanglement answered 10/3, 2012 at 3:12 Comment(8)
I know this is a matter of opinion, but I don't see how format is more attractive than a simple String concatenation expression. Where format comes into its own is when you need to do padding, number formatting, etcetera.Desberg
@StephenC: I don't disagree with you at all. But it is a useful alternative for String formatting especially when needing to do padding as you say and as I say above (i.e., to show tabular numeric data). I've used it quite a bit for formatting blood chemistry and CBC result reports.Entanglement
@StephenC I like format for a few reasons: first of all, '%d' uses the platform line delimiter. Second, you can easily find all variables at the end. You can easily reformat or even reorder the variables you input. It's easier to avoid mistakes (like 1 + "oops"), especially if you use FindBugs (which parses format strings and input parameters). And, as the asker says, in many cases it's more readable. Of course, it's a shame that the format method has been made static, that was a rather stupid design mistake.Browse
@owlstead - "Of course, it's a shame that the format method has been made static, that was a rather stupid design mistake.". Huh? How would format relate to the target string? Surely you are not suggesting that we should be expected to write "A String %s %2d".format(aStringVar, anIntVar) ... are you?Desberg
@StephenC And why not? Although renaming the method to e.g. asFormat would make more sense. Of course, the fact that Eclipse does not work that well with static imports makes it a bit more painful to use the current String.format as well.Browse
@owlstead - "And why not?" - because I think that most developers would think it looks unnatural. Anyway, I imagine that the Java designers considered this option. The Eclipse issue is not relevant to the API design issue. The Java designers cannot be blamed for faults in an IDE created by a different company.Desberg
@owlstead - "asFormat" wouldn't be right. It implies that the method is creating and returning a format object.Desberg
I have a reason. When I use log4j I use interpolation for log.error() and so on, and, immediately I will usually throw a custom exception with the same message, but I cannot quickly copy/paste the same string due to lack of interpolation in the same style. At that moment you start to wonder how to minimize the effort.Copley
H
101

This is called string interpolation; it doesn't exist as such in Java.

One approach is to use String.format:

String string = String.format("A string %s", aVariable);

Another approach is to use a templating library such as Velocity or FreeMarker.

Hulburt answered 10/3, 2012 at 3:15 Comment(0)
R
56

Also consider java.text.MessageFormat, which uses a related syntax having numeric argument indexes. For example,

String aVariable = "of ponies";
String string = MessageFormat.format("A string {0}.", aVariable);

results in string containing the following:

A string of ponies.

More commonly, the class is used for its numeric and temporal formatting. An example of JFreeChart label formatting is described here; the class RCInfo formats a game's status pane.

Rectal answered 10/3, 2012 at 4:41 Comment(2)
For somebody coming from CSharp this way is more straightforward since it is similar to string.Format in C#.Sukkah
I much prefer this due to how clean and reusable a variable is, compared to the String.format() method.Boltonia
S
37

Since Java 15, you can use a non-static string method called String::formatted(Object... args)

Example:

String foo = "foo";
String bar = "bar";

String str = "First %s, then %s".formatted(foo, bar);     

Output:

"First foo, then bar"

School answered 15/10, 2020 at 16:9 Comment(0)
T
21

Apache Commons Text's StringSubstitutor can be used. See the library's Dependency Information for how to include it in a project.

import org.apache.commons.text.StringSubstitutor;
// ...
Map<String, String> values = new HashMap<>();
values.put("animal", "quick brown fox");
values.put("target", "lazy dog");
StringSubstitutor sub = new StringSubstitutor(values);
String result = sub.replace("The ${animal} jumped over the ${target}.");
// "The quick brown fox jumped over the lazy dog."

This class supports providing default values for variables.

String result = sub.replace("The number is ${undefined.property:-42}.");
// "The number is 42."

To use recursive variable replacement, call setEnableSubstitutionInVariables(true);.

Map<String, String> values = new HashMap<>();
values.put("b", "c");
values.put("ac", "Test");
StringSubstitutor sub = new StringSubstitutor(values);
sub.setEnableSubstitutionInVariables(true);
String result = sub.replace("${a${b}}");
// "Test"

The library can be found on Maven central repository. This is the Maven dependency:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-text</artifactId>
    <version>1.10.0</version>
</dependency>
Tabaret answered 19/4, 2021 at 1:25 Comment(0)
S
3

you can use String format to include variables within strings

i use this code to include 2 variable in string:

String myString = String.format("this is my string %s %2d", variable1Name, variable2Name);

Seka answered 18/7, 2020 at 10:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.