文章目录
一. Guava概述
- Guava是 Google公司基于java1.6的类库集合的扩展项目,其中包含谷歌很多项目使用的核心库。这个库是为了方便编码,并减少编码错误。这个库提供用于集合,缓存,支持原语,并发性,常见注解,字符串处理,I/O和验证的实用方法。(官方Guava API)。
- 源码包概述
com.google.common.annotations:普通注解类型。
com.google.common.base:基本工具类库和接口。
com.google.common.cache:缓存工具包,非常简单易用且功能强大的JVM内缓存。
com.google.common.collect:带泛型的集合接口扩展和实现,以及工具类,这里你会发现很多好玩的集合。
com.google.common.eventbus:发布订阅风格的事件总线。
com.google.common.io:I/O工具包。
com.google.common.net:网络工具包。
com.google.common.primitives:八种原始类型和无符号类型的静态工具包。
com.google.common.util.concurrent:多线程工具包。 - Guava maven依赖
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>25.0-jre</version> </dependency>
二. Strings类
- 所在包:com.google.common.base包。
- 常用方法
public static String nullToEmpty(@Nullable String string):如果string为null,则返回"";否则,返回str本身
public static String emptyToNull(@Nullable String string):如果string为"",则返回null;否则,返回string本身
public static boolean isNullOrEmpty(@Nullable String string):如果string为null或"",则返回true;否则,返回false - 常用方法源码
package com.google.common.base; public final class Strings { public static String nullToEmpty(@Nullable String string) { return (string == null) ? "" : string; } @Nullable public static String emptyToNull(@Nullable String string) { return isNullOrEmpty(string) ? null : string; } public static boolean isNullOrEmpty(@Nullable String string) { return string == null || string.length() == 0; // string.isEmpty() in Java 6 } } - 使用示例
public class StringsTest { public static void main(String[] args) { String str1 = ""; String str2 = null; String str3 = "娃哈哈"; // 1. Strings.isNullOrEmpty(String str) boolean flag1 = Strings.isNullOrEmpty(str1); //true boolean flag2 = Strings.isNullOrEmpty(str2); //true boolean flag3 = Strings.isNullOrEmpty(str3); //false System.out.println("|"+str1+"|"); // || System.out.println("|"+str2+"|"); // |null| System.out.println("|"+str3+"|"); // |娃哈哈| // 2. Strings.nullToEmpty(String str) String tempStr1= Strings.nullToEmpty(str1); String tempStr2= Strings.nullToEmpty(str2); String tempStr3= Strings.nullToEmpty(str3); System.out.println("|"+tempStr1+"|"); // || System.out.println("|"+tempStr2+"|"); // || System.out.println("|"+tempStr3+"|"); // |娃哈哈| // 3. Strings.emptyToNull(String str) String tempStr4= Strings.emptyToNull(str1); String tempStr5= Strings.emptyToNull(str2); String tempStr6= Strings.emptyToNull(str3); System.out.println("|"+tempStr4+"|"); // |null| System.out.println("|"+tempStr5+"|"); // |null| System.out.println("|"+tempStr6+"|"); // |娃哈哈| } }
三. Preconditions类
- 所在包:com.google.common.base
- 概述:用来做参数校验
- 常用方法
public static <T> T checkNotNull(T reference, @NullableDecl Object errorMessage):判断参数是否为null。如果为null,则抛出NullPointerException空指针异常。
public static void checkArgument(boolean expression, @NullableDecl Object errorMessage):判断参数是否符合某种条件。当不符合条件时,则抛出illegalArgumentException异常。
public static int checkElementIndex(int index, int size, @NullableDecl String desc):判断index是否在[0,size)范围内。如果在0<=index<size,则通过;否则,抛出IndexOutOfBoundsException异常。 - 使用示例
public class PreconditionsTest { public static void main(String[] args) throws Exception{ // 1. 校验通过示例 Person person = new Person("xixi",24,"西西吃烤肉去了~"); check(person); // 输出结果:参数校验通过! // 2. 校验未通过示例 Person person2 = new Person(null,24,"西西吃烤肉去了~"); check(person); // 输出结果:见下 } public static void check(Person person){ Preconditions.checkNotNull(person.getName(), "Name may not be Null!"); Preconditions.checkArgument(person.getAge() >= 18 && person.getAge() < 99, "age must in range (18,99)"); Preconditions.checkArgument(person.getDecs() !=null, "desc may not be Null "); Preconditions.checkElementIndex(0,7,"0<=index<size"); System.out.println("参数校验通过!"); } } class Person{ String name; int age; String decs; //getter and setter }
- 校验未通过的输出结果
objc[49493]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/bin/java (0x1020374c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x1020b74e0). One of the two will be used. Which one is undefined.
java.lang.NullPointerException: Name may not be Null!
at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:900)
at guava.PreconditionsTest.check(PreconditionsTest.java:21)
at guava.PreconditionsTest.main(PreconditionsTest.java:11)
Name may not be Null!
四. Optional类
1. 背景与概述
- Optional类出现的背景:Java应用程序最常见的空指针异常
- 解决空指针异常的通用解决方法
if(name != null){ name.defaultName(); } - 概述
- 为了解决空指针异常,Google公司最先在Guava项目中引入
Optional类,通过检查空值的方式来防止代码污染。 - 受Google Guava的启发,
Optional类已成为Java 8类库的一部分。Optional实际上是个容器:它可以保存类型为T的值,或者仅仅保存null。 Optional类提供了很多有用的方法,这样就可以不显式进行空值检测。
- 为了解决空指针异常,Google公司最先在Guava项目中引入
2. Guava Optional类
2.1 概述
- Guava的Optional实例要么包含一个非空对象,要么什么都不包含,但不会出现包含一个空引用的情况。因此一个Optional对象定义了两种类型来分别表示它们: Present和Absent。
2.2 常用方法
- 创建Optional实例的方法
public static <T> Optional<T> of(T reference):创建一个包含非空对象的Optional。如果reference为null,则抛出NullPointerException。public static <T> Optional<T> absent():创建一个不包含对象的Optional实例(Absent)。public static <T> Optional<T> fromNullable(@Nullable T nullableReference):如果nullableReference非空,则创建一个包含这个非空对象的Optional实例;否则创建一个不包含对象的Optional实例(Absent)。
- 获得被包装对象的方法
public abstract T get():返回被包含的对象。如果实例是Absent,则抛出illegalStateException。public abstract T or(T defaultValue):返回被包含的对象。如果实例是Absent,返回defaultValue。public abstract T orNull():返回被包含的对象。如果实例是Absent,返回Null。
2.3 源码参考
- Optional类
public abstract class Optional<T> implements Serializable {
// 1. 创建Optional实例
public static <T> Optional<T> of(T reference) {
return new Present<T>(checkNotNull(reference));
}
public static <T> Optional<T> absent() {
return Absent.withType();
}
public static <T> Optional<T> fromNullable(@NullableDecl T nullableReference) {
return (nullableReference == null) ? Optional.<T>absent() : new Present<T>(nullableReference);
}
// 2. 是否为Present对象
public abstract boolean isPresent();
// 3. 获得对象
public abstract T get();
public abstract T or(T defaultValue);
public abstract T orNull();
}
- Present类
final class Present<T> extends Optional<T> {
private final T reference;
@Override
public boolean isPresent() {
return true;
}
@Override
public T get() {
return reference;
}
@Override
public T or(T defaultValue) {
checkNotNull(defaultValue, "use Optional.orNull() instead of Optional.or(null)");
return reference;
}
@Override
public T orNull() {
return reference;
}
}
- Absent类
final class Absent<T> extends Optional<T> {
static final Absent<Object> INSTANCE = new Absent<Object>();
static <T> Optional<T> withType() {
return (Optional<T>) INSTANCE;
}
@Override
public boolean isPresent() {
return false;
}
@Override
public T get() {
throw new IllegalStateException("Optional.get() cannot be called on an absent value");
}
@Override
public T or(T defaultValue) {
return checkNotNull(defaultValue, "use Optional.orNull() instead of Optional.or(null)");
}
public T orNull() {
return null;
}
}
2.4 测试
// 1. Absent对象
Optional<Integer> optionalAbsent = Optional.absent();
// Integer b = optionalAbsent.get(); // 抛出IllegalStateException
Integer a = optionalAbsent.or(2); // 2
Integer c = optionalAbsent.orNull(); // null
// 2. Present对象
Optional<Integer> optionalPresent = Optional.of(3);
Integer aa = optionalPresent.get(); //3
Integer bb = optionalPresent.or(3); //3
Integer cc = optionalPresent.orNull(); //3
3. Java 8 中Optional类
3.1 部分源码
public final class Optional<T> {
private static final Optional<?> EMPTY = new Optional<>();
private final T value;
private Optional() {
this.value = null;
}
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
public static<T> Optional<T> empty() {
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
public boolean isPresent() {
return value != null;
}
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
public T orElse(T other) {
return value != null ? value : other;
}
public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent())
return this;
else
return predicate.test(value) ? this : empty();
}
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}
}
3.2 创建Optional对象的方法
- 方法概述
public static <T> Optional<T> of(T value):创建一个包含非空对象的Optional。如果value为null,则抛出NullPointerException。public static <T> Optional<T> ofNullable(T value):创建一个Optional对象。如果value非空,则创建一个包含这个非空对象的Optional实例;否则,创建一个不包含对象的Optional实例。public static<T> Optional<T> empty():创建一个不包含对象的Optional实例。
- 使用
// 1. Optional.of() Optional<Integer> optional1 = Optional.of(1); // Optional<Integer> optional2 = Optional.of(null); // NullPointerException // 2. Optional.ofNullable() Optional<Integer> optional3 = Optional.ofNullable(2); Optional<Integer> optional4 = Optional.ofNullable(null); Optional<Integer> optional5 = Optional.ofNullable(null); // 3. Optional.empty() Optional<Integer> optional6 = Optional.empty(); System.out.println(optional4==optional5); //true System.out.println(optional5==optional6); // true
3.3 判断值是否存在
- 概述
public boolean isPresent():判断值是否存在。
- 使用
Optional<Integer> optional1 = Optional.of(1); Optional<Integer> optional2 = Optional.ofNullable(null); boolean optional1FLag = optional1.isPresent(); // true boolean optional2Flag = optional2.isPresent(); // false
3.4 获得值
- 概述
public T get():如果optional对象的value值不为空,则返回该value;否则,抛出NoSuchElementException异常。public T orElse(T other):如果optional对象保存的value值不为null,则返回value值,否则返回other值。
- 使用
Optional<Integer> optional1 = Optional.of(1); Optional<Integer> optional2 = Optional.ofNullable(null); // 1. get() System.out.println(optional1.get()); // 1 System.out.println(optional2.get()); // 抛出NoSuchElementException // 2. orElse(T other) System.out.println(optional1.orElse(1000)); // 1 System.out.println(optional2.orElse(1000)); // 1000
3.5 ifPresent(Consumer consumer)
- 概述
public void ifPresent(Consumer<? super T> consumer):如果option对象保存的value值不为null,则调用consumer对象,否则不调用。- Consumer类
@FunctionalInterface public interface Consumer<T> { void accept(T t); default Consumer<T> andThen(Consumer<? super T> after) { Objects.requireNonNull(after); return (T t) -> { accept(t); after.accept(t); }; } }
- 使用
Optional<Integer> optional1 = Optional.of(1); Optional<Integer> optional2 = Optional.ofNullable(null); // 如果value不是null,则调用Consumer optional1.ifPresent(new Consumer<Integer>() { @Override public void accept(Integer t) { System.out.println("value is " + t); // value is 1 } }); // 如果value为null,则不调用Consumer optional2.ifPresent(new Consumer<Integer>() { @Override public void accept(Integer t) { System.out.println("value is " + t); // optional2的ifPresent()方法不会被调用 } });
3.6 filter(Predicate predicate)
- 概述
public Optional<T> filter(Predicate<? super T> predicate):如果optional实例的value值存在,并且value值满足给定的predicate.test()方法,则返回该Optional实例;否则,返回一个empty Optional实例。如果predicate为null,则抛出NullPointerException。- Predicate类
@FunctionalInterface public interface Predicate<T> { boolean test(T t); // ... }
- 使用
Optional<Integer> optional1 = Optional.of(1); Optional<Integer> optional2 = Optional.ofNullable(null); Optional<Integer> filter1 = optional1.filter((a) -> a == null); System.out.println(filter1.isPresent()); // false Optional<Integer> filter2 = optional1.filter((a) -> a == 1); System.out.println(filter2.isPresent()); // true Optional<Integer> filter3 = optional2.filter((a) -> a == null); System.out.println(filter3.isPresent()); // false
3.7 map(Function mapper)
- 概述
public<U> Optional<U> map(Function<? super T, ? extends U> mapper):如果value值不为null,则对value值进行函数运算,并返回新的Optional(可以是任何类型),否则返回一个empty的optional实例。如果function对象为null,抛出NullPointerException异常。- Function类
@FunctionalInterface public interface Function<T, R> { R apply(T t); // ... }
- 使用
Optional<Integer> optional1 = Optional.of(1); Optional<Integer> optional2 = Optional.ofNullable(null); Optional<String> mapOptional1 = optional1.map((a) -> "key" + a); Optional<String> mapOptional2 = optional2.map((a) -> "key" + a); System.out.println(mapOptional1.get()); // key1 System.out.println(mapOptional2.isPresent());// false
五. Guava 集合
1. 集合创建和初始化
/**
* 集合创建
*/
List<String> list = Lists.newArrayList();
Map<String,Object> map = Maps.newHashMap();
/**
* 集合创建并初始化
*/
List<String> list2 = Lists.newArrayList("one","two","three");
Set<String> set2 = Sets.newHashSet("1","2","3");
2. 创建不可变集合
-
之前用法:
Collections.unmodifiableList(),并不是真正的不可变集合 -
Collections.unmodifiableList()的使用List<String> list = new ArrayList<String>(); list.add("1"); list.add("2"); list.add("3"); final List<String> imList = Collections.unmodifiableList(list); System.out.println(imList); // [1, 2, 3] // imList.add("1"); //抛出异常一切看起来很不错。但如果有用户修改了list,会发生什么情况?
List<String> list = new ArrayList<String>(); list.add("1"); list.add("2"); list.add("3"); final List<String> imList = Collections.unmodifiableList(list); System.out.println(imList); // [1, 2, 3] list.add("1"); System.out.println(imList); //[1, 2, 3, 1]可见,我们的不可变集合imList此时增加了一个元素,因此Collections.unmodifiableList(…)实现的不是真正的不可变集合,当原始集合被修改后,不可变集合里面的元素也是跟着发生变化。
-
Guava提供的Immutable:真正的不可变集合
/** * 常量List */ ImmutableList<String> imList = ImmutableList.of("a","b","c"); //imList.add("2"); //抛出异常 for(String s:imList){ System.out.println(s); } /** * 常量Map */ ImmutableMap<String,String> immap = new ImmutableMap.Builder<String,String>() .put("a","1") .put("b","2") .put("c", "3") .build(); for(Map.Entry<String,String> e:immap.entrySet()){ System.out.println(e.getKey()+"="+e.getValue()); } /** * 常量Set */ ImmutableSet<String> imset=ImmutableSet.of("a","b","c"); for(String s:imset){ System.out.println(s); }
参考资料
JDK8新特性:使用Optional避免null导致的NullPointerException
Guava Optional 和 Java 8 optional
Java类库Google Guava扩展项目学习笔记
Immutable不可变集合
理解不可变集合 | Guava Immutable与JDK unmodifiableList
Guava教程
本文深入解析了Google Guava库与Java8中的Optional类,涵盖了Optional的背景、使用场景、方法详解及源码分析,同时对比了Guava与Java8中Optional的不同之处,帮助开发者有效避免空指针异常,提升代码质量。
4737

被折叠的 条评论
为什么被折叠?



