[英]How to avoid the last new line in when writing to a File using the Stream API and Printwriter?
I am studying the Lambdas and Stream API that comes with Java 8. I wanted to create a file something like this using Stream API just for exercising purposes: 我正在研究Java 8附带的Lambdas和Stream API。我想使用Stream API创建一个类似于此类的文件,仅用于练习目的:
b
bb
bbb
bbbb
bbbbb
bbbb
bbb
bb
b
and this is the implementation I came up with: 这是我提出的实现:
final File file = new File("/Users/kt/sample.data");
final PrintWriter printWriter = new PrintWriter(file);
Stream.concat(IntStream.iterate(1, i -> i + 1).limit(6).boxed(),
IntStream.iterate(5, i -> i - 1).limit(5).boxed())
.map(counter -> {
StringBuilder stringBuilder = new StringBuilder();
IntStream.range(1, counter).forEach(c -> stringBuilder.append("b"));
return stringBuilder.toString();
}).filter(s -> s.length() != 0).forEach(s -> printWriter.println(s));
printWriter.flush();
printWriter.close();
Now the only problem is, I end up with an empty last line in the file, since printwriter is printing the last 'b' together with a new line. 现在唯一的问题是,我最终在文件中留下了一个空的最后一行,因为printwriter正在用新行打印最后一个'b'。
Obviously I can pass 4
instead of 5
to 2nd IntStream.iterate
I have and before flushing the printWriter
I can do: printWriter.print("b");
显然我可以传递
4
而不是5
到第二个IntStream.iterate
我已经和刷新printWriter
之前我可以做: printWriter.print("b");
, but my goal is to harness the Stream API. ,但我的目标是利用Stream API。
How can I achieve this more Streamy ? 我怎样才能实现更多Streamy ?
You can do you job much simpler as 你可以更简单地工作
Files.write(Paths.get("/Users/kt/sample.data"),
() -> IntStream.range(1, 10)
.<CharSequence>mapToObj(i -> "bbbbb".substring(Math.abs(5-i)))
.iterator());
Not to speak of 不说了
Files.write(Paths.get("C:\\Users\\pietsch\\AppData\\Local\\Temp\\output"),
Collections.singletonList("b\nbb\nbbb\nbbbb\nbbbbb\nbbbb\nbbb\nbb\nb"));
If it feels too much like cheating due to hardcoded invariants, change the code to allow to specify an arbitrary maximum string size: 如果由于硬编码不变量而感觉太像欺骗,请更改代码以允许指定任意最大字符串大小:
int size = 5;
int[] codepoints = IntStream.range(0, size).map(i -> 'b').toArray();
Files.write(Paths.get("/Users/kt/sample.data"),
() -> IntStream.range(1, size*2)
.<CharSequence>mapToObj(i -> new String(codepoints, 0, size-Math.abs(size-i)))
.iterator());
I recommend to use a variable to store the size, as there is several places that requires it : maxSize
我建议使用变量来存储大小,因为有几个地方需要它:
maxSize
print
, and as a tip you can simplify your use of StringBuilder
with a map
operation print
,作为提示,您可以通过map
操作简化StringBuilder
使用 int maxSize = 5;
String str =
IntStream.concat(IntStream.iterate(2, i -> i + 1).limit(maxSize),
IntStream.iterate(maxSize, i -> i - 1).limit(maxSize - 1))
.mapToObj(count -> IntStream.range(1, count).mapToObj(c -> "b").collect(Collectors.joining()))
.collect(Collectors.joining("\n"));
printWriter.print(str);
String
variable, would be add a \\n
between each block, then limit to remove the last one and print all, but this is not the more efficient between both : String
变量,将在每个块之间添加\\n
,然后限制删除最后一个并打印全部,但这两者之间的效率不是更高: int maxSize = 5;
IntStream.concat(IntStream.iterate(2, i -> i + 1).limit(maxSize),
IntStream.iterate(maxSize, i -> i - 1).limit(maxSize - 1))
.mapToObj(count -> IntStream.range(1, count).mapToObj(c -> "b").collect(Collectors.joining()))
.flatMap(b -> Stream.of(b, "\n"))
.limit((maxSize * 2 - 1) * 2 - 1)
.forEach(printWriter::print);
Do not know exactly what the Streamy way means, but how about this: 不知道Streamy方式到底意味着什么,但是这个怎么样:
int[] arr = new int[max * 2 - 1];
arr[(max * 2) / 2] = max;
IntStream.range(0, max)
.forEachOrdered(x -> {
arr[x] = x + 1;
arr[x + max - 1] = max - x;
});
String result = Arrays.stream(arr)
.mapToObj(x -> IntStream.range(0, x)
.mapToObj(i -> "b")
.collect(Collectors.joining()))
.collect(Collectors.joining("\n"));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.