通过 Java 8 个流 API 进行 StringBuilder 操作
StringBuilder manipulation via Java 8 Streams API
我很难从 StringBuilder 中删除一些字符。该方法工作正常。但是,我想通过 Java-8 流 API 实现相同的目的。当前代码冗长。有什么方法可以通过 Java 8 个流 API 重构第二个方法 removeCarryReturnsCharacters() 吗?
private static StringBuilder readEntireFileUsingStream(Path filePath) throws IOException {
StringBuilder data = new StringBuilder(String.valueOf(Files.readAllLines(filePath, StandardCharsets.ISO_8859_1)));
return removeCarryReturnsCharacters(data);
}
private static StringBuilder removeCarryReturnsCharacters(StringBuilder fileData){
int endIndex = 1012;
String needToRemove = "";
long totDataChunkCount = fileData.length()/1014;
long delCounter = 1;
try{
while (delCounter < totDataChunkCount) {
needToRemove = fileData.substring(endIndex, endIndex + 2);
if (needToRemove.equals("^^")) {
fileData.delete(endIndex, endIndex + 2);
}
endIndex += 1012;
delCounter++;
}
}catch(StringIndexOutOfBoundsException exp){
throw exp;
}
return fileData;
}
由于缺少 Stream API,当前代码并不冗长,但有大量不必要的操作:
- 初始分配
needToRemove = "";
已过时
- 您正在维护两个冗余循环变量,
delCounter
和 endIndex
- 你正在使用
while
循环,尽管你有一个带有初始语句、条件和递增操作的经典计数循环,确切地说,for
循环是为 创建的
- 您使用的
long
变量绝对不会超过 int
值范围
- 你有一个过时的
try … catch
块只是重新抛出捕获的异常
- 您不需要
needToRemove
变量来保存对象以供一次性使用;你可以简单地检查 if(fileData.substring(endIndex, endIndex + 2).equals("^^"))
或者,我更喜欢只检查两个字符,
if(fileData.charAt(endIndex)=='^' && fileData.charAt(endIndex+1)=='^')
解决所有这些问题将使方法变为
private static StringBuilder removeCarryReturnsCharacters(StringBuilder fileData) {
for(int endIndex = 1012; endIndex < fileData.length(); endIndex += 1012)
if(fileData.charAt(endIndex) == '^' && fileData.charAt(endIndex+1) == '^')
fileData.delete(endIndex, endIndex + 2);
return fileData;
}
我认为重写循环以使用 Stream 不会有任何额外的好处 API。
private static StringBuilder removeCarryReturnsCharacters(StringBuilder fileData) {
Stream.iterate(1012, i -> i + 1012)
.limit(fileData.length() / 1014)
.sorted(Collections.reverseOrder())
.forEach(e -> {
if (fileData.substring(e, e + 2).equals("^^")) {
fileData.delete(e, e + 2);
}
});
return fileData;
}
您似乎正试图从原始文件的各个行中删除 ^^
。您可以仅使用 File.lines
和 Stream.map
:
来解决这个问题
List<String> lines = Files.lines(filePath, StandardCharsets.ISO_8859_1)
.map(line -> {
if (line.charAt(endIndex) == '^' && line.charAt(endIndex + 1) == '^') {
return new StringBuilder(line).delete(endIndex, endIndex + 2).toString();
} else {
return line;
}
})
.collect(Collectors.toList());
我想这可能比
性能更差
new StringBuilder(String.valueOf(Files.readAllLines(...)))
However readAllLines read all lines into a List, but lines
populates lazily as the stream is consumed.
在这种情况下,如果我们使用一个大
StringBuilder
- 所有数据都先 读取 并 稍后 处理。相反 - 在 File.lines
的情况下,数据在 同时被处理和读取 。在文件的最后一行被流管道读取和处理后 - 将有一个删除了 ^^
个字符的文件行列表。
我很难从 StringBuilder 中删除一些字符。该方法工作正常。但是,我想通过 Java-8 流 API 实现相同的目的。当前代码冗长。有什么方法可以通过 Java 8 个流 API 重构第二个方法 removeCarryReturnsCharacters() 吗?
private static StringBuilder readEntireFileUsingStream(Path filePath) throws IOException {
StringBuilder data = new StringBuilder(String.valueOf(Files.readAllLines(filePath, StandardCharsets.ISO_8859_1)));
return removeCarryReturnsCharacters(data);
}
private static StringBuilder removeCarryReturnsCharacters(StringBuilder fileData){
int endIndex = 1012;
String needToRemove = "";
long totDataChunkCount = fileData.length()/1014;
long delCounter = 1;
try{
while (delCounter < totDataChunkCount) {
needToRemove = fileData.substring(endIndex, endIndex + 2);
if (needToRemove.equals("^^")) {
fileData.delete(endIndex, endIndex + 2);
}
endIndex += 1012;
delCounter++;
}
}catch(StringIndexOutOfBoundsException exp){
throw exp;
}
return fileData;
}
由于缺少 Stream API,当前代码并不冗长,但有大量不必要的操作:
- 初始分配
needToRemove = "";
已过时 - 您正在维护两个冗余循环变量,
delCounter
和endIndex
- 你正在使用
while
循环,尽管你有一个带有初始语句、条件和递增操作的经典计数循环,确切地说,for
循环是为 创建的
- 您使用的
long
变量绝对不会超过int
值范围 - 你有一个过时的
try … catch
块只是重新抛出捕获的异常 - 您不需要
needToRemove
变量来保存对象以供一次性使用;你可以简单地检查if(fileData.substring(endIndex, endIndex + 2).equals("^^"))
或者,我更喜欢只检查两个字符,
if(fileData.charAt(endIndex)=='^' && fileData.charAt(endIndex+1)=='^')
解决所有这些问题将使方法变为
private static StringBuilder removeCarryReturnsCharacters(StringBuilder fileData) {
for(int endIndex = 1012; endIndex < fileData.length(); endIndex += 1012)
if(fileData.charAt(endIndex) == '^' && fileData.charAt(endIndex+1) == '^')
fileData.delete(endIndex, endIndex + 2);
return fileData;
}
我认为重写循环以使用 Stream 不会有任何额外的好处 API。
private static StringBuilder removeCarryReturnsCharacters(StringBuilder fileData) {
Stream.iterate(1012, i -> i + 1012)
.limit(fileData.length() / 1014)
.sorted(Collections.reverseOrder())
.forEach(e -> {
if (fileData.substring(e, e + 2).equals("^^")) {
fileData.delete(e, e + 2);
}
});
return fileData;
}
您似乎正试图从原始文件的各个行中删除 ^^
。您可以仅使用 File.lines
和 Stream.map
:
List<String> lines = Files.lines(filePath, StandardCharsets.ISO_8859_1)
.map(line -> {
if (line.charAt(endIndex) == '^' && line.charAt(endIndex + 1) == '^') {
return new StringBuilder(line).delete(endIndex, endIndex + 2).toString();
} else {
return line;
}
})
.collect(Collectors.toList());
我想这可能比
性能更差new StringBuilder(String.valueOf(Files.readAllLines(...)))
However readAllLines read all lines into a List, but lines populates lazily as the stream is consumed.
在这种情况下,如果我们使用一个大
StringBuilder
- 所有数据都先 读取 并 稍后 处理。相反 - 在 File.lines
的情况下,数据在 同时被处理和读取 。在文件的最后一行被流管道读取和处理后 - 将有一个删除了 ^^
个字符的文件行列表。