Guava:好用的java类库学习小记

更新时间:2023-06-19 10:46:59 阅读: 评论:0

Guava:好⽤的java类库学习⼩记
基础功能
google guava中定义的String操作
在google guava中为字符串操作提供了很⼤的便利,有⽼牌的判断字符串是否为空字符串或者为null,⽤指定字符填充字符串,以及拆分合并字符串,字符串匹配的判断等等。
1. 使⽤ba.Strings类的isNullOrEmpty(input)⽅法判断字符串是否为空
1        //Strings.isNullOrEmpty(input) demo
2        String input = "";
3        boolean isNullOrEmpty = Strings.isNullOrEmpty(input);
4        System.out.println("input " + (isNullOrEmpty?"is":"is not") + " null or empty.");
2. 获得两个字符串相同的前缀或者后缀
1        //Prefix(a,b) demo
一种关注
2        String a = "Hello";
3        String b = "Hi";
4        String ourCommonPrefix = Prefix(a,b);
5        System.out.println("a,b common prefix is " + ourCommonPrefix);
6
7        //Suffix(a,b) demo
8        String c = "le.Hello";
9        String d = "com.jd.Hello";
10        String ourSuffix = Suffix(c,d);
11        System.out.println("c,d common suffix is " + ourSuffix);
3. Strings的padStart和padEnd⽅法来补全字符串
1        int minLength = 4;
2        String padEndResult = Strings.padEnd("123", minLength, '0');
3        System.out.println("padEndResult is " + padEndResult);
4
5        String padStartResult = Strings.padStart("1", 2, '0');
6        System.out.println("padStartResult is " + padStartResult);
4. 使⽤Splitter类来拆分字符串
Splitter类可以⽅便的根据正则表达式来拆分字符串,可以去掉拆分结果中的空串,可以对拆分后的字串做trim操作,还可以做⼆次拆分。我们先看⼀个基本的拆分例⼦:
Iterable<String> splitResults = Pattern("[,,]{1,}")
.trimResults()毕业论文任务书
.omitEmptyStrings()
.split("hello,word,,世界,⽔平");
for (String item : splitResults) {
System.out.println(item);
}
Splitter的onPattern⽅法传⼊的是⼀个正则表达式,其后紧跟的trimResults()⽅法表⽰要对结果做trim,omitEmptyStrings()表⽰忽略空字符串,split⽅法会执⾏拆分操作。李峤的诗
split返回的结果为Iterable<String>,我们可以使⽤for循环语句来逐个打印拆分字符串的结果。
Splitter还有更强⼤的功能,做⼆次拆分,这⾥⼆次拆分的意思是拆分两次,例如我们可以将a=b;c=d这样的字符串拆分成⼀个
Map<String,String>。
1        String toSplitString = "a=b;c=d,e=f";
2        Map<String,String> kvs = Pattern("[,;]{1,}").withKeyValueSeparator('=').split(toSplitSt
ring);
3        for (Map.Entry<String,String> entry : Set()) {
4            System.out.println(String.format("%s=%s", Key(),Value()));
5        }
⼆次拆分⾸先是使⽤onPattern做第⼀次的拆分,然后再通过withKeyValueSeperator('')⽅法做第⼆次的拆分。
5. 有拆分字符串必然就有合并字符串,guava为我们提供了Joiner类来做字符串的合并春节的作文600字
我们先看⼀个简单的⽰例:
1        String joinResult = (" ").join(new String[]{"hello","world"});
2        System.out.println(joinResult);
⾯例⼦中我们使⽤(" ").join(xx)来合并字符串。很简单也很有效。
Splitter⽅法可以对字符串做⼆次的拆分,对应的Joiner也可以逆向操作,将Map<String,String>做合并。我们看下下⾯的例⼦:
1        Map<String,String> map = new HashMap<String,String>();
2        map.put("a", "b");
3        map.put("c", "d");
4        String mapJoinResult = (",").withKeyValueSeparator("=").join(map);
5        System.out.println(mapJoinResult);
使⽤withKeyValueSeparator⽅法可以对map做合并。合并的结果是:a=b,c=d
guava库中还可以对字符串做⼤⼩写转换(CaFormat枚举),可以对字符串做模式匹配。使⽤起来都很⽅便。
guava中的对象操作封装
在开发中经常会需要⽐较两个对象是否相等,这时候我们需要考虑⽐较的两个对象是否为null,然后
再调⽤equals⽅法来⽐较是否相
等,google guava库的ba.Objects类提供了⼀个静态⽅法equals可以避免我们⾃⼰做是否为空的判断,⽰例如下:
1  Object a = null;
2  Object b = new Object();
3 boolean aEqualsB = Objects.equal(a, b);
Objects.equals的实现是很完美的,其实现代码如下:
1 public static boolean equal(@Nullable Object a, @Nullable Object b) {
2    return a == b || (a != null && a.equals(b));
3  }
⾸先判断a b是否是同⼀个对象,如果是同⼀对象,那么直接返回相等,如果不是同⼀对象再判断a不为null并且a.equals(b). 这样做既考虑了性能也考虑了null空指针的问题。
另外Objects类中还为我们提供了⽅便的重写toString()⽅法的机制,我们通过例⼦来了解⼀下吧:
1 le.common.ba.Objects;
2
3 public class ObjectsDemo {
4    public static void main(String [] args) {
5      Student jim = new Student();
6        jim.tId(1);
7        jim.tName("Jim");
8        jim.tAge(13);
9        System.out.String());
10    }
11
12    public static class Student {
13        private int id;
14        private String name;
15        private int age;
16
17        public int getId() {
18            return id;
19        }
20        public void tId(int id) {
21            this.id = id;
22        }
23
24        public String getName() {
25            return name;
26        }
27        public void tName(String name) {
28            this.name = name;
29        }
30
31        public int getAge() {
32            return age;
33        }
34        public void tAge(int age) {
35            this.age = age;
36        }少数民族运动会
37
38        public String toString() {
39            Class())
40                    .add("id", id)
41                    .add("name", name)
42                    .add("age", age)
43                    .omitNullValues().toString();
44        }
45    }
46 }
我们定义了⼀个Student类,该类有三个属性,分别为id,name,age,我们重写了toString()⽅法,在这个⽅法中我们使⽤了
上⾯代码输出的结果是:
Student{id=1, name=Jim, age=13}
这种⽅式写起来很简单,可读性也很好,所以⽤Guava吧。
guava的Preconditions使⽤
guava的ba包中提供的Preconditions类⽤来⽅便的做参数的校验,他主要提供如下⽅法:
1. checkArgument 接受⼀个boolean类型的参数和⼀个可选的errorMsg参数,这个⽅法⽤来判断参数是否符合某种条件,符合什么条件
google guava不关⼼,在不符合条件时会抛出IllegalArgumentException异常
2. checkState 和checkArgument参数和实现基本相同,从字⾯意思上我们也可以知道这个⽅法是⽤来判断状态是否正确的,如果状态不
正确会抛出IllegalStateException异常
3. checkNotNull⽅法⽤来判断参数是否不是null,如果为null则会抛出NullPointerException空指针异常
4. checkElementIndex⽅法⽤来判断⽤户传⼊的数组下标或者list索引位置,是否是合法的,如果不合法会抛出
IndexOutOfBoundsException
5. checkPositionIndexes⽅法的作⽤和checkElementIndex⽅法相似,只是此⽅法的索引范围是从0到size包括size,⽽上⾯的⽅法不包括
size。
下⾯我们看⼀个具体的使⽤⽰例:
1 le.common.ba.Preconditions;
2
3 public class PreconditionsDemo {
4    public static void main(String[] args) {
5        PreconditionsDemo demo = new PreconditionsDemo();
6        demo.doSomething("Jim", 19, "hello world, hello java");
7    }
8
9    public void doSomething(String name, int age, String desc) {
10        Preconditions.checkNotNull(name, "name may not be null");
11        Preconditions.checkArgument(age >= 18 && age < 99, "age must in range (18,99)");
12        Preconditions.checkArgument(desc !=null && desc.length() < 10, "desc too long, max length is ", 10);
13
14        //do things
15    }
16 }
上⾯例⼦中的doSomething()⽅法调⽤了三次Preconditions的⽅法,来对参数做校验。
看似Preconditions实现很简单,他的意义在于为我们提供了同⼀的参数校验,并对不同的异常情况抛出合适类型的异常,并对异常信息做格式化。
使⽤google guava的Optional接⼝来避免空指针错误
null会带来很多问题,从开始有null开始有⽆数程序栽在null的⼿⾥,null的含义是不清晰的,检查null在⼤多数情况下是不得不做的,⽽我们⼜在很多时候忘记了对null做检查,在我们的产品真正投⼊使⽤的时候,空指针异常出现了,这是⼀种讨厌的情况。
鉴于此google的guava库中提供了Optional接⼝来使null快速失败,即在可能为null的对象上做了⼀层封装,在使⽤Optional静态⽅法of时,如果传⼊的参数为null就抛出NullPointerException异常。
我们看⼀个实际的例⼦:
1 le.common.ba.Optional;
2
3 public class OptionalDemo {
4    public static void main(String[] args) {
5        Optional<Student> possibleNull = Optional.of(null);
6        ();
7    }
8    public static class Student { }
9 }
上⾯的程序,我们使⽤Optional.of(null)⽅法,这时候程序会第⼀时间抛出空指针异常,这可以帮助我们尽早发现问题。
我们再看另外⼀个例⼦,我们使⽤Optional.abnt⽅法来初始化posibleNull实例,然后我们get此对象,看看会是什么情况。
1 public class OptionalDemo {
狐假虎威文言文2    public static void main(String[] args) {
3        Optional<Student> possibleNull = Optional.abnt();周公解梦大全查询免费版
4        Student jim = ();
5    }
6    public static class Student { }
7 }
运⾏上⾯的程序,发现出现了:Exception in thread "main" java.lang.IllegalStateException: () cannot be called on an abnt value。
这样使⽤也会有异常出来,那Optional到底有什么意义呢?
使⽤Optional除了赋予null语义,增加了可读性,最⼤的优点在于它是⼀种傻⽠式的防护。Optional迫使你积极思考引⽤缺失的情况,因为你必须显式地从Optional获取引⽤。直接使⽤null很容易让⼈忘掉某些情形,尽管FindBugs可以帮助查找null相关的问题,但是我们还是认为它并不能准确地定位问题根源。
如同输⼊参数,⽅法的返回值也可能是null。和其他⼈⼀样,你绝对很可能会忘记别⼈写的⽅法method(a,b)会返回⼀个null,就好像当你实现method(a,b)时,也很可能忘记输⼊参数a可以为null。将⽅法的返回类型指定为Optional,也可以迫使调⽤者思考返回的引⽤缺失的情形。
google guava Throwables帮你抛出异常,处理异常
guava类库中的Throwables提供了⼀些异常处理的静态⽅法,这些⽅法的从功能上分为两类,⼀类是帮你抛出异常,另外⼀类是帮你处理异常。
也许你会想:为什么要帮我们处理异常呢?我们⾃⼰不会抛出异常吗?
假定下⾯的⽅法是我们要调⽤的⽅法。
1  public void doSomething() throws Throwable {
2        //ignore method body
3    }
4
5    public void doSomethingEl() throws Exception {
6        //ignore method body
7    }
这两个⽅法的签名⼀个throws出了Throwable另外⼀个throws出了Exception,他们没有定义具体会抛出什么异常,也就是说他们什么异常都有可能抛出来,如果我们要调⽤这样的⽅法,就需要对他们的异常做⼀些处理了,我们需要判断什么样的异常需要抛出去,什么样的异常需要封装成RuntimeException。⽽这些事情就是Throwables类要帮我们做的事情。
假定我们要实现⼀个doIt的⽅法,该⽅法要调⽤doSomething⽅法,⽽doIt的定义中只允许抛出SQLException,我们可以这样做:
1    public void doIt() throws SQLException {
2        try {
3            doSomething();
4        } catch (Throwable throwable) {
爸爸是女儿5            Throwables.propagateIfInstanceOf(throwable, SQLException.class);
6            Throwables.propagateIfPossible(throwable);
7        }
8    }
请注意doIt的catch块,下⾯这⾏代码的意思是如果异常的类型是SQLException,那么抛出这个异常
Throwables.propagateIfInstanceOf(throwable, SQLException.class);
第⼆⾏表⽰如果异常是Error类型,那么抛出这个类型,否则将抛出RuntimeException,我们知道RuntimeException是不需要在throws中声明的。
Throwables.propagateIfPossible(throwable);
Throwables类还为我们提供了⼀些⽅便的异常处理帮助⽅法:
1. 我们可以通过RooCau(Throwable)获得根异常
2. 可以使⽤getCausalChain⽅法获得异常的列表
3. 可以通过getStackTraceAsString获得异常堆栈的字符串
集合增强
guava的不可变集合
不可变集合的意义
不可变对象有很多优点,包括:
当对象被不可信的库调⽤时,不可变形式是安全的;
不可变对象被多个线程调⽤时,不存在竞态条件问题
不可变集合不需要考虑变化,因此可以节省时间和空间。所有不可变的集合都⽐它们的可变形式有更好的内存利⽤率(分析和测试细节);
不可变对象因为有固定不变,可以作为常量来安全使⽤。
创建对象的不可变拷贝是⼀项很好的防御性编程技巧。Guava为所有JDK标准集合类型和Guava新集合类型都提供了简单易⽤的不可变版本。
JDK也提供了Collections.unmodifiableXXX⽅法把集合包装为不可变形式,但我们认为不够好:
笨重⽽且累赘:不能舒适地⽤在所有想做防御性拷贝的场景;
不安全:要保证没⼈通过原集合的引⽤进⾏修改,返回的集合才是事实上不可变的;
低效:包装过的集合仍然保有可变集合的开销,⽐如并发修改的检查、散列表的额外空间,等等。
如果你没有修改某个集合的需求,或者希望某个集合保持不变时,把它防御性地拷贝到不可变集合是个很好的实践。
重要提⽰:所有Guava不可变集合的实现都不接受null值。我们对Google内部的代码库做过详细研究,发现只有5%的情况需要在集合中允许null元素,剩下的95%场景都是遇到null值就快速失败。如果你需要在不可变集合中使⽤null,请使⽤JDK中的Collections.unmodifiableXXX ⽅法。更多细节建议请参考“使⽤和避免null”。
如何使⽤guava的不可变集合
1. 如何创建不可变集合
第⼀种⽅法使⽤builder创建:
1 public class ImmutableDemo {
2    public static void main(String[] args) {
3        Set<String> immutableNamedColors = ImmutableSet.<String>builder()
4                .add("red", "green","black","white","grey")
5                .build();
6        //immutableNamedColors.add("abc");
7        for (String color : immutableNamedColors) {
8            System.out.println(color);
9        }
10    }
11 }
第⼆种⽅法使⽤of静态⽅法创建:
ImmutableSet.of("red","green","black","white","grey");
第三种⽅法使⽤copyOf静态⽅法创建:
2. 使⽤asList()获得不可变集合的list视图
asList⽅法是在ImmutableCollection中定义,⽽所有的不可变集合都会从ImmutableCollection继承,所以所有的不可变集合都会有asList()⽅法返回当前不可变集合的list视图,这个视图也是不可变的。
3. 不可变集合的使⽤
不可变集合的使⽤和普通集合⼀样,只是不能使⽤他们的add,remove等修改集合的⽅法。
guava集合之Multit
Multit看似是⼀个Set,但是实质上它不是⼀个Set,它没有继承Set接⼝,它继承的是Collection<E>接⼝,你可以向Multit中添加重复的元素,Multit会对添加的元素做⼀个计数。
它本质上是⼀个Set加⼀个元素计数器。
1 le.common.ba.Splitter;
2 llect.HashMultit;
3 llect.Multit;
4
5 public class MultitDemo {
6    public static void main(String[] args) {
7        Multit multit = ate();

本文发布于:2023-06-19 10:46:59,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1045469.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:集合   字符串   不可   拆分   需要   抛出   对象
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图