It’s possible to build up and combine unprocessed RAW template snippets, then combine and process them together:
static int[] val = new int[] { 2048, 31337, 0xbeefcace, 9000, 4711, 1337, 2100, 2600 }; @Benchmark public String toStringFMTCombineHex8() { var templates = new ArrayList<StringTemplate>(); for (int i = 0; i < 8; i++) { int h = val[i]; templates.add(RAW."%x\{h}"); } return StringTemplate.combine(templates).process(FMT); } Performance is… not great, but I think we can and should work on that: Benchmark Mode Cnt Score Error Units StringBuilders.toStringFMTCombineHex8 avgt 15 2421,151 ± 646,501 ns/op /Claes 2 okt. 2023 kl. 14:46 skrev 温绍锦(高铁) <shaojin.we...@alibaba-inc.com>: Using String Template FMT has better performance and better code readability. But String Template does not yet support for/while/if/switch. Is there any plan to enhance String Template to support for/while/if/switch? The following scenarios cannot be implemented using String.format or String Template. I think whether to build in support for foo(bar(x)) depends on whether it is a common enough method. ```java package java.net; class Inet6Address extends InetAddress { static String numericToTextFormat(byte[] src) { StringBuilder sb = new StringBuilder(39); for (int i = 0; i < (INADDRSZ / INT16SZ); i++) { sb.append(Integer.toHexString(((src[i<<1]<<8) & 0xff00) | (src[(i<<1)+1] & 0xff))); if (i < (INADDRSZ / INT16SZ) -1 ) { sb.append(":"); } } return sb.toString(); } } class SocketPermission { private boolean authorizedIPv6(String cname, byte[] addr) { String authHost = ""; InetAddress auth; try { StringBuilder sb = new StringBuilder(39); for (int i = 15; i >= 0; i--) { sb.append(Integer.toHexString(((addr[i]) & 0x0f))); sb.append('.'); sb.append(Integer.toHexString(((addr[i] >> 4) & 0x0f))); sb.append('.'); } ... } } ``` ```java package sun.security.krb5.internal.crypto.dk; class DkCrypto { static String bytesToString(byte[] digest) { // Get character representation of digest StringBuilder digestString = new StringBuilder(); for (int i = 0; i < digest.length; i++) { if ((digest[i] & 0x000000ff) < 0x10) { digestString.append('0').append(Integer.toHexString(digest[i] & 0x000000ff)); } else { digestString.append( Integer.toHexString(digest[i] & 0x000000ff)); } } return digestString.toString(); } } ``` - wenshao ------------------------------------------------------------------ 发件人:Mark Reinhold <mark.reinh...@oracle.com> 发送时间:2023年10月2日(星期一) 20:19 收件人:Claes Redestad <claes.redes...@oracle.com> 抄 送:温绍锦(高铁) <shaojin.we...@alibaba-inc.com>; core-libs-dev@openjdk.org <core-libs-dev@openjdk.org> 主 题:Re: Adding appendHex method to StringBuilder 2023/10/2 7:22:55 -0400, claes.redes...@oracle.com: > I think this goes against the grain: StringBuilder is a simple builder > for non-localized unformatted output. For formatted output there’s > Formatter, String.format and, with JEP 430[1], FMT."..." to help output > string data in more advanced, formatted and localized ways. Agreed. If we were to introduce a `fooBar(x)` method for every common `foo(bar(x))` expression in the JDK code base then our APIs would fast become inscrutable. - Mark