突发奇想,想写一个压缩Java代码中冗余空白符的算法,但实际写起来,是真的复杂!)。
欢迎各位提出更简单的压缩算法
import cn.hutool.core.util.CharUtil;
public static String compressJava(File file) {
int inComment = 0;
final StringBuilder builder = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)))) {
while (reader.ready()) {
final String line = " " + reader.readLine().strip() + " ";
for (int i = 1; i < line.length() - 1; i++) {
final char bPre = builder.isEmpty() ? ' ' : builder.charAt(builder.length() - 1), tPre = line.charAt(i - 1), cur = line.charAt(i);
if (CharUtil.isBlankChar(cur) && !(CharUtil.isLetterOrNumber(tPre) && CharUtil.isLetterOrNumber(line.charAt(i + 1))))
continue;// 消除单个空白符:只要有一个是符号而非字母,就可以删除该单个空白符
if (bPre != tPre && CharUtil.isLetterOrNumber(bPre) && CharUtil.isLetterOrNumber(cur))
builder.append(' '); // 消除多个空白符:连续多个空白符被替换为一个空格
if (tPre == '/' && (cur == '*' || cur == '/')) { // 如果为注释
if (inComment > 0) // 如果多次声明注释
builder.deleteCharAt(builder.length() - 1);
else { // 如果首次声明注释
inComment = cur == '*' ? 2 : 1;
builder.append("*");
}
continue;
}
if (tPre == '*' && cur == '/') { // 关闭注释
if (i == line.length() - 2) { // 若块注释在行尾关闭(此时不关闭,直到下一代码行的出现)
builder.deleteCharAt(builder.length() - 1);
inComment = 1;
continue;
}
else // 若块注释在行内关闭
inComment = 0;
}
if (i == 1 && inComment == 1 && !(line.startsWith(" //") || line.startsWith(" /*"))) { // 关闭注释
builder.append("*/");
inComment = 0;
}
builder.append(cur);
}
}
return builder.toString();
} catch (IOException e) {
return "";
}
}
// 以下是hutool-Jar的代码,如果不想引入该Jar,就手动放上去
public static boolean isBlankChar(char c) {
return Character.isWhitespace(c)
|| Character.isSpaceChar(c)
|| c == '\ufeff'
|| c == '\u202a'
|| c == '\u0000'
// issue#I5UGSQ,Hangul Filler
|| c == '\u3164'
// Braille Pattern Blank
|| c == '\u2800'
// MONGOLIAN VOWEL SEPARATOR
|| c == '\u180e';
}
CharUtil.isLetterOrNumber(char c) {
return '0'<=c<='9' || 'a'<=c<='z' || 'A'<=c<='Z';
}