原则

  1. 虽然使用new 声明的字符串调用intern方法,也可以让字符串进行驻留,但在业务代码中滥用intern,可能会产生性能问题。
    1. -XX:+PrintStringTableStatistic 可以查看字符串常量表
      1. 字符串常量池是一个固定容量的Map。如果容量太小(Number of buckets=60013)、字符串太多(1000万个字符串),那么每一个桶中的字符串数量会非常多,所以搜索起来就很慢。输出结果中的Average bucket size=167,代表了Map中桶的平均长度是167。
    2. -XX:StringTableSize=xxx 可以设置字符串常量表长度
  2. 所以没事别轻易用intern,如果要用一定要注意控制驻留的字符串的数量,并留意常量表的各项指标。

hashcode、equals、compareTo

  • hashcode 可以通过 Objects.hash 方法生成
  • 如果要实现 Comparable,请记得 equalshashCodecompareTo三者逻辑一致
  • lombok 的注解默认不实现父类的属性

乱码问题

原因

  1. 指定的字符集不支持复杂汉字
    1. 使用支持复杂汉字的字符集
  2. 字节数组和字符串相互转换时字符串不匹配
    1. 使用相同字符集
  • 一般都用 UTF-8 即可
    1. private static void characterDemo() {
    2. String str = "呵呵哒";
    3. // 指定字符集
    4. byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
    5. // 指定字符集
    6. String target = new String(bytes, StandardCharsets.UTF_8);
    7. }

首字母大写/小写

  • 使用 substring()

    public String substring(int beginIndex [,int endIndex])

  • substring() 是调用 String 的一个构造方法,后者调用

    Arrays.copyOfRange(字符数组, 开始offset, 结束offset);

  1. /**
  2. * 首字母小写
  3. */
  4. private static void firstCharacterLower() {
  5. String name = DemoService.class.getName();
  6. // DemoService -> demoService
  7. String targetName = name.substring(0, 1).toLowerCase() + name.substring(1);
  8. }

equals 如何实现

  1. 如果内存地址不一致( == 进行比较) ,false
  2. 如果类型不一致 ( instance 进行比较 ),false
    1. 如果长度不一致,false
    2. 如果内容不一致 false

常用 api

替代

拆分

  • 简单场景可以用 public String[] split(String regex [,int limit])

    1. private static void simpleSplitDemo() {
    2. String str = "a,b,c";
    3. // 分成三个 [a, b, c]
    4. System.out.println(Arrays.toString(str.split(",")));
    5. // 分成 limit 个 [a, b,c]
    6. System.out.println(Arrays.toString(str.split(",", 2)));
    7. }
  • 但是如果需要结果去除空值等要求,可以用 guavaSplitter

    1. private static void guavaSplit() {
    2. String str = ",a,b,c";
    3. // 使用jdk自带的 split
    4. // [, a, b, c] 空值也取出来了
    5. System.out.println(Arrays.toString(str.split(",")));
    6. // guava api
    7. List<String> list = Splitter.on(",")
    8. .trimResults() // 去除空格
    9. .omitEmptyStrings() // 去除 空值
    10. .splitToList(str);
    11. // -> [a, b, c] 空值去掉了
    12. System.out.println(list);
    13. }

合并

  • 可以用 join,但是建议用 guavaJointer

    1. private static void guavaJointer() {
    2. // 1. 指定 join 时添加的分隔符
    3. // 2. 并且join 有 null 时跳过
    4. Joiner joiner = Joiner.on("#").skipNulls();
    5. String result = joiner.join("a", "b", null, "c");
    6. // -> a#b#c
    7. System.out.println(result);
    8. // -> a#b#c
    9. result = joiner.join(Lists.newArrayList("a", "b", null, "c"));
    10. System.out.println(result);
    11. }