记录英语单词时,想把英语和中文翻译分别对齐,有些人写代码喜欢把变量按这种方式对齐。在网上没搜到相关方法,于是自己试着写代码去实现,原本以为很简单,写的时候才发现有不少问题。先看效果:

普通的

对齐前:

对齐后:

发挥点创意

对齐前:

对齐后:

实现

实现的思路比较简单,读取文本文件,按正则分割,找出最长的部分,补齐空格,输出。

看起来相当简单,花了一个多小时,就写出来了,马上运行,发现输出一团糟,去查看每个部分的字符数,个数是一样的,网上一搜,原来跟字体有关系,好吧,那换个等宽的字体。换好字体后有些地方已经对齐了,有些地方还是没对齐,发现是中文的问题,中文宽度与英文宽度不相同,于是首先根据正则去判断字符是中文还是英文,然后自己实现计算字符长度的方法,在判断中文字符上折腾了许久,因为标点符号等等都要考虑进去,反正是来来回回试了好久,对Unicode编码范围不熟悉,没办法。终于,好像都搞定了,反复测试,突然发现第一行的对齐少了一个空格,尼玛,这是怎么回事啊,Debug发现第一行的最开始有一个奇怪的字符"\uFEFF",这他妈是什么鬼,上网搜,发现是Unicode编码的什么BOM头,好吧,不管它是什么鬼,直接把它去掉了……

反正是遇到了各种各样的问题,与字符集相关的问题实在是太头疼了。另外,我没有去处理编码的问题,所以文本的编码需要和IDE的编码保持一致,否则就会产生乱码。

源码

看过《重构》和《代码整洁之道》之后,写代码时时刻想着要写干净点,扩展性强点,经过反复修改,最终自己觉得还行吧,当然,肯定有不少值得改进的地方,现在就这样吧。

App.java

1 packagetextalign;2

3 importjava.io.IOException;4

5 /**

6 *@authortingl7 *@version2017/9/278 */

9 public classApp {10

11 public static voidmain(String[] args) {12 long start =System.currentTimeMillis();13

14 String filePath = "C:\\Users\\tingl\\Desktop\\Test2.txt";15 TextAlign textAlign = new TextAlign(/*",|。|,|[.]|( {2,})|\t| +"*/);16

17 if (args.length > 0) {18 filePath = args[0];19 }20 try{21 textAlign.align(filePath);22 } catch(IOException e) {23 e.printStackTrace();24 }25

26 System.out.println(System.currentTimeMillis() -start);27 }28 }

TextAlign.java

1 packagetextalign;2

3 importjava.io.IOException;4 importjava.util.List;5 importjava.util.regex.Pattern;6

7 /**

8 *@authortingl9 *@version2017/9/2710 */

11 public classTextAlign {12 private static final String CHINESE_CHARACTER = "[\u4e00-\u9fa5]|[\uFE30-\uFFA0]|[\u3000-\u303F]";13 private static final Pattern CHINESE_CHARACTER_PATTERN =Pattern.compile(CHINESE_CHARACTER);14 private static final int SEPARATE_SPACE_AMOUNT = 4;15

16 privateTextAlignFileUtil textAlignFileUtil;17 private ListtextLines;18 private int[] longestBlockLengths;19

20 publicTextAlign() {21 textAlignFileUtil = newTextAlignFileUtil();22 }23

24 publicTextAlign(String spiltRegex) {25 textAlignFileUtil = newTextAlignFileUtil(spiltRegex);26 }27

28 public void align(String filePath) throwsIOException {29 textLines =textAlignFileUtil.readToList(filePath);30 initLongestBlockLengths();31 fillTextLinesBySpaces();32 textAlignFileUtil.write();33 }34

35 private voidinitLongestBlockLengths() {36 int longestArrayLength = 0;37 for(String[] blocks : textLines) {38 if (blocks.length >longestArrayLength) {39 longestArrayLength =blocks.length;40 }41 }42 longestBlockLengths = new int[longestArrayLength];43 fillLongestBlockLengths();44 }45

46 private voidfillLongestBlockLengths() {47 for(String[] blocks : textLines) {48 if (blocks.length < 2) continue;49 for (int i = 0; i < blocks.length; i++) {50 int length =stringLengthFitWidth(blocks[i]);51 if (length >longestBlockLengths[i]) {52 longestBlockLengths[i] =length;53 }54 }55 }56 }57

58 private intstringLengthFitWidth(String s) {59 if (!CHINESE_CHARACTER_PATTERN.matcher(s).find()) {60 returns.length();61 }62 int length = 0;63 for (String c : s.split("")) {64 if(CHINESE_CHARACTER_PATTERN.matcher(c).find()) {65 length++;66 }67 length++;68 }69 returnlength;70 }71

72 private voidfillTextLinesBySpaces() {73 for(String[] blocks : textLines) {74 for (int i = 0; i < blocks.length - 1; i++) {75 String block =blocks[i];76 int spaceAmount = longestBlockLengths[i] - stringLengthFitWidth(block) +SEPARATE_SPACE_AMOUNT;77 blocks[i] = block +spaces(spaceAmount);78 }79 }80 }81

82 private String spaces(intspaceAmount) {83 StringBuilder spaces = newStringBuilder();84 for (int i = 0; i < spaceAmount; i++) {85 spaces.append(" ");86 }87 returnspaces.toString();88 }89 }

TextAlignFileUtil.java

1 packagetextalign;2

3 import java.io.*;4 importjava.util.ArrayList;5 importjava.util.Arrays;6 importjava.util.List;7

8 /**

9 *@authortingl10 *@version2017/9/2711 */

12 classTextAlignFileUtil {13 private static final String FILENAME_POSTFIX = "_aligned";14 private String spiltRegex = "( {2,})|\t";15 private ListtextLines;16 privateString outPath;17

18 TextAlignFileUtil() {19 }20

21 TextAlignFileUtil(String spiltRegex) {22 this.spiltRegex =spiltRegex;23 }24

25 List readToList(String path) throwsIOException {26 File file = newFile(path);27 returnreadToList(file);28 }29

30 private List readToList(File file) throwsIOException {31 getOutPath(file.getAbsolutePath());32 try (BufferedReader reader = new BufferedReader(newFileReader(file))) {33 textLines = new ArrayList<>();34 String line;35 while ((line = reader.readLine()) != null) {36 textLines.add(removeEmptyAndTrim(line.split(spiltRegex)));37 }38 }39 removeBomHead();40 returntextLines;41 }42

43 private voidgetOutPath(String srcPath) {44 int dotPosition = srcPath.lastIndexOf(".");45 outPath = srcPath.substring(0, dotPosition) + FILENAME_POSTFIX +srcPath.substring(dotPosition);46 if (newFile(outPath).exists()) {47 getOutPath(outPath);48 }49 }50

51 privateString[] removeEmptyAndTrim(String[] src) {52 for (int i = 0; i < src.length; i++) {53 src[i] =src[i].trim();54 }55

56 List dest = new ArrayList<>(Arrays.asList(src));57 dest.removeIf(String::isEmpty);58 return dest.toArray(new String[0]);59 }60

61 private voidremoveBomHead() {62 String[] blocks = textLines.get(0);63 blocks[0] = blocks[0].replace("\uFEFF", "");64 }65

66 void write() throwsIOException {67 try (BufferedWriter writer = new BufferedWriter(newFileWriter(outPath))) {68 for(String[] blocks : textLines) {69 writer.write(getLine(blocks));70 writer.newLine();71 writer.flush();72 }73 }74 }75

76 privateString getLine(String[] blocks) {77 StringBuilder sb = newStringBuilder();78 for(String block : blocks) {79 sb.append(block);80 }81 returnsb.toString();82 }83 }

java代码自动对齐_java程序实现编写代码时变量名垂直对齐的风格相关推荐

  1. Python语言学习:在python中,如何获取变量的本身字符串名字而非其值/内容及其应用(在代码中如何查找同值的所有变量名)

    Python语言学习:在python中,如何获取变量的本身字符串名字而非其值/内容及其应用(在代码中如何查找同值的所有变量名) 目录

  2. java 测试代码效率_JAVA程序的性能测试方法

    JAVA程序的性能测试方法 Java 1.5以上都在虚拟机里内建了程序性能跟踪的功能,并提供了Java Profiling API,简称JPA,你可以搜索'java profiling'.Java也提 ...

  3. 编写java程序的常见问题_Java程序的编写与执行、Java新手常见的问题解决

    原标题:Java程序的编写与执行.Java新手常见的问题解决 今天,我们来写一段Java程序.然后看看Java程序是如何执行的,以及Java新手小白遇到的问题和解决办法. HelloWorld的编写 ...

  4. java构造块_java中的静态代码块、构造代码块、构造方法详解

    运行下面这段代码,观察其结果: package com.test; public class HelloB extends HelloA { public HelloB() { } { System. ...

  5. Java 匿名存储过程_Java程序员的存储过程

    存储过程是指保存在数据库并在数据库端执行的程序.你可以使用特殊的语法在Java类中调用存储过程.在调用时,存储过程的名称及指定的参数通过JDBC连接发送给DBMS,执行存储过程并通过连接(如果有)返回 ...

  6. java自动封箱_Java程序员面试,自动封箱/拆箱原理与包装类的缓冲机制你知道么?(转)...

    概述 本文中小编为大家细致的讲解了Java中基本数据类型对应的包装类以及包装类的缓冲机制在实际开发中的应用 . 并且对Java中基本数据类型的包装类的主要应用---自动封箱.自动拆箱做了底层剖析 . ...

  7. 怎么短时间提高Java面试水平_Java程序员如何在面试时短时间内让面试官刮目相看?...

    技术面试是每一位程序员都会经历的一件事情,技术面试官会通过自己的方式去考察程序员的技术功底与基础理论知识,这个过程被有的程序员成为"造火箭式的技术轰炸",不同程序员的面试经历与体验 ...

  8. linux java后台运行_Java程序在Linux中实现后台运行

    1.运行脚本 脚本如下,这个脚本存在一点问题,Log4j稍微有点问题,但是对运行及日志记录没有影响,日志是通过将所有控制台数据全部写入文件的形式记录的. #!/bin/sh #author:wangc ...

  9. Java基础笔记(2) 程序入口 关键字 标识符 常量 变量

    提醒:关于那些和我一样新鸟来看资料的,能看懂多少看多少,看不懂的就是不重要,重要的你想我自己学习肯定要标注的,这些信息明白每个知识点实际作用就好了,其他的比如等会讲的常量内存,常量池这些都是我找的资料 ...

最新文章

  1. java编程思想(第四版)第二章练习题-12
  2. ajax点赞只能点一次,php+mysql+ajax局部刷新点赞取消点赞功能(每个账号只点赞一次).pdf...
  3. Ansible :一个配置管理和IT自动化工具
  4. python【蓝桥杯vip练习题库】BASIC-19完美的代价(贪心算法)
  5. 慢吞吞的pip切换源
  6. 机器学习-数据科学库(第六天)
  7. 成大事必备9种能力、9种手段、9种心态
  8. javascript随堂练习(分支,循环语句)
  9. windows redis批量删除前缀的key_阿里官方Redis开发规范!
  10. UVA 11552——Fewest Flops
  11. java设计模式之模板模式
  12. 移动文件读/写指针----lseek
  13. 如何打造一个搞垮公司的产品?
  14. bzoj1047 [HAOI2007]理想的正方形 单调队列
  15. hexo html代码高亮,使用 prismjs 自定义 Hexo 代码高亮
  16. 为什么我得到javafx.fxml.LoadException甚至fxml文件的路径都是正确的
  17. 基于STM32设计的酒驾报警系统
  18. php 正则过滤中英文标点
  19. 2022国赛论文及可运行代码
  20. Java实现 LeetCode 113 路径总和 II

热门文章

  1. 叉乘分配律的几何证明
  2. php东软期末,大连东软期末C语言考试题库(20131208总结).docx
  3. Java实现二分图的最大匹配
  4. 页面报206错误,可能是nginx导致的
  5. Vue3和Vite实现极客时间官网首页
  6. VC++使用URI Scheme实现从web网页上打开本地C++应用程序(附源码)
  7. 【转载】基于深度卷积网络方法的高光谱图像分类
  8. Python - 两数之和
  9. 关于sql注入中的 --+
  10. 微信小游戏 实战-让一张图片自动在屏幕上滚动