前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《Guava》基础 入门

《Guava》基础 入门

作者头像
猫头虎
发布2024-04-07 19:55:43
720
发布2024-04-07 19:55:43
举报

前言

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

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

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

避免使用null

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

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

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

解决方案:

Optional

静态方法:

方法

描述

Optional.of(T)

如果给定的值不为null,直接返回,为null 抛出 NullPointException 快速失败。

Optional.absent()

返回一个空Optional对象,isPresent() 将会返回false

Optional.fromNullable(T)

将 null 引用的对象 转换成 Optional对象

代码语言:javascript
复制
**案列:**
/**
 *  为空快速失败
 */
public static void ofTest(){
    Integer value2 =  null;
    Optional<Integer> b = Optional.of(value2);
    System.out.println(b);
}
代码语言:javascript
复制
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
代码语言:javascript
复制
/**
 *  返回一个 空的 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
代码语言:javascript
复制
/**
 *  将 null 引用的对象 转换成 Optional对象
 */
public static void fromNullAble(){
    Integer value2 =  null;
    Optional<Integer> b = Optional.fromNullable(value2);
    System.out.println(b.isPresent());
}
false

非静态方法:

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

方法

描述

boolean isPresent()

判断是否为 null 实例

T get()

不为空,返回实例,为空 抛出 IllegalStateException

T or(T)

返回this中的当前值Optional,如果没有,则返回指定的默认值。

T orNull()

返回此值的当前值Optional,如果没有,则返回null。的逆运算fromNullable。

Set<T> asSet()

返回一个Set包含this中的实例的不可变单例Optional(如果有一个实例),否则返回一个空的不可变集。

T transform()

转成成 用户需要的对象

java.util.Options toJavaUtil()

转换成 java的 Options 对象

案列:

代码语言:javascript
复制
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());
}
代码语言:javascript
复制
console:true
123
123
123
[123]
123ok
123

Strings 方法使用

代码语言:javascript
复制
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()
代码语言:javascript
复制
/**
 *  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);
}
代码语言:javascript
复制
User{age=18, userName=null, ok}
User{age=18, ok}

\2. 对比

代码语言:javascript
复制
/**
 *  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.利用 比较链的方式 实现比较

代码语言:javascript
复制
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();
    }
}

参数检查

代码语言:javascript
复制
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 排序

代码语言:javascript
复制
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);
    }
}

异常处理

// 如果是 InvalidInputException 才抛出

Throwables.throwIfInstanceOf(e, InvalidInputException.class);

// 抛出不检查的异常

Throwables.throwIfUnchecked(e);

代码语言:javascript
复制
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 修饰的常量。

字符串的拼接

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

代码语言:javascript
复制
 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(可追加)接口

代码语言:javascript
复制
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();

完成效果如下

Map 拼接

代码语言:javascript
复制
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 修饰的常量。

比如:

代码语言:javascript
复制
String[] split = ",a,,b,".split(",");

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

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

字符串拆分成List集合

代码语言:javascript
复制
        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 集合

** **

代码语言:javascript
复制
String str2="name=zhang&age=18";
Map<String, String> split = Splitter.on("&")
        .withKeyValueSeparator("=")
        .split(str2);
//{name=zhang, age=18}System.out.println(split);

方法

描述

Splitter.on(char)

在出现特定的个性角色时拆分。

Splitter.on(';')

Splitter.on(CharMatcher)

在某个类别中出现任何字符时进行拆分。

Splitter.on(CharMatcher.BREAKING_WHITESPACE) Splitter.on(CharMatcher.anyOf(";,."))

Splitter.on(String)

按字面量拆分String。

Splitter.on(", ")

Splitter.on(Pattern) Splitter.onPattern(String)

按正则表达式拆分。

Splitter.onPattern("\r?\n")

Splitter.fixedLength(int)

将字符串拆分为指定固定长度的子字符串。最后一块可以小于length,但永远不会为空。

Splitter.fixedLength(3)

方法

描述

omitEmptyStrings()

自动从结果中删除空字符串。

Splitter.on(',').omitEmptyStrings().split("a,,c,d") 结果"a", "c", "d"

trimResults()

从结果中修剪空格;相当于trimResults(CharMatcher.WHITESPACE)。

Splitter.on(',').trimResults().split("a, b, c, d") 结果"a", "b", "c", "d"

trimResults(CharMatcher)

修剪CharMatcher与结果中指定的字符匹配的字符。

Splitter.on(',').trimResults(CharMatcher.is('_')).split("_a ,_b_ ,c__")返回"a ", "b_ ", "c"。

limit(int)

返回指定数目的字符串后停止拆分。

Splitter.on(',').limit(3).split("a,b,c,d") 结果 "a", "b", "c,d"

CaseFormat CaseFormat

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

Format

Example

LOWER_CAMEL

lowerCamel

LOWER_HYPHEN

lower-hyphen

LOWER_UNDERSCORE

lower_underscore

UPPER_CAMEL

UpperCamel

UPPER_UNDERSCORE

UPPER_UNDERSCORE

简单用法

代码语言:javascript
复制
//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"`。  
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-01-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档