使用 System.out::print 打印 String[] 时如何附加分隔符字符串?

How to append a separator string when using System.out::print to print String[]?

我正在努力学习并熟悉使用 lambda、流和方法引用 - 所有新奇的 Java 11 东西。

我想排序并打印出字符串数组,同时保持 null 不变。 在最后一行,如何打印带有 spaces 的名称? (一般情况是打印每个名称和一条消息)。 当前输出为:

nullGoyleMalfoyCrabbe

我要

null Goyle Malfoy Crabbe

最后一个元素后没有 space。

ArrayList<String> enemies = new ArrayList<>(Arrays.asList("Malfoy", "Crabbe", "Goyle", null));
List<String> es = enemies.stream().map(object -> Objects.toString(object,null)).collect(Collectors.toList());
String[] as = es.toArray(String[]::new);
Arrays.sort(as, Comparator.nullsFirst((a,b) -> a.length() - b.length()));
Arrays.stream(as).forEach(System.out::print);

最简单的解决方案是在每个列表条目后添加一个空格:

Arrays.stream(as).map(s -> s + " ").forEach(System.out::print);

但这也会在末尾添加一个空格。

从Java8开始有StringJoiner可以配置分隔符,前缀和后缀:

StringJoiner s = new StringJoiner("my separator", "my prefix", "my suffix");
s.add("str 1");
s.add("str 2");
System.out.print(s.toString());

还有一个 Collector 可以加入 Streams(在底层使用 StringJoiner):

String s = myStream.collect(Collectors.joining("my separator", "my prefix", "my suffix"));
System.out.print(s);

StringJoiner 只在元素 之间添加分隔符 ,而不是在末尾。如果您想在 StringJoiner 末尾添加内容,则必须添加后缀。

您可以像下面这样使用 method reference

Arrays.stream(as).forEach(enem -> System.out.print(enem + " "));

你只需要 join:

System.out.print(String.join(" ", as));

流(恕我直言)的优点之一是方法链接。我会尝试这样的事情,在流管道中做所有事情:

    String output = Stream.of("Malfoy", "Crabbe", "Goyle", null)
            .map(object -> Objects.toString(object,null))
            .sorted(Comparator.nullsFirst(Comparator.comparingInt(String::length)))
            .collect(Collectors.joining(" "));
    System.out.format("Result is \"%s\".%n", output);

输出为:

Result is "null Goyle Malfoy Crabbe".

您注意到 Crabbe 之后没有 space。

如果您已经有数组,可以将其传递给 Arrays.stream()Stream.of() 以创建第一个流。