《Guava》基础 入门

简介: 《Guava》基础 入门

前言


Guava 包含我们在基于Java的项目中依赖的Google的几个核心库:集合,缓存,原语支持,并发库,通用批注,字符串处理,I / O等。


这些工具中的每一种都会被Google员工用于生产服务中,国内很多公司都在使用,它的封装极大加快了Java开发者的开发速度。


我们日常开发中 遇到最多的Exception 可能就是NullPointException 了,那么 guava 如何来优化这个问题呢?


避免使用null


粗心地使用null可能会导致各种错误。通过研究Google代码库,我们发现不应该有95%的集合中包含任何null值,而让它们快速失败而不是静默接受它们null将对开发人员有所帮助。


null 本身的含义就是模棱两可的,在不同的语境下表达的含义都不相同。


例如,当 Map.get返回null时,可能意味着该值不存在,或者该值存在且为null。最关键的是,null不能表示null值的含义。


解决方案:


Optional

静态方法:98.png

**案列:**
/**
 *  为空快速失败
 */
public static void ofTest(){
    Integer value2 =  null;
    Optional<Integer> b = Optional.of(value2);
    System.out.println(b);
}
Exception in thread "main" java.lang.NullPointerException
  at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:877)
  at com.google.common.base.Optional.of(Optional.java:103)
  at com.sf.guava.basic.UseNullTest.ofTest(UseNullTest.java:51)
  at com.sf.guava.basic.UseNullTest.main(UseNullTest.java:24)
:UseNullTest.main() FAILED
/**
 *  返回一个 空的 Optional 对象
 */
public static void absentTest(){
    Optional<Integer> b1 = Optional.absent();
    Optional<String> b2 = Optional.absent();
    Optional<List> b3 = Optional.absent();
    System.out.println(b1.isPresent());
    System.out.println(b2.isPresent());
    System.out.println(b3.isPresent());
}
false
false
false
/**
 *  将 null 引用的对象 转换成 Optional对象
 */
public static void fromNullAble(){
    Integer value2 =  null;
    Optional<Integer> b = Optional.fromNullable(value2);
    System.out.println(b.isPresent());
}
false


非静态方法:

这些都是针对特定Optional<T>值的非静态方法。99.png


案列:

public static void select(){
    Optional optional = Optional.of("123");
    //判断是否为 null,
    System.out.println(optional.isPresent());
    //获取值
    System.out.println(optional.get());
    // 不为空返回 值,为空 返回默认值
    System.out.println(optional.or("this is default"));
    //不为空返回 值,为空返回 null
    System.out.println(optional.orNull());
    // 返回含有值的 Set 集合
    System.out.println(optional.asSet());
    // 转换成 用户想要的对象类型
    Optional transform = optional.transform(new Function() {
        @Nullable
        @Override
        public Object apply(@Nullable Object input) {
            return input+"ok";
        }
    });
    System.out.println(transform.get());
    // 转成 java 提供的 Options 对象
    System.out.println(optional.toJavaUtil().get());
}
console:true
123
123
123
[123]
123ok
123

Strings 方法使用

public static void StringsTest(){
    // 判断 是否为null 或是 Empty
    System.out.println(Strings.isNullOrEmpty(null));
    // 如果是 null 或是 "" 转换成 null
    System.out.println(Strings.emptyToNull("123"));
    // null 转成 ""
    System.out.println(Strings.nullToEmpty(null));
    // 构建 重复 count 个数的值
    System.out.println(Strings.repeat("a",10));
    // 按长度填充,补充在前面
    System.out.println(Strings.padStart("123456",10,'a'));
    // 按长度填充,补充在后面
    System.out.println(Strings.padEnd("12345",10,'a'));
    // 返回匹配的前缀
    System.out.println(Strings.commonPrefix("ac2345","acvbfdgsdf"));
    // 返回匹配的后缀
    System.out.println(Strings.commonSuffix("asdasdasef","acvbfdgsdf"));
    // 模板填充
    System.out.println(Strings.lenientFormat("this is %s","ak47"));
}

MoreObjects 使用

  1. 定制 toString()
/**
 *  1. 返回两个参数中 不为空的一个
 *  2. 如果都是空则抛出NullPointerException。
 *  3. 如果两个都不为空 则返回 第一个
 *
 *   作用 定制 toString
 */
public static void MoreObjectsTest(){
    System.out.println(MoreObjects.firstNonNull("321","123"));
    User user = new User();
    MoreObjects.ToStringHelper result = MoreObjects.toStringHelper(user)
            .add("age", "18")
            .add("userName", null);
    result.addValue("ok");
    System.out.println(result);
    //去除空值
    result.omitNullValues();
    System.out.println(result);
}
User{age=18, userName=null, ok}
User{age=18, ok}


\2. 对比

/**
 *  Objects 比较
 */
public static void objectsTest(){
    String str1 = "123";
    String str2 = new String("123");
    // 检查 可能为空 的对象时 不会出现 NullPointException
    System.out.println(Objects.equal("a", "a"));// 打印 true
    System.out.println(Objects.equal(null, "a"));// 打印 false
    System.out.println(Objects.equal("a", null));// 打印 false
    System.out.println(Objects.equal(null, null)); // 打印 true
    System.out.println(Objects.equal(str1, str2)); // 打印 true
}


3.利用 比较链的方式 实现比较

package com.sf.guava.basic;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Ordering;
/**
 * @Classname ObjectsTest
 * @Description Objects 使用
 * @Date 2019/12/15 0015 17:48
 * @Created by 埔枘
 */
public class ObjectsTest {
    public static void main(String[] args) {
        Person person1 = new Person();
        person1.setFirstName("321");
        person1.setLastName("123");
        person1.setZipCode(3);
        Person person2 = new Person();
        person2.setFirstName("321");
        person2.setLastName("123");
        person2.setZipCode(2);
        System.out.println(person1.compareTo(person2));
    }
}
class Person implements Comparable<Person>{
    private String lastName;
    private String firstName;
    private int zipCode;
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public int getZipCode() {
        return zipCode;
    }
    public void setZipCode(int zipCode) {
        this.zipCode = zipCode;
    }
    @Override
    public int compareTo(Person other) {
         //JDK 方式 实现
//        int cmp = lastName.compareTo(other.lastName);
//        if (cmp != 0) {
//            return cmp;
//        }
//        cmp = firstName.compareTo(other.firstName);
//        if (cmp != 0) {
//            return cmp;
//        }
//        return Integer.compare(zipCode, other.zipCode);
        // 通过 比较链的方式 比较
        return ComparisonChain.start()
                .compare(this.lastName, other.lastName)
                .compare(this.firstName, other.firstName)
                .compare(this.zipCode, other.zipCode, Ordering.natural().nullsLast())
                .result();
    }
}

参数检查

package com.sf.guava.basic;
import com.google.common.base.Preconditions;
/**
 * @Classname PreconditionsTest
 * @Description 参数检查
 * @Date 2019/12/6 0006 18:22
 * @Created by 埔枘
 */
public class PreconditionsTest {
    public static void main(String[] args) {
        try {
            System.out.println(sqrt(-3.0));
        }catch(IllegalArgumentException e){
            System.out.println(e.getMessage());
        }
        try {
            System.out.println(sum(null,3));
        }catch(NullPointerException e){
            System.out.println(e.getMessage());
        }
        try {
            System.out.println(getValue(6));
        }catch(IndexOutOfBoundsException e){
            System.out.println(e.getMessage());
        }
    }
    public static double sqrt(double input) throws IllegalArgumentException {
        Preconditions.checkArgument(input > 0.0,
                "Illegal Argument passed: Negative value %s.", input);
        return Math.sqrt(input);
    }
    public static int sum(Integer a, Integer b){
        a = Preconditions.checkNotNull(a,
                "Illegal Argument passed: First parameter is Null.");
        b = Preconditions.checkNotNull(b,
                "Illegal Argument passed: Second parameter is Null.");
        return a+b;
    }
    public static int getValue(int input){
        int[] data = {1,2,3,4,5};
        Preconditions.checkElementIndex(input,data.length,
                "Illegal Argument passed: Invalid index.");
        return 0;
    }
}


Ordering 排序

package com.sf.guava.basic;
import com.google.common.collect.Ordering;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
 * @Classname OrderingTest
 * @Description 排序
 * @Date 2019/12/6 0006 18:27
 * @Created by 埔枘
 */
public class OrderingTest {
    public static void main(String[] args) {
    }
    private static void addList(List<Integer> numbers) {
        numbers.add(new Integer(5));
        numbers.add(new Integer(2));
        numbers.add(new Integer(15));
        numbers.add(new Integer(51));
        numbers.add(new Integer(53));
        numbers.add(new Integer(35));
        numbers.add(new Integer(45));
        numbers.add(new Integer(32));
        numbers.add(new Integer(43));
        numbers.add(new Integer(16));
    }
    //自然排序
    public static void  natural(){
        List<Integer> numbers = new ArrayList<Integer>();
        addList(numbers);
        //自然排序
        Ordering ordering = Ordering.natural();
        System.out.println("Input List: ");
        System.out.println(numbers);
        Collections.sort(numbers,ordering );
        System.out.println("Sorted List: ");
        System.out.println(numbers);
    }
    //是否已经排序
    public static void isOrdered(){
        List<Integer> numbers = new ArrayList<Integer>();
        Ordering ordering = Ordering.natural();
        addList(numbers);
        //判断是否已经排序完成
        System.out.println("List is sorted: " + ordering.isOrdered(numbers));
    }
    //获取最值
    public static void maxOrMin(){
        List<Integer> numbers = new ArrayList<Integer>();
        Ordering ordering = Ordering.natural();
        System.out.println("Minimum: " + ordering.min(numbers));
    }
    //反序
    public static void reverse(){
        List<Integer> numbers = new ArrayList<Integer>();
        Ordering ordering = Ordering.natural();
        Collections.sort(numbers,ordering.reverse());
        System.out.println("Reverse: " + numbers);
    }
    //把 null 排到第一个
    public static void firstNull(){
        List<Integer> numbers = new ArrayList<Integer>();
        Ordering ordering = Ordering.natural();
        Collections.sort(numbers,ordering.nullsFirst());
        System.out.println("Null first Sorted List: ");
        System.out.println(numbers);
    }
}


100.gif

异常处理


// 如果是 InvalidInputException 才抛出


Throwables.throwIfInstanceOf(e, InvalidInputException.class);


// 抛出不检查的异常


Throwables.throwIfUnchecked(e);

package com.sf.guava.basic;
import com.google.common.base.Throwables;
import java.io.IOException;
/**
 * @Classname ThrowablesTest
 * @Description 异常
 * @Date 2019/12/11 0011 17:07
 * @Created by 埔枘
 */
public class ThrowablesTest {
    public static void main(String[] args) {
        ThrowablesTest throwablesTest = new ThrowablesTest();
        try {
            throwablesTest.showcaseThrowables();
        } catch (InvalidInputException e) {
            //get the root cause
            System.out.println(Throwables.getRootCause(e));
        }catch (Exception e) {
            //get the stack trace in string format
            System.out.println(Throwables.getStackTraceAsString(e));
        }
    }
    public void showcaseThrowables() throws InvalidInputException{
        try {
            sqrt(-3.0);
        } catch (Throwable e) {
            //此方法 已不推荐 使用
//            Throwables.propagateIfInstanceOf(e, InvalidInputException.class);
            // 如果是 InvalidInputException 才抛出
            Throwables.throwIfInstanceOf(e, InvalidInputException.class);
            // 抛出不检查的异常
            Throwables.throwIfUnchecked(e);
        }
    }
    public void showcaseThrowables1(){
        try {
            int[] data = {1,2,3};
            getValue(data, 4);
        } catch (Throwable e) {
            Throwables.propagateIfInstanceOf(e, IndexOutOfBoundsException.class);
            Throwables.propagate(e);
        }
    }
    public double sqrt(double input) throws InvalidInputException{
        if(input < 0) throw new InvalidInputException();
        return Math.sqrt(input);
    }
    public double getValue(int[] list, int index) throws IndexOutOfBoundsException {
        return list[index];
    }
    public void dummyIO() throws IOException {
        throw new IOException();
    }
}
class InvalidInputException extends Exception {
}


Joiner 联接器


用分隔符将字符串序列连接在一起通常会很棘手,一般做法是通过for循环拼接,但事实并非如此。如果您的序列包含空值,则可能会更加困难。


Joiner使其变得简单。


线程安全问题:


Joiner 的实例本身是不可变的,on 方法每次都会返回一个新的实例,这使得Joiner 线程安全,可用于 static final 修饰的常量。


字符串的拼接

链式编程方式完美处理了字符串拼接问题,并提供了各种特性

 List<Integer> eleList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, null);
        //分隔符
        //线程安全--不可变类
        String joinStr = Joiner.on("#")
                // 替换 null 内容 or skipNulls 二选一
                .useForNull("ak47")
                //过滤null元素
//                .skipNulls()
                //要分割的集合
                .join(eleList);
        //console : 1#2#3#4#5#6#7
        System.out.println(joinStr);


文件内容拼接

要求被拼接的Class 实现了 Appendable(可追加)接口

FileWriter fileWriter = new FileWriter(new File("path.txt"));
List<String> dateList = new ArrayList<>();
dateList.add("123");
dateList.add("abc");
Joiner joiner = Joiner.on("#").useForNull(" ");
//returns the FileWriter instance with the values appended into it
FileWriter fileWriter1 = joiner.appendTo(fileWriter, dateList);
fileWriter1.write("test context");
fileWriter1.flush();


完成效果如下101.png


Map 拼接

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");
String returnedString = Joiner.on("#").withKeyValueSeparator("=").join(testMap);
// Washington D.C=Redskins#New York City=Giants#Philadelphia=Eagles#Dallas=Cowboys
System.out.println(returnedString);


Splitter 分离器


用于拆分字符串的内置Java实用程序具有一些古怪的行为。


线程安全:


Splitter 的实例本身是不可变的,on 方法每次都会返回一个新的实例,这使得Splitter 线程安全,可用于 static final 修饰的常量。


比如:


String[] split = ",a,,b,".split(",");

结果如下: 发现没有b 后面的被忽略了… 我滴个亲娘额


102.png


使用Splitter 完美解决,并提供了更多的操作特性

字符串拆分成List集合

        String str="1,2,3,4,5,6,7    ";
        List<String> stringList = Splitter.on(",")
                // 去空格
//                .trimResults()
                .trimResults(new CharMatcher() {
                    @Override
                    public boolean matches(char c) {
                        //忽略 符合条件的
                        if(c == 49){
                            return true;
                        }
                        return false;
                    }
                })
                //过滤空字符串
                .omitEmptyStrings()
                //分路器,类似分页
//                .limit(2)
                .splitToList(str);
        //[2, 3, 4, 5, 6, 7    ]        System.out.println(stringList);


字符串拆分成Map 集合

**

**

String str2="name=zhang&age=18";
Map<String, String> split = Splitter.on("&")
        .withKeyValueSeparator("=")
        .split(str2);
//{name=zhang, age=18}System.out.println(split);

111.png1112.png


CaseFormat CaseFormat

CaseFormat是一个方便的小类,用于在ASCII大小写约定之间进行转换,例如,编程语言的命名约定。支持的格式包括:113.png


简单用法

//constantName  大写下划线  转 小写驼峰
System.out.println(CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, "CONSTANT_NAME"));
//abcDfg        小写连字符 转小写驼峰
System.out.println(CaseFormat.LOWER_HYPHEN.to(CaseFormat.LOWER_CAMEL, "abc-dfg"));
"_a ,_b_ ,c__")`返回`"a ", "b_ ", "c"`。  
目录
相关文章
|
3月前
|
设计模式 存储 缓存
Guava 源码中7种设计模式的实现分析
V 哥在学习 Guava 源码中总结的7个设计模式的实现分析,欢迎关注威哥爱编程,做自己的技术,让别人去卷吧。
|
5月前
|
Java 数据库连接
提升编程效率的利器: 解析Google Guava库之IO工具类(九)
提升编程效率的利器: 解析Google Guava库之IO工具类(九)
|
5月前
|
缓存 算法 Java
提升编程效率的利器: 解析Google Guava库之常用工具类-40个示例(七)
提升编程效率的利器: 解析Google Guava库之常用工具类-40个示例(七)
|
5月前
|
监控 安全 算法
提升编程效率的利器: 解析Google Guava库之RateLimiter优雅限流(十)
提升编程效率的利器: 解析Google Guava库之RateLimiter优雅限流(十)
|
5月前
|
缓存 安全 Java
提升编程效率的利器: 解析Google Guava库之集合工具类-50个示例(八)
提升编程效率的利器: 解析Google Guava库之集合工具类-50个示例(八)
|
6月前
|
XML Java 测试技术
Java异常处理神器:Guava Throwables类概念与实战
【4月更文挑战第29天】在Java开发中,异常处理是保证程序稳定性和可靠性的关键。Google的Guava库提供了一个强大的工具类Throwables,用于简化和增强异常处理。本篇博客将探讨Throwables类的核心功能及其在实战中的应用。
110 2
|
6月前
|
存储 安全 Java
【Java技术专题】「Guava开发指南」手把手教你如何进行使用Guava工具箱进行开发系统实战指南(不可变集合篇)
【Java技术专题】「Guava开发指南」手把手教你如何进行使用Guava工具箱进行开发系统实战指南(不可变集合篇)
75 1
|
6月前
|
Java API Apache
【Java技术专题】「Guava开发指南」手把手教你如何进行使用Guava工具箱进行开发系统实战指南(基础编程篇)
【Java技术专题】「Guava开发指南」手把手教你如何进行使用Guava工具箱进行开发系统实战指南(基础编程篇)
84 0
|
6月前
|
存储 缓存 Java
Guava常用工具库整理
Guava常用工具库整理
|
设计模式 缓存 Java
Java两大工具库:Commons和Guava(6)
除了操作集合、限流和缓存,Guava还有另一个隐秘的功能:事件总线EventBus机制——是发布-订阅模式的实现,不需要显式地注册回调——比观察者模式更灵活。
145 0
下一篇
无影云桌面