Java常见问题

介绍

记录在日常使用Linux过程中遇到的一些问题,便于之后查找

问题描述

java中使用replace替换字符串中的\及\ \

原因:

\常用作转码,故不能直接使用\进行替换

解决方案:

使用\ \ \ \进行对\的替换,使用\ \ \ \ \ \ \ \进行\ \的替换

1
2
3
4
String str="abc\def"
str.replaceAll("\\\\","");
str="abc\\def"
str.replaceAll("\\\\\\\\","");
问题描述

java json转义问题(消除反斜杠及{}外面多余的”),接口交互过程中,接收到的JSON串中包含多余的\和”

原因:

map等其他类型把String类型的值转成json的容易在{}外面有引号,会导致转换出错,如:使用fastjson的Json.toJsonString()方法

解决方案:

根据实际情况,有多种解决方案

  1. 使用replace去掉多余的,因为可能存在作为转译使用的,替换时需要替换\ ,保留转译用的\
  2. 使用common-lang或goovy中的StringEscapeUtils.unescapeJavaScript()方法进行删除\操作,但是对于{}对象,可能会存在嵌套””的情况发生,此时还需要对{}外的””进行替换处理
    1
    2
    3
    4
    5
    6
    //先去除多余的转义符号
    json = StringEscapeUtils.unescapeJavaScript(json);
    //去掉{}两边的引号{}需要\\进行转义,"需要\进行转义
    json=json.replaceAll("\"\\{", "\\{");
    json=json.replaceAll("\\}\"", "\\}");
    return json;
问题描述

zxing生成二维码或条形码时存在白边

原因:

QRCodeWriter中的renderResult中默认渲染了padding(内边距),造成默认生成的二维码存在白边

解决方案:

参考:使用Zxing玩转二维码白边的各个花样
参考:Java基于zxing生成二维码矩阵过程解析

根据实际情况,有多种解决方案

  1. 在比较新的Zxing包中EncodeHintType有另外一个属性就是Margin,可以设置这个属性,将属性设置为0即可去掉白边
    1
    2
    3
    4
    5
    6
    Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
    hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
    hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
    hints.put(EncodeHintType.MARGIN, 0);
    BitMatrix bitMatrix = new MultiFormatWriter().encode(content,
    BarcodeFormat.QR_CODE, QRCODE_SIZE_W, QRCODE_SIZE_H, hints);
  2. 将Zxing生成的BitMatrix更新一下去掉白边,并重新设置白边的宽度
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    private static BitMatrix updateBit(BitMatrix matrix, int margin) {
    int tempM = margin * 2;
        //left,top,width,height
        // 0  1  2   3  对应的数组下标
        //这里的width和height是指去除白色边框后的真实的二维码长宽,而不是图片长宽。
        int[] rec = matrix.getEnclosingRectangle(); // 获取二维码图案的属性
        int resWidth = rec[2] + tempM;//真实宽度加左右边距
        int resHeight = rec[3] + tempM;
        BitMatrix resMatrix = new BitMatrix(resWidth, resHeight); // 按照自定义边框生成新的BitMatrix
        resMatrix.clear();
        //从上->下按列进行值得复制,即一列一列的扫描到新的二维矩阵中
        for (int i = margin; i < resWidth - margin; i++) { // 循环,将二维码图案绘制到新的bitMatrix中
          for (int j = margin; j < resHeight - margin; j++) {
            //margin + rec[0]
            if (matrix.get(i - margin + rec[0], j - margin + rec[1])) {
              resMatrix.set(i, j);
            }
          }
        }
        return resMatrix;
    }
问题描述

java Font默认没有下划线,需要自己创建对应字体

原因:

java Font默认没有下划线,需要自己创建对应字体

解决方案:

创建字体对象,以下代码生成的字体包括下划线和粗体
参考:java中decimalFormat格式化数值

1
2
3
4
5
6
7
8
// 生成带有下划线的字体
// 需要借助于TextAttribute类来处理
HashMap<TextAttribute, Object> hm = new HashMap<TextAttribute, Object>();
hm.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); // 定义是否有下划线
hm.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD); // 定义粗体
hm.put(TextAttribute.SIZE, 40); // 定义字号
hm.put(TextAttribute.FAMILY, "楷体"); // 定义字体名
Font font = new Font(hm); // 生成字号为40,字体为楷,字形带有下划线和粗体的字体
问题描述

java 经常要对数字进行格式化,比如取小数点后两位小数,或者加个百分比符号等,Java提供了DecimalFormat(java.text.DateFormat)这个类
0 和 # 的区别:”#”可以理解为在正常的数字显示中,如果前缀与后缀出现不必要的多余的0,则将其忽略。

解决方案:

使用DecimalFormat对数字进行格式化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//使用方法1
String a4 = new DecimalFormat("000").format(1);

//使用方法2
int num=1;
Format df = new DecimalFormat("000");
df.format(num);

//示例
double pi = 123.1512134567;
// 取整数部分
String s1 = new DecimalFormat("0").format(pi);
System.out.println("取整数:" + s1);//123

// 取小数点后1位,四舍五入
String s2 = new DecimalFormat("0.0").format(pi);
System.out.println(s2);//123.2

// 取小数点后3位,不足部分取0
String s3 = new DecimalFormat("0.000").format(pi);
System.out.println(s3);//123.150

// 百分比
String s4 = new DecimalFormat("0.0%").format(pi);
System.out.println(s4);// 12315.0%

// 科学计数法
String s5 = new DecimalFormat("0.00E0").format(pi);
System.out.println(s5);

// 每三位以逗号分开
double d = 1234567;
String s6 = new DecimalFormat(",000").format(d);
System.out.println(s6);

//小数点后3位,如果是0则不显示
String s7 = new DecimalFormat("#.###").format(123.300);
System.out.println(s7);//123.3
问题描述

java new Date(String)构造方法在新的jdk中被弃用

原因:

new Date(String)构造方法在新的jdk中被弃用

解决方案:
  1. 使用DateFormat(java.text.DateFormat)替代new Date(String)构造方法

  2. 使用SimpleDateFormat(java.text.SimpleDateFormat)

  3. 使用Timestamp(java.sql.Timestamp)

* 待确认:windows下支持的格式为yyyy-MM-dd,linux下支持的个是为yyyyMMdd,通用使用yyy.MM.dd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Date parsed = new Date();
// 方案1,存在linux和windows下支持的格式不一样的问题
//windows
parsed=DateFormat.getDateInstance().parse("yyyy-MM-dd HH:mm:ss");
//linux
parsed=DateFormat.getDateInstance().parse("yyyy-MM-dd");

// 方案2,疑似存在linux和windows下支持的格式不一样的问题
//windows
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//linux
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
parsed = format.parse(dateString);

// 方案3,如果是yyyy/MM/dd或者是yyyy/MM/dd(比较常用的两种格式)就可以使用下面的方式来进行转换
String strTime = “2019-03-05”;
strTime = (new StringBuilder(String.valueOf(strTime))).append(" 00:00:00.000000000").toString();
Date date = Timestamp.valueOf(strTime);

总结

持续更新中….

作者

BE

发布于

2021-08-19

更新于

2021-08-19

许可协议