Java 将'IntStream'打印为'String'的最简单方法`
使用Java-8,我可以使用Java 将'IntStream'打印为'String'的最简单方法`,java,java-8,java-stream,Java,Java 8,Java Stream,使用Java-8,我可以使用chars或codePoints方法轻松地将字符串(或任何CharSequence)视为IntStream IntStream chars = "Hello world.".codePoints(); 然后我可以操纵流的内容 IntStream stars = chars.map(c -> c == ' ' ? ' ': '*'); 我一直在寻找一个整洁的方式来打印结果,我甚至找不到一个简单的方式。如何将ints流放回可以像打印字符串一样打印的表单中 从上面
chars
或codePoints
方法轻松地将字符串(或任何CharSequence
)视为IntStream
IntStream chars = "Hello world.".codePoints();
然后我可以操纵流的内容
IntStream stars = chars.map(c -> c == ' ' ? ' ': '*');
我一直在寻找一个整洁的方式来打印结果,我甚至找不到一个简单的方式。如何将int
s流放回可以像打印字符串一样打印的表单中
从上面的stars
我希望打印
***** ******
但是,“你好,世界。”.replaceAll(“[^]”),“*”
更简单。并非所有产品都能从lambdas中获益。效率稍低,但更简洁地解决了Holger的问题:
String result=“你好,世界。”
.codePoints()
.mapToObj(c->c==“”?:“*”)
.collect(收集器.joining());
Collectors.joining()
在内部使用StringBuilder
,至少在。其他答案说明如何将字符串流收集到单个字符串中,以及如何从IntStream
中收集字符。此答案显示了如何在字符流上使用自定义收集器
如果您想将int流收集到字符串中,我认为最干净、最通用的解决方案是创建一个
返回一个收集器。然后您可以像往常一样使用Stream.collect
方法
此实用程序可以按如下方式实现和使用:
public static void main(String[] args){
String s = "abcacb".codePoints()
.filter(ch -> ch != 'b')
.boxed()
.collect(charsToString());
System.out.println("s: " + s); // Prints "s: acac"
}
public static Collector<Integer, ?, String> charsToString() {
return Collector.of(
StringBuilder::new,
StringBuilder::appendCodePoint,
StringBuilder::append,
StringBuilder::toString);
}
publicstaticvoidmain(字符串[]args){
字符串s=“abcacb”.codePoints()
.filter(通道->通道!=“b”)
.boxed()
.collect(charsToString());
System.out.println(“s:+s);//打印“s:acac”
}
公共静态收集器charsToString(){
返回收集器(
StringBuilder::新建,
StringBuilder::appendCodePoint,
StringBuilder::append,
StringBuilder::toString);
}
标准库中没有这样的东西,这有点令人惊讶
这种方法的一个缺点是需要对字符进行装箱,因为IntStream
接口不能与收集器一起工作
一个尚未解决的难题是实用方法的名称。收集器实用程序方法的约定是调用它们toXXX
,但是toString
已被采用。您可以直接使用以下代码执行此操作:-
"Hello world".codePoints().forEach(n -> System.out.print(n == ' ' ? ' ':'*'));
有一个简单的答案,它稍微不倾向于使用流媒体做任何事情。因此,它不是一行,但可能更有效,更容易阅读:
public static String stars(String t) {
StringBuilder sb = new StringBuilder(t.length());
t.codePoints().map(c -> c == ' ' ? ' ' : '*').forEach(sb::appendCodePoint);
return sb.toString();
}
有时short和concrete不一样,我认为任何人都不必怀疑上面的函数是如何运行的
此解决方案确保永远不会将代码点转换回字符。因此,它比这里列出的其他一些解决方案更通用。如果我们必须这样做,我们可以用这种极其丑陋的方式制作一行:
public static String stars(String t) {
return t.codePoints().map(c -> c == ' ' ? ' ': '*').mapToObj(i -> new String(new int[] { i }, 0, 1)).collect(Collectors.joining());
}
它执行与相同的版本,但始终使用流媒体。显然需要一些函数将单个代码点转换为字符串:
public static String stars(String t) {
return t.codePoints().map(c -> c == ' ' ? ' ': '*').mapToObj(Stars::codePointToString).collect(Collectors.joining());
}
private static String codePointToString(int codePoint) {
return new String(new int[] { codePoint }, 0, 1);
}
这将这些函数放置在类中,当然是星号。您可以执行以下操作:
chars.mapToObj(c -> c == ' ' ? " ": "*").collect(joining());
另一个例子:
以下示例返回原始字符串。但这些操作可以与其他中间操作结合使用,如filter()
我的方法是使用reduce。要获得每个字符的*和每个空格的空格,它将如下所示
String hello = "hello world";
String result = hello.chars()
.map(val -> (val == ' ') ? ' ' : '*')
.mapToObj(val -> String.valueOf((char) val))
.reduce("",(s1, s2) -> s1+s2);
关键是要对整数执行任何操作,而不是将其强制转换为字符,然后将其映射到字符串,然后将其连接起来,您可以使用reduce或Collectors.joining()这怎么样
System.out.println(stars.mapToObj(c->String.format(“%c”,c)).collect(
连接());
或
字符串s=stars.mapToObj(c->String.format(“%c”,c)).reduce(“,
(a,b)->a+b);
这对我很有用。我对此感到高兴。我理解你关于过度使用lambdas的观点——我的例子只是一个例子。我知道,我无法抗拒。更复杂的字符转换甚至可以从并行执行中受益……这一点都不简单。这些东西应该从Java中删除,并变得更加复杂simple@GeorgiosPligoropoulos这里不是讨论Java应该是什么或不是什么的合适地方。@GeorgiosPligoropoulos Stackoverflow仍然不是这样讨论的合适地方。顺便说一下,这是answer开发的一个阶段。欢迎大家发表意见。很好!谢谢-当然有点整洁。为什么效率会低一些?@MaartenBodewes,因为它会在加入字符之前将每个字符转换为字符串。啊,好的。您认为我的解决方案如何:我不经常使用流。customTag=secureRandom.ints(9,0,chrs.length()).mapToObj(I->chrs.charAt(I)).collector(Collectors.joining())代码>产生IDE编译错误方法collect(CollectorMy解决方案不收集字符串,但收集int
s。事实上,它使用的操作与您的解决方案几乎完全相同。唯一的区别是它不需要装箱,正确处理补充代码点,并且更紧凑。没有用于此目的的内置收集器的原因正是disadvan您命名的阶段:由于IntStream
不支持Collector
s,因此需要装箱。另一方面,如果您不介意装箱开销,使用Collector.joining()的解决方案
就足够了。@霍尔格:在使用收集器时。加入必须将字符包装成字符串,这稍微贵一点,并且不能清楚地表达意图。在使用int-streams时,不能使用收集器。这为收集器使用盒装字符的方法提供了一些理由。这也可能会导致是个好主意
chars.mapToObj(i -> String.valueOf((char) i)).collect(Collectors.joining()));
"abc".chars().mapToObj(i -> "" + (char) i)).collect(Collectors.joining()));
String hello = "hello world";
String result = hello.chars()
.map(val -> (val == ' ') ? ' ' : '*')
.mapToObj(val -> String.valueOf((char) val))
.reduce("",(s1, s2) -> s1+s2);
IntStream charStream = "hello".chars();
charStream.mapToObj(c -> (char)c).forEach(System.out::println);