Guava翻译之Strings

简介: guava翻译系列

使用Guava处理Strings

不管你更喜欢使用哪种语言,程序员都必须和字符串打交道,有时候这是无趣的并且容易出错的。 有的时候,我们需要从文件或者数据库的表中读取数据,并格式化这些数据。 或者为了满足业务需求我们需要排序等操作,幸运的是,Guava给我们提供一些非常有用的类,可以帮助我们处理Strings类更加容易.这些类是:

  • CharMatcher
  • Charsets
  • Strings
    下面让我们看一下在我们的代码中怎么样是使用这些类。

使用Charsets类

在Java平台下有个6个标准的字符集,下面是和字符集相关的非常常见的例子:
byte[] bytes = someString.getBytes();
但是上面的这个代码片段是有问题的,在获取byte的时候没有指定字符集编码,那么默认就会去系统的默认编码,但是有可能系统默认的编码不是你想要的编码。因此一般的最佳实践是按照如下的方式获取byte数据:
`try{
bytes = "foobarbaz".getBytes("UTF-8");
}catch (UnsupportedEncodingException e){
//This really can't happen UTF-8 must be supported
}`
上面的例子中依然有两个错误的地方:

  • UTF-8 在Java平台上是肯定会被支持的,所以基本上是不可能会抛出UnsupportedEncodingException异常的。
  • 我们是用'UTF-8'这种方式指定编码的,有可能会出现输入错误的情况,例如不小心输入成'UF-8'.

上面的这两个问题正是CharSets可以解决。 Charsets类 对于这6个字符集提供了一个 final的静态的引用。 使用Charsets,上面的那段代码可以简化为如下:
byte[] bytes2 = "foobarbaz".getBytes(Charsets.UTF_8);
不过在Java7中已经提供了类似的功能,在Java 7中的类名是: StandardCharsets.

使用Stings类

Strings提供了一些工具方法区处理字符串,你是否写过下面的代码:
`StringBuilder builder = new StringBuilder("foo");
char c = 'x';
for(int i=0; i<3; i++){
builder.append(c);
}
return builder.toString();`
在上面的这段代码中,我们使用了6行代码完成了这么一个简单的功能,现在利用Strings 我们可以简单的用一行代码就可以完成:
Strings.padEnd("foo",6,'x');
这里面有个重要的提示,这里面的6不是指将x循环的增加6遍,而是指将'foo'补充成6位长度。 如果这时候 'fooxxxx'已经是6位长度了,那么这段代码将不起任何作用. 同样 有一个'padStart'方法,它的作用和'padEnd'是相似的,只不过是在字符串前面补充指定的字符。补充到指定的长度。

在处理null值方面,Strings有三个比较好用的方法:

  • nullToEmpty 这个方法获取一个字符串参数,如果这个参数不为null或长度大于0,那么直接返回该参数,否则返回"" 空字符串
  • emptyToNull 这个方法和nulltoEmpty差不多,只不过如果参数是null或则长度不大于0 那么会返回 null
  • isNullOrEmpty 当传入的参数书null或则长度为0 那么这个方法的返回值就是 true。

最佳实践: 在讲String作为参数传递时,最好先使用nullToEmpty对字符串做一下处理。

使用CharMatcher类

Charmatcher 类提供了处理各种characters的方法,能够非常容易的格式化处理文本。 下面的例子展示的是,使用CharMatcher将一个多行的字符串转换成以' '分隔的单行字符串
CharMatcher.BREAKING_WHITESPACE.replaceFrom(stringWithLinebreaks,' ');
replaceFrom方法不仅可以接受一个char类型参数还可以接受一个charsequence参数。

为了将连续的多个 tab或者空格 压缩成一个空格,我们可以使用下面的代码:
`@Test
public void testRemoveWhiteSpace(){
String tabsAndSpaces = "String with spaces and
tabs";
String expected = "String with spaces and tabs";
String scrubbed = CharMatcher.WHITESPACE.
collapseFrom(tabsAndSpaces,' ');
assertThat(scrubbed,is(expected));
}`

上面的test中,我们看到我用一行代码就将多个tab及多个空变成一个空格。 但是上面的这个例子只是在特殊的情况下有效,如果我们想将字符串前面的空格都去掉,只保留字符中间的一个空格呢? 尽管需求这么变态,使用 trimAndCollapseFrom方法就可以实现,示例如下:
`@Test
public void testTrimRemoveWhiteSpace(){
String tabsAndSpaces = " String with spaces and
tabs";
String expected = "String with spaces and tabs";
String scrubbed = CharMatcher.WHITESPACE.
trimAndCollapseFrom(tabsAndSpaces,' ');
assertThat(scrubbed,is(expected));
}`

上面的例子我们依然讨论了如何将多个tab或空格变成一个空格,现在让我们来看一下其他的使用方式,

  • 将符合条件的字符提取出来,example:
    `@Test

public void testRetainFrom(){
String lettersAndNumbers = ""foo989yxbar234"";
String expected = ""989234"";
String retained = CharMatcher.JAVA_DIGIT.
retainFrom(lettersAndNumbers);
assertThat(expected,is(retained));
}`
上面的例子中,我们将所有的数字都提取了出来,仅仅是使用了一行代码哦!

  • 在讲其他的类的使用之前,我们来看一个大招,example:
    `String lettersAndNumbers = "fo o989yxbar234";

String expected = " 989234";
CharMatcher.JAVA_DIGIT.or(CharMatcher.WHITESPACE).retainFrom(lettersAndNumbers);`

上面的例子中既可以提取数字也可以提取空白字符

由此可见,CharMatcher在处理Java字符串方面是非常好用并且非常好用的方法。

使用 Preconditions类

Preconditions类里面包含了一系列的静态方法,用来验证我们期望的值。 Preconfitions 是非常重要,因为他可以保证我们的预期和实际发生的是一致的。 一旦预期和实际运行的记过不一致,我们立马就可以得到反馈,因此使用preconditions 可以确保我们的代码在我们预期的情况下运行着。 另外对于debug也是非常有好处的。

  • 在使用preconfitions 之前我们一定写过下面的代码:
    `if(someObj == null){

throw new IllegalArgumentException(" someObj must
not be null");
}`
使用preconfitions 后,我们可以如下的方法进行检查:
checkNotNull(someObj,"someObj must not be null");
其中preconfitions 是可以静态导入的 static imports
下面我们来看一个例子:
`public class PreconditionExample {
private String label;
private int[] values = new int[5];
private int currentIndex;
public PreconditionExample(String label) {
//returns value of object if not null
this.label = checkNotNull(label,"Label can''t be null");
}
public void updateCurrentIndexValue(int index, int valueToSet) {
//Check index valid first
this.currentIndex = checkElementIndex(index, values.length,
"Index out of bounds for values");
//Validate valueToSet
checkArgument(valueToSet <= 100,"Value can't be more than
100");
values[this.currentIndex] = valueToSet;
}
public void doOperation(){
checkState(validateObjectState(),"Can't perform operation");
}
private boolean validateObjectState(){
return this.label.equalsIgnoreCase("open") && values[this.
currentIndex]==10;
}
}`
从上面的例子中,我们总结一下这个几个方法的使用:

  1. checkNotNull(T object,Object message) : 如果object是null 那么就会抛出一个NullPointException异常,否则返回这个Object.
  2. checkElementIndex(int index,int size,Object message): 这个方法中 index 参数是你想要访问的位置,size 是array,list,或者string的长度, 如果 index的范围大于size 那么将会抛出 IndexOutOfBoundexception 否则返回index的值
  3. checkArgument(Boolean expression,Object message): 根据expression表达式算出来的值做判断,如果值为false那么就会抛出IllegalArgumentException异常
  4. checkState(Boolean expression,Object message): 作用和checkArgument一样,代码实现也是一样,使用场景不一致,checkArgument 一般用来检查输入参数

使用Object utilities类

这一个小章节中,我们将覆盖 空值检查,生成 toString,hashCode 等方法。 我们还将学习一个新的类帮助我们从实现Comparable接口痛苦摆脱出来。

使用 toString方法

toString 方法在我们debug或者查日志的时候是十分方便的,但是写一个toString方法却是一个比较无趣的事情,但是使用Objects的toStringHelper方法你可以很方便的实现,下面我们看一个例子:
`public class Book implements Comparable {
private Person author;
private String title;
private String publisher;
private String isbn;
private double price;
....
public String toString() {
return Objects.toStringHelper(this)
.omitNullValues()
.add("title", title)
.add("author", author)
.add("publisher", publisher)
.add("price",price)
.add("isbn", isbn).toString();
}
`
让我们来探究一下这段代码的意思

  • 首先我们传递一个Book的引用,创建一个ToStringHelper对象
  • 调用omitNullValues 排除属性是空值的
  • 分别调用 add 方法将 'label' 和对应的值

不过貌似这个还没有 apache 下面的 ToStringBuilder好用

检查空值

firstNonNull 方法接受两个参数,如果参数是空,就返回设置的默认值,否则指定的第一次参数,如果传入的两个参数都是null 那么就会抛出NullPointException异常

生成HashCode 方法

方法很简单,如下:
`Objects.hashCode(Object...);
`

实现CompareTo接口

我们任然使用上面的Book类,下面是一个实现CompareTo接口典型实现:
`public int compareTo(Book o) {
int result = this.title.compareTo(o.getTitle());
if (result != 0) {
return result;
}
result = this.author.compareTo(o.getAuthor());
if (result != 0) {
return result;
}
result = this.publisher.compareTo(o.getPublisher());
if(result !=0 ) {
return result;
}
return this.isbn.compareTo(o.getIsbn());
}`

下面我们来看一下使用ComparisonChain的方式实现compareTo接口:
`public int compareTo(Book o) {
return ComparisonChain.start()
.compare(this.title, o.getTitle())
.compare(this.author, o.getAuthor())
.compare(this.publisher, o.getPublisher())
.compare(this.isbn, o.getIsbn())
.compare(this.price, o.getPrice())
.result();
}`
上面的这个例子中,使用ComparisonChain的方式更加简单,也更加易读,只要其中的一个比较不为0,那么就直接返回。

总结

在这一章中我们已经介绍了很多。

  • 我们学习了怎样使用Joiner,Splitter,MapJioner,MapSplitter,Charsets,CharMatcher,Strings 让我们在处理格式化的字符串时更加容易
  • 我们学习了使用Preconfitions类让我们的代码更加强壮,学习使用了 Objects类的 toString,hashCode 方法让我们的debug更加容易,我们还学习了ComparisonChain类,让我们实现CompareTo方式更加容易
  • 在下一章,我们将学习怎样使用guava的函数式变成,让我们的代码更加清晰和强壮。我们将涉及两个接口: Function 和 Predicate 接口
目录
相关文章
|
Java 数据库连接 Spring
JavaWeb优雅实现接口参数校验
JavaWeb优雅实现接口参数校验
533 0
|
Windows
『Consul』Consul数据持久化配置并且注册为Windows服务
📣读完这篇文章里你能收获到 - Consul数据持久化配置并且注册为Windows服务
1933 0
『Consul』Consul数据持久化配置并且注册为Windows服务
|
移动开发 Linux
linux文件切割命令之split
linux文件切割命令之split
647 0
|
存储 前端开发 Java
一篇文章带你搞懂Controller、Service等各层的功能与作用
本文将深入探讨这些controller.service等层的作用与功能,帮助读者更好地理解它们在软件开发中的重要性和运作原理。
5988 1
|
6月前
|
前端开发 开发者 容器
前端组件库Layui知识点大全(二)
教程来源 https://hllft.cn/category/tech-trends.html Layui提供灵活响应式布局系统,含`layui-container`(固定宽)与`layui-fluid`(100%宽)两种容器;栅格基于12等分,支持`xs/sm/md/lg`四端适配、偏移、间距及无限嵌套,助力快速构建结构清晰、多端兼容的页面。
|
10月前
|
消息中间件 存储 缓存
RabbitMQ工作模型
工作队列模型通过多个消费者共同消费一个队列中的消息,实现任务的并行处理。默认情况下,消息平均分配给消费者,可能导致处理能力不同的消费者负载不均。通过设置`prefetch=1`,可实现“能者多劳”,即处理速度快的消费者自动接收更多消息,提升整体效率。发布订阅模型则通过交换机(Exchange)将一条消息转发给多个队列,支持Fanout、Direct、Topic等类型交换机,实现广播或多条件路由消息,满足不同业务场景需求。
|
SQL 分布式计算 资源调度
Dataphin功能Tips系列(48)-如何根据Hive SQL/Spark SQL的任务优先级指定YARN资源队列
如何根据Hive SQL/Spark SQL的任务优先级指定YARN资源队列
635 4
|
存储 消息中间件 缓存
支持百万人超大群聊的Web端IM架构设计与实践
本文将回顾实现一个支持百万人超大群聊的Web端IM架构时遇到的技术挑战和解决思路,内容包括:通信方案选型、消息存储、消息有序性、消息可靠性、未读数统计。希望能带给你启发。
927 0
支持百万人超大群聊的Web端IM架构设计与实践
|
缓存 Java 程序员
Java|SpringBoot 项目开发时,让 FreeMarker 文件编辑后自动更新
在开发过程中,FreeMarker 文件编辑后,每次都需要重启应用才能看到效果,效率非常低下。通过一些配置后,可以让它们免重启自动更新。
653 0
|
Java Spring
@PostConstruct注解的使用
@PostConstruct注解的使用
555 0