2

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

例如:

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

… 或者:

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

如何从 中获取另一个String具有值cat的对象codePoints

4

3 回答 3

3

String 有一个构造函数int,它接受一个代码点编号数组。

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

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

于 2021-08-01T04:44:29.917 回答
1

ListStreamStringBuilderString

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

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

或不同的格式:

String output = 
        codePoints
                .stream()
                .collect( StringBuilder :: new , StringBuilder :: appendCodePoint , 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 :: appendCodePoint , StringBuilder :: append )
                .toString();

请参阅在 IdeOne.com 上实时运行的代码

输入:狗

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

输出:狗

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

为方便起见,我们可以为此代码创建一个实用方法。为了安全起见,我们可以添加一个调用以.filter跳过任何无效的代码点编号(负数或超出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 :: appendCodePoint , StringBuilder :: append )
                    .toString();
    return output ;
}

查看在 IdeOne.com 上实时运行的代码

于 2021-07-31T22:28:51.123 回答
0

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

package cp2string;

import java.util.List;

public class CP2String {

    public static void main(String[] args) {
        List< Integer> codePoints = List.of(100, -999, 111, 103, 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

笔记:

  • 输出中的黑色矩形表示故意包含在示例数据中的无效代码点。
  • 静态方法需要 JDK 11 或更高版本 Character.toString​(int codePoint)
  • 可能需要更改字体才能正确呈现输出。我使用了 Segoe UI Symbol
  • 显然,如果考虑并行操作,则使用基于流的方法是可行的方法,但对于不关心性能和可伸缩性的场景,可以说简单的方法同样好。
于 2021-08-08T20:45:55.157 回答