您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > JAVA

跟着 Guava 学 Java 之字符串处理

时间:2022-10-03 15:53:11  来源:  作者:小盒子的技术分享

Joiner

Guava Joiner

顾名思义就是将字符串连接起来

  Joiner joiner = Joiner.on("; ").skipNulls();

  System.out.println(joiner.join("Harry", null, "Ron", "Hermione"));

  //可以传集合、数组或多个参数
  List<Integer> nums = List.of(1, 2, 3, 4, 5);
  System.out.println(joiner.join(nums));

输出:

Harry; Ron; Hermione
1; 2; 3; 4; 5

上面代码中忽略了 null 也可以将 null 替换为其他字符串,比如:

System.out.println(Joiner.on("; ").useForNull("**").join(1,2,3,null));

Joiner 是线程安全的,一般你可以定义一个 static final的常量:

static final Joiner joiner = Joiner.on(","); 

还可以将 map 也 join 起来:

  Joiner.MapJoiner mapJoiner = Joiner.on("; ").withKeyValueSeparator("|");
  Map<String, Integer> testMap = Map.of("a", 1, "b", 2);
  System.out.println(mapJoiner.join(testMap));

输出:

b|2; a|1

其他 Joiner

JDK 自身也有 String 的 Joiner API:

  String PREFIX = "[";
  String SUFFIX = "]";
  StringJoiner jdkJoiner = new StringJoiner(",");
  StringJoiner jdkJoiner2 = new StringJoiner(
          ",", PREFIX, SUFFIX);

  System.out.println(jdkJoiner2.add("a").add("b").add("c").toString());

可以添加前、后缀,但元素只能一个一个 add,没有 guava 方便 。

如果你是简单的 join 需求,使用 JDK8 以后的 API,直接用 Stream 就完了。

  //use JAVA8 stream
  List<String> rgbList = Arrays.asList("Red", "Green", "Blue");
  String commaSeparatedRGB = rgbList.stream()
          .map(color -> color.toString())
          .collect(Collectors.joining(","));

  System.out.println(commaSeparatedRGB);

总结

简单 join 直接 stream 流式一行代码搞定,特殊点的看看 Guava 的 joiner 支不支持,一般 Guava 的 Joiner 够用了。再搞不定的自己写个工具类方法吧。

Splitter

JDK 内建

JDK 内建的字符串拆分工具有一些古怪的特性。比如,String.split悄悄丢弃了尾部的分隔符。

System.out.println(Arrays.toString(",a,,b,".split(",")));

//输出 [, a, , b]

当然还有 StringTokenizer 这种更繁琐的东西:

  String str = "runoob,google,taobao,facebook,zhihu";
  // 以 , 号为分隔符来分隔字符串
  StringTokenizer st=new StringTokenizer(str,",");
  while(st.hasMoreTokens()) { 
      System.out.println(st.nextToken());
  }

Guava Splitter

Splitter使用令人放心的、直白的流畅 API 模式对这些混乱的特性作了完全的掌控。

Iterable<String> split = Splitter.on(',')
                .trimResults()
                .omitEmptyStrings()
                .split("foo,bar,,   qux");

System.out.println(split.toString());

//输出 [foo, bar, qux]

Splitter 可以被设置为按照任何 Pattern, char, String, 或者 CharMatcher拆分。

方法 描述 范例 Splitter.on(char) 按单个字符拆分 Splitter.on(';') Splitter.on(CharMatcher) 按字符匹配器拆分 Splitter.on(CharMatcher.anyOf(";,.")) Splitter.on(String) 按字符串拆分 Splitter.on(",") Splitter.on(Pattern) Splitter.onPattern(String) 按正则表达式拆分 Splitter.onPattern("r?n") Splitter.fixedLength(int) 按固定长度拆分;最后一段可能比给定长度短,但不会为空。 Splitter.fixedLength(3)

列举一些 Splitter 的方法

方法 描述 omitEmptyStrings() 从结果中自动忽略空字符串 trimResults() 移除结果字符串的前导空白和尾部空白 trimResults(CharMatcher) 给定匹配器,移除结果字符串的前导匹配字符和尾部匹配字符 limit(int) 限制拆分出的字符串数量

注意 trimResults(CharMatcher) ,它是把所有前导字符干掉外加尾部能匹配上的字符,举个例子:

// 可以看到,前缀都没了,尾部与 “_” 匹配上的只有 “c__”,所以干掉了一个 “_”,剩下 “c_”
System.out.println(Splitter.on(',').trimResults(CharMatcher.is('_')).split("_a ,_b_ ,c__").toString());

上面的代码返回 :[a , b_ , c] ,

同 Joiner 一样,Splitter实例也是线程安全的,所以可以定义为 static final

static final  Splitter  splitter = Splitter.on(",").omitEmptyStrings().trimResults();

还可以利用 MapSplitter 把字符串反序列化成 Map,例如:

  @Test
  public void testMapSplitter() {

      String startSring = "Washington D.C=Redskins#New York City=Giants#Philadelphia=Eagles#Dallas=Cowboys";
      Map<String, String> testMap = Maps.newLinkedHashMap();
      testMap.put("Washington D.C", "Redskins");
      testMap.put("New York City", "Giants");
      testMap.put("Philadelphia", "Eagles");
      testMap.put("Dallas", "Cowboys");
      Splitter.MapSplitter mapSplitter = Splitter.on("#").withKeyValueSeparator("=");
      Map<String, String> splitMap = mapSplitter.split(startSring);

      assertEquals(testMap, splitMap);
  }

CharMatcher

Guava 为我们提供了字符匹配器,你可以认为一个CharMatcher实例代表着某一类字符,如数字或空白字符。CharMatcher 还提供了一系列方法,让你对字符进行特定类型的操作:修剪 [trim]、折叠 [collapse]、移除 [remove]、保留 [retAIn] 等等。

所以使用 CharMatcher,大致分两步

  • 第一步:定义 CharMatcher,定义怎样算“匹配” 到字符
  • 第二步:如何处理匹配到的这些字符

下面我们用一些小例子来说明:

将 " 1 2 3 4 6 9 " 转换成 "1 2 3 4 6 9" 去掉多余的空格,用空格间隔每个字符

// 我们先定义“空白” 然后折叠连续的空白并用一个空格代替,同时修剪掉首尾的空格
String tmpStr = "  1   2   3 4 6    9   " ;
String result = CharMatcher.whitespace().trimAndCollapseFrom(tmpStr,' ');
System.out.println(result);

获取 0-6 范围内的数字字符

String tmpStr = "df67sn18kj9" ;
String result = CharMatcher.inRange('0','6').retainFrom(tmpStr) ;
System.out.println( result);

获取 d-k 范围内的数字字符

String tmpStr = "df67sn18kj9" ;
String result = CharMatcher.inRange('d','k').retainFrom(tmpStr) ;
System.out.println( result); 

去掉特殊字符

String input = "H*el.lo,}12";
CharMatcher matcher = CharMatcher.javaLetterOrDigit();
String result = matcher.retainFrom(input);

assertEquals("Hello12", result);

去掉非 ASCII 码字符

String input = "あ hello₤";

String result = CharMatcher.ascii().retainFrom(input);
assertEquals("hello", result);

result = CharMatcher.inRange('0', 'z').retainFrom(input);
assertEquals("hello", result);

过滤或筛选字符串中的汉字

  //单字节匹配器(汉字是双字节) 不要汉字
  System.out.println("去除双字节,获取单字节:" + CharMatcher.singleWidth().retainFrom(matchStr));
  //只留汉字
  System.out.println("去除单字节,获取双字节:" + CharMatcher.singleWidth().removeFrom(matchStr));

方法分类

看完上面的例子,你可能对 CharMatcher 的方法感兴趣了,CharMatcher 一类分三类

第一类是判定型函数,判断 Charmacher 和入参字符串的匹配关系。

CharMatcher.is('a').matchesAllOf("aaa");//true
CharMatcher.is('a').matchesAnyOf("aba");//true
CharMatcher.is('a').matchesNoneOf("aba");//true

第二类是计数型函数,查找入参字符串中第一次、最后一次出现目标字符的位置,或者目标字符出现的次数,比如 indexIn,lastIndexIn 和 countIn。

CharMatcher.is('a').countIn("aaa"); // 3
CharMatcher.is('a').indexIn("java"); // 1

第三类就是对匹配字符的操作。包括 removeFrom、retainFrom、replaceFrom、trimFrom、collapseFrom 等。

方法清单

拉个单子方便查

 

 

 

 

CaseFormat

CaseFormat 被用来方便地在各种 ASCII 大小写规范间转换字符串——比如,编程语言的命名规范。CaseFormat 支持的格式如下:

格式 范例 LOWER_CAMEL lowerCamel LOWER_HYPHEN lower-hyphen LOWER_UNDERSCORE lower_underscore UPPER_CAMEL UpperCamel UPPER_UNDERSCORE UPPER_UNDERSCORE

CaseFormat 的用法很直接:

CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, "CONSTANT_NAME")); // returns "constantName"

CaseFormat 在某些时候尤其有用,比如编写代码生成器的时候。

Strings

Strings 工具类也提供了许多好用的处理字符串的方法,比如简单和见名知义就不多说了。

参考

  • https://www.runoob.com/w3cnote/java-stringtokenizer-intro.html
  • https://www.baeldung.com/guava-string-charmatcher
  • https://Github.com/google/guava/wiki/StringsExplained#splitter
  • https://mindawei.github.io/2018/03/17/Guava 学习之 CharMatcher/


Tags:Java   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
JavaScript的异步编程常见模式
在JavaScript中,异步编程是一种处理长时间运行操作(如网络请求或I/O操作)的常见方式。它允许程序在等待这些操作完成时继续执行其他任务,从而提高应用程序的响应性和性能。JavaS...【详细内容】
2024-04-12  Search: Java  点击:(2)  评论:(0)  加入收藏
17 个你需要知道的 JavaScript 优化技巧
你可能一直在使用JavaScript搞开发,但很多时候你可能对它提供的最新功能并不感冒,尽管这些功能在无需编写额外代码的情况下就可以解决你的问题。作为前端开发人员,我们必须了解...【详细内容】
2024-04-03  Search: Java  点击:(6)  评论:(0)  加入收藏
你不可不知的 15 个 JavaScript 小贴士
在掌握如何编写JavaScript代码之后,那么就进阶到实践&mdash;&mdash;如何真正地解决问题。我们需要更改JS代码使其更简单、更易于阅读,因为这样的程序更易于团队成员之间紧密协...【详细内容】
2024-03-21  Search: Java  点击:(27)  评论:(0)  加入收藏
Oracle正式发布Java 22
Oracle 正式发布 Java 22,这是备受欢迎的编程语言和开发平台推出的全新版本。Java 22 (Oracle JDK 22) 在性能、稳定性和安全性方面进行了数千种改进,包括对Java 语言、其API...【详细内容】
2024-03-21  Search: Java  点击:(10)  评论:(0)  加入收藏
构建一个通用灵活的JavaScript插件系统?看完你也会!
在软件开发中,插件系统为应用程序提供了巨大的灵活性和可扩展性。它们允许开发者在不修改核心代码的情况下扩展和定制应用程序的功能。本文将详细介绍如何构建一个灵活的Java...【详细内容】
2024-03-20  Search: Java  点击:(20)  评论:(0)  加入收藏
Java 8 内存管理原理解析及内存故障排查实践
本文介绍Java8虚拟机的内存区域划分、内存垃圾回收工作原理解析、虚拟机内存分配配置,以及各垃圾收集器优缺点及场景应用、实践内存故障场景排查诊断,方便读者面临内存故障时...【详细内容】
2024-03-20  Search: Java  点击:(15)  评论:(0)  加入收藏
如何编写高性能的Java代码
作者 | 波哥审校 | 重楼在当今软件开发领域,编写高性能的Java代码是至关重要的。Java作为一种流行的编程语言,拥有强大的生态系统和丰富的工具链,但是要写出性能优异的Java代码...【详细内容】
2024-03-20  Search: Java  点击:(24)  评论:(0)  加入收藏
在Java应用程序中释放峰值性能:配置文件引导优化(PGO)概述
译者 | 李睿审校 | 重楼在Java开发领域,优化应用程序的性能是开发人员的持续追求。配置文件引导优化(Profile-Guided Optimization,PGO)是一种功能强大的技术,能够显著地提高Ja...【详细内容】
2024-03-18  Search: Java  点击:(27)  评论:(0)  加入收藏
对JavaScript代码压缩有什么好处?
对JavaScript代码进行压缩主要带来以下好处: 减小文件大小:通过移除代码中的空白符、换行符、注释,以及缩短变量名等方式,可以显著减小JavaScript文件的大小。这有助于减少网页...【详细内容】
2024-03-13  Search: Java  点击:(2)  评论:(0)  加入收藏
跨端轻量JavaScript引擎的实现与探索
一、JavaScript 1.JavaScript语言JavaScript是ECMAScript的实现,由ECMA 39(欧洲计算机制造商协会39号技术委员会)负责制定ECMAScript标准。ECMAScript发展史: 2.JavaScript...【详细内容】
2024-03-12  Search: Java  点击:(2)  评论:(0)  加入收藏
▌简易百科推荐
Java 8 内存管理原理解析及内存故障排查实践
本文介绍Java8虚拟机的内存区域划分、内存垃圾回收工作原理解析、虚拟机内存分配配置,以及各垃圾收集器优缺点及场景应用、实践内存故障场景排查诊断,方便读者面临内存故障时...【详细内容】
2024-03-20  vivo互联网技术    Tags:Java 8   点击:(15)  评论:(0)  加入收藏
如何编写高性能的Java代码
作者 | 波哥审校 | 重楼在当今软件开发领域,编写高性能的Java代码是至关重要的。Java作为一种流行的编程语言,拥有强大的生态系统和丰富的工具链,但是要写出性能优异的Java代码...【详细内容】
2024-03-20    51CTO  Tags:Java代码   点击:(24)  评论:(0)  加入收藏
在Java应用程序中释放峰值性能:配置文件引导优化(PGO)概述
译者 | 李睿审校 | 重楼在Java开发领域,优化应用程序的性能是开发人员的持续追求。配置文件引导优化(Profile-Guided Optimization,PGO)是一种功能强大的技术,能够显著地提高Ja...【详细内容】
2024-03-18    51CTO  Tags:Java   点击:(27)  评论:(0)  加入收藏
Java生产环境下性能监控与调优详解
堆是 JVM 内存中最大的一块内存空间,该内存被所有线程共享,几乎所有对象和数组都被分配到了堆内存中。堆被划分为新生代和老年代,新生代又被进一步划分为 Eden 和 Survivor 区,...【详细内容】
2024-02-04  大雷家吃饭    Tags:Java   点击:(57)  评论:(0)  加入收藏
在项目中如何避免和解决Java内存泄漏问题
在Java中,内存泄漏通常指的是程序中存在一些不再使用的对象或数据结构仍然保持对内存的引用,从而导致这些对象无法被垃圾回收器回收,最终导致内存占用不断增加,进而影响程序的性...【详细内容】
2024-02-01  编程技术汇  今日头条  Tags:Java   点击:(70)  评论:(0)  加入收藏
Java中的缓存技术及其使用场景
Java中的缓存技术是一种优化手段,用于提高应用程序的性能和响应速度。缓存技术通过将计算结果或者经常访问的数据存储在快速访问的存储介质中,以便下次需要时可以更快地获取。...【详细内容】
2024-01-30  编程技术汇    Tags:Java   点击:(73)  评论:(0)  加入收藏
JDK17 与 JDK11 特性差异浅谈
从 JDK11 到 JDK17 ,Java 的发展经历了一系列重要的里程碑。其中最重要的是 JDK17 的发布,这是一个长期支持(LTS)版本,它将获得长期的更新和支持,有助于保持程序的稳定性和可靠性...【详细内容】
2024-01-26  政采云技术  51CTO  Tags:JDK17   点击:(90)  评论:(0)  加入收藏
Java并发编程高阶技术
随着计算机硬件的发展,多核处理器的普及和内存容量的增加,利用多线程实现异步并发成为提升程序性能的重要途径。在Java中,多线程的使用能够更好地发挥硬件资源,提高程序的响应...【详细内容】
2024-01-19  大雷家吃饭    Tags:Java   点击:(107)  评论:(0)  加入收藏
这篇文章彻底让你了解Java与RPA
前段时间更新系统的时候,发现多了一个名为Power Automate的应用,打开了解后发现是一个自动化应用,根据其描述,可以自动执行所有日常任务,说的还是比较夸张,简单用了下,对于office、...【详细内容】
2024-01-17  Java技术指北  微信公众号  Tags:Java   点击:(99)  评论:(0)  加入收藏
Java 在 2023 年仍然流行的 25 个原因
译者 | 刘汪洋审校 | 重楼学习 Java 的过程中,我意识到在 90 年代末 OOP 正值鼎盛时期,Java 作为能够真正实现这些概念的语言显得尤为突出(尽管我此前学过 C++,但相比 Java 影响...【详细内容】
2024-01-10  刘汪洋  51CTO  Tags:Java   点击:(78)  评论:(0)  加入收藏
站内最新
站内热门
站内头条