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 接口
目录
相关文章
|
1月前
|
缓存 Java API
Guava极简教程 - Joiner和Splitter
Guava是Google开发的一个开源Java库,增强了Java标准库的核心功能。它提供了多种工具和集合类,如不可变集合、多映射、缓存、并发工具、字符串处理、I/O工具、哈希与编码、范围、图形数据结构及参数验证等,使开发更高效、代码更简洁。`Joiner`用于将集合转换为字符串,支持分隔符和键值分隔符自定义;`Splitter`则用于将字符串拆分为集合,支持多个分隔符和空字符串忽略。更多详情及示例代码可见:[项目地址](https://gitee.com/naylor_personal/ramble-spring-boot/tree/master/guava)。
36 0
|
API
Google Guava之Splitter
我们上篇文章讲述了Joiner相关API使用,其中提到了Splitter,它与Joiner操作相反,它是根据给定的分隔符,把一个字符串分隔成若个子字符串,那么本篇我们来看看Splitter都有哪些操作的方式。
209 0
Google Guava之Splitter
|
缓存
guava翻译系列之Cache
guava翻译系列
2743 0
|
缓存 移动开发 安全
Guava基本工具包Base:Null和字符串分割(Splitter)、拼接(Joiner)处理
Guava基本工具包Base:Null和字符串分割(Splitter)、拼接(Joiner)处理
445 0
Guava基本工具包Base:Null和字符串分割(Splitter)、拼接(Joiner)处理
|
Java 测试技术 程序员
Guava翻译系列之File
guava翻译系列
2944 0
|
Java 缓存 设计模式
Guava翻译之Functional
guava翻译系列
1744 0
|
Java Android开发
Effective java中文总结翻译版
前言:作为几年的android开发人员,越来越没有刚毕业学习新东西的激情,越来越觉得什么都不会了,零零洒洒的几篇文章都是皮毛,看后让自己汗颜.向上需牢固基础,向下需钻研领域,向左需巩固知识,向右需不断学习.
1180 0
|
Java 程序员 安全
|
Java
[Guava源码分析](6)Objects分析
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SunnyYoona/article/details/71079778 1.
1040 0