从代码点整数列表生成一个字符串对象?

如果我有一个 List< Integer >,它的整数值为 Unicode code point 数字。如何构造由这些代码点确定的字符的 String 对象?

例如:

List < Integer > codePoints = List.of( 100,111,103,128054 ) ;

... 或:

List < Integer > codePoints = "cat".codePoints().boxed().toList();

如何从 String 获取另一个值为 catcodePoints 对象?

maidh521 回答:从代码点整数列表生成一个字符串对象?

String has a constructor 接受 int 代码点数数组。

int[] ints = codePoints.stream().mapToInt(i -> i).toArray();
String string = new String(ints,ints.length);

转换 List -> Stream -> IntStream -> int[] -> String

,

ListStreamStringBuilderString

一种解决方案是将您的 List 转换为 Stream。然后将该流的元素收集到 StringBuilder 中。 StringBuilder 类提供了一个 appendCodePoint 方法,专门用于容纳代码点整数。当可变 StringBuilder 完成时,转换为不可变 String

String output = codePoints.stream().collect( StringBuilder :: new,StringBuilder :: appendCodePoint,StringBuilder :: append ).toString();

或不同的格式:

String output = 
        codePoints
                .stream()
                .collect( StringBuilder :: new,StringBuilder :: append )
                .toString();

这是一些示例代码。

String input = "dog?" ;
List < Integer > codePoints = input.codePoints().boxed().collect( Collectors.toList() );  // In Java 16+,replace the last part with simply `.toList()`.
String output = 
        codePoints
                .stream()
                .collect( StringBuilder :: new,StringBuilder :: append )
                .toString();

看到这个code run live at IdeOne.com

输入:狗?

代码点:[100,111,103,128054]

输出:狗?

要了解带有 StringBuilder 方法引用的代码的工作原理,请参阅 Java 8 Int Stream collect with StringBuilder

为了方便起见,我们可以为这段代码创建一个实用方法。为了安全起见,我们可以添加对 .filter 的调用以跳过 any invalid code point 号(负数或超过 Character.MAX_CODE_POINT)。

public static final String listOfCodePointsToString( List< Integer > codePoints )
{
    String output = 
            codePoints
                    .stream()
                    .filter( codePoint -> Character.isValidCodePoint​( codePoint ) )
                    .collect( StringBuilder :: new,StringBuilder :: append )
                    .toString();
    return output ;
}

看到那个code run live at IdeOne.com

,

现有的答案很好,但也有一种简单的“老式”方法,不需要使用功能接口或流。以下是最少且完整的示例代码:

package cp2string;

import java.util.List;

public class CP2String {

    public static void main(String[] args) {
        List< Integer> codePoints = List.of(100,-999,128054);
        Character BLACK_VERTICAL_RECTANGLE = '\u25AE';
        StringBuilder sb = new StringBuilder();

        for (int cp : codePoints) {
            sb.append(Character.toString(Character.isValidCodePoint(cp) ? cp : BLACK_VERTICAL_RECTANGLE));
        }
        System.out.println("sb=" + sb.toString());
    }
}

当代码运行时,这是输出:

sb=d▮og?

注意事项:

  • 输出中的黑色矩形表示样本数据中故意包含的无效代码点。
  • 静态方法 Character.toString​(int codePoint) 需要 JDK 11 或更高版本。
  • 可能需要更改字体才能正确呈现输出。我使用了 Segoe UI 符号
  • 如果考虑并行操作,显然使用基于流的方法是可行的方法,但对于不关心性能和可扩展性的场景,简单的方法可以说同样好。
本文链接:https://www.f2er.com/3799.html

大家都在问