开发者

What classes do you use to make string templates?

What classes do you use to make string placeholders work?

 String template = "You have %1 tickets for %d",
 Br开发者_开发技巧r object = new Brr(template, {new Integer(1), new Date()});
 object.print();


You have two options:

  • java.util.Formatter
    • An interpreter for printf-style format strings. This class provides support for layout justification and alignment, common formats for numeric, string, and date/time data, and locale-specific output.
  • java.text.MessageFormat.
    • MessageFormat provides a means to produce concatenated messages in a language-neutral way. Use this to construct messages displayed for end users.

Of the two, MessageFormat is by far the more powerful. Here's an example of using ChoiceFormat to handle 0, 1, and >1 case differently:

import java.text.MessageFormat;
import java.util.Date;
//...

String p = "You have {0,choice,0#none|1#one ticket|1<{0,number,integer} tickets} for {1,date,full}.";
for (int i = 0; i < 4; i++) {
    System.out.println(MessageFormat.format(p, i, new Date()));
}

This prints:

You have none for Tuesday, June 1, 2010.
You have one ticket for Tuesday, June 1, 2010.
You have 2 tickets for Tuesday, June 1, 2010.
You have 3 tickets for Tuesday, June 1, 2010.

The documentation has many more examples.


How about java.util.Formatter?

Shorthands for it include String.format and System.out.format.


String.format is the easiest:

String s = String.format("%s %s", "Hello", "World!");

You can call it with a variable number of parameters, like I showed above, or pass it an array of Object and it'll use that.


The following should work:

import java.util.*;


class Brr {
    String template;
    Object[] args;
    public Brr(String template, Object... args) {
        this.template = template;
        this.args = args;
    }
    public void print() {
        System.out.println(String.format(template, args));
    }
}

public class Test {
    public static void main(String... args) {
        String template = "You have %d tickets for %tF";
        Brr object = new Brr(template, new Integer(1), new Date());
        object.print();
    }
}

Output:

You have 1 tickets for 2010-06-01

Have a look at http://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html if you want the full reference of conversions.


MessageFormat.format() allows me to use ordinal parameters, thus easily enabling i18n

private final Map<String, String> localizedMessages = new HashMap<String, String>();

private void init() {
    this.localizedMessages.put("de_DE", "{2} Suchtreffer, zeige Ergebnisse ${0} bis ${1}");
    this.localizedMessages.put("en_US", "Showing results {0} through {1} of a total {2");
}

public String getLocalizedMessage(final String locale,
        final Integer startOffset, final Integer endOffset,
        final Integer totalResults) {
    return MessageFormat.format(this.localizedMessages.get(locale),
            startOffset, endOffset, totalResults);

}


If you need something a little more powerful for templating strings the Apache Velocity library is pretty useful http://velocity.apache.org/


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("You have @num tickets for @date", 1, new Date());

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("num", 1);
args.put("date", new Date());
String result = Rythm.render("You have @num tickets for @date", args);

Links:

  • Check the full featured demonstration
  • read a brief introduction to Rythm
  • download the latest package or
  • fork it
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜