admin 1 rok temu
rodzic
commit
01b600b217
41 zmienionych plików z 2786 dodań i 0 usunięć
  1. 64 0
      guavaGoogle/pom.xml
  2. 57 0
      guavaGoogle/src/main/java/org/example/base/LowerCaseDomain.java
  3. 18 0
      guavaGoogle/src/main/java/org/example/base/ObjectsGuava.java
  4. 32 0
      guavaGoogle/src/main/java/org/example/base/OptionalGuava.java
  5. 71 0
      guavaGoogle/src/main/java/org/example/base/OrderingGuava.java
  6. 56 0
      guavaGoogle/src/main/java/org/example/base/PreconditionsGuava.java
  7. 41 0
      guavaGoogle/src/main/java/org/example/cache/CacheEmployee.java
  8. 36 0
      guavaGoogle/src/main/java/org/example/collections/ImmutableGuava.java
  9. 57 0
      guavaGoogle/src/main/java/org/example/collections/MultisetGuava.java
  10. 34 0
      guavaGoogle/src/main/java/org/example/concurrency/AbstractExecutionThreadServiceImpl.java
  11. 35 0
      guavaGoogle/src/main/java/org/example/concurrency/AbstractScheduledServiceImpl.java
  12. 18 0
      guavaGoogle/src/main/java/org/example/eventBus/OrderEventListener.java
  13. 19 0
      guavaGoogle/src/main/java/org/example/eventBus/OrderMessage.java
  14. 6 0
      guavaGoogle/src/main/java/org/example/hasing/Male.java
  15. 49 0
      guavaGoogle/src/main/java/org/example/hasing/Person.java
  16. 63 0
      guavaGoogle/src/main/java/org/example/io/IOOperation.java
  17. 25 0
      guavaGoogle/src/main/java/org/example/math/MathGuava.java
  18. 50 0
      guavaGoogle/src/test/java/org/example/base/RangeGuava.java
  19. 60 0
      guavaGoogle/src/test/java/org/example/base/StopwatchTest.java
  20. 65 0
      guavaGoogle/src/test/java/org/example/base/ThrowablesTests.java
  21. 117 0
      guavaGoogle/src/test/java/org/example/cache/CacheTest.java
  22. 29 0
      guavaGoogle/src/test/java/org/example/collections/BimapTest.java
  23. 199 0
      guavaGoogle/src/test/java/org/example/collections/MapsTest.java
  24. 107 0
      guavaGoogle/src/test/java/org/example/collections/MultimapsTest.java
  25. 49 0
      guavaGoogle/src/test/java/org/example/collections/RangeMapTest.java
  26. 69 0
      guavaGoogle/src/test/java/org/example/collections/RangeSetTest.java
  27. 137 0
      guavaGoogle/src/test/java/org/example/collections/TableTest.java
  28. 52 0
      guavaGoogle/src/test/java/org/example/concurrency/AbstractExecutionThreadServiceTest.java
  29. 53 0
      guavaGoogle/src/test/java/org/example/concurrency/AbstractScheduledServiceImplTest.java
  30. 62 0
      guavaGoogle/src/test/java/org/example/concurrency/ListenableFutureGuava.java
  31. 54 0
      guavaGoogle/src/test/java/org/example/concurrency/ServiceManagerTest.java
  32. 20 0
      guavaGoogle/src/test/java/org/example/eventBus/EventBusTest.java
  33. 82 0
      guavaGoogle/src/test/java/org/example/functional/FunctionsPredicatesTest.java
  34. 101 0
      guavaGoogle/src/test/java/org/example/hashing/HashingTest.java
  35. 286 0
      guavaGoogle/src/test/java/org/example/primitives/IntsTest.java
  36. 26 0
      guavaGoogle/src/test/java/org/example/reflection/GuavaReflectionExample.java
  37. 26 0
      guavaGoogle/src/test/java/org/example/string/CaseFormatTest.java
  38. 207 0
      guavaGoogle/src/test/java/org/example/string/CharMatcherTest.java
  39. 89 0
      guavaGoogle/src/test/java/org/example/string/JoinTest.java
  40. 97 0
      guavaGoogle/src/test/java/org/example/string/SplitterTest.java
  41. 68 0
      guavaGoogle/src/test/java/org/example/string/StringsTest.java

+ 64 - 0
guavaGoogle/pom.xml

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.example</groupId>
+    <artifactId>guavaGoogle</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.2.2.RELEASE</version>
+    </parent>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context-support</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>30.0-jre</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 57 - 0
guavaGoogle/src/main/java/org/example/base/LowerCaseDomain.java

@@ -0,0 +1,57 @@
+package org.example.base;
+
+import com.google.common.collect.ContiguousSet;
+import com.google.common.collect.DiscreteDomain;
+import com.google.common.collect.Range;
+
+/**
+ * 自定义离散域 DiscreteDomain
+ * Range
+ */
+
+public class LowerCaseDomain extends DiscreteDomain<Character> {
+    private static LowerCaseDomain domain = new LowerCaseDomain();
+
+    public static DiscreteDomain letters() {
+        return domain;
+    }
+
+    @Override
+    public Character next(Character value) {
+        return (char) (value + 1);
+    }
+
+    @Override
+    public Character previous(Character value) {
+        return (char) (value - 1);
+    }
+
+    @Override
+    public long distance(Character start, Character end) {
+        return end - start;
+    }
+
+    @Override
+    public Character minValue() {
+        return 'a';
+    }
+
+    @Override
+    public Character maxValue() {
+        return 'z';
+    }
+
+    public static void main(String[] args) {
+        // a b c d e f g h i j k l m n o p q r s t u v w x y z
+        for (Object i : ContiguousSet.create(Range.closed('a', 'z'), LowerCaseDomain.letters())) {
+            System.out.print(i + " ");
+        }
+
+        System.out.println();
+
+// m n o p q r s t u v w x y z
+        for(Object i : ContiguousSet.create(Range.atLeast('m'), LowerCaseDomain.letters())) {
+            System.out.print(i + " ");
+        }
+    }
+}

+ 18 - 0
guavaGoogle/src/main/java/org/example/base/ObjectsGuava.java

@@ -0,0 +1,18 @@
+package org.example.base;
+
+import com.google.common.base.Objects;
+
+// 使用和避免null:使用Objects.equal
+
+public class ObjectsGuava {
+    public static void main(String[] args) {
+        System.out.println(Objects.equal("a", "a"));
+        System.out.println(Objects.equal(null, "a"));
+        System.out.println(Objects.equal("a", null));
+        System.out.println(Objects.equal(null, null));
+        System.out.println(Objects.hashCode("a"));
+        System.out.println(Objects.hashCode("a"));
+        System.out.println(Objects.hashCode(null));
+        System.out.println(Objects.hashCode(null));
+    }
+}

+ 32 - 0
guavaGoogle/src/main/java/org/example/base/OptionalGuava.java

@@ -0,0 +1,32 @@
+package org.example.base;
+
+import com.google.common.base.Optional;
+
+// 使用和避免null: 创建Optional实例
+
+public class OptionalGuava {
+    public static void main(String[] args) {
+        Optional<String> str=  Optional.of("5") ;
+        // T get() 返回Optional所包含的引用,若引用缺失,则抛出java.lang.IllegalStateException
+        // T or(T) 返回Optional所包含的引用,若引用缺失,返回指定的值
+        if(str.isPresent())
+            System.out.println(str.get() + " " + str.or("31"));
+//        5 5
+
+
+        Optional<String> str2=  Optional.fromNullable(null);
+        if(!str2.isPresent())
+            System.out.println(str2.or("22"));
+//        22
+
+        Optional<Object> p = Optional.fromNullable(null) ;
+        System.out.println(p.isPresent());
+        System.out.println(p.or(4));
+        // 返回Optional所包含的引用,若引用缺失,返回null
+        System.out.println(p.orNull());
+        // 返回Optional所包含引用的单例不可变集。<br>如果引用存在,返回一个只有单一元素的集合,如果引用缺失,返回一个空集合。
+        System.out.println(p.asSet());
+        System.out.println(p.toString());
+        System.out.println(p.get());
+    }
+}

+ 71 - 0
guavaGoogle/src/main/java/org/example/base/OrderingGuava.java

@@ -0,0 +1,71 @@
+package org.example.base;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Ordering;
+import com.google.common.primitives.Ints;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+// 排序器
+
+public class OrderingGuava {
+    public static void main(String[] args) {
+        //对可排序类型做自然排序,如数字按大小,日期按先后排序
+        Ordering<Comparable> natural = Ordering.natural();
+        System.out.println(natural.isOrdered(new ArrayList<Integer>(Arrays.asList(1,4,3))));
+        //按对象的字符串形式做字典排序
+        Ordering.usingToString();
+        //把给定的Comparator转化为排序器或者继承Ordering实现自定义排序器
+        Ordering<Integer> from = Ordering.from((Integer x, Integer y) -> Ints.compare(x, y));
+        System.out.println(from.max(5, 6));
+
+
+        //扩展排序器
+        Ordering<Comparable> natural1 = Ordering.natural();
+        natural1.max(1, 2); //2
+        //获取语义相反的排序器
+        natural1.reverse().max(1, 2); //1
+        List<Integer> list = Lists.newArrayList(5, 9, 3, 7, 4);
+        Collections.sort(list,natural1.nullsFirst()); //使用排序器对集合排序
+        list.forEach(x-> System.out.print(x+" ")); //3, 4, 5, 7, 9
+        System.out.println();
+
+        // 不使用这两个排序器,排序元素不能为null,否则会报空指针
+        natural1.nullsFirst();//使用当前排序器,并把null值排到最前
+        natural1.nullsLast();//使用当前排序器,并把null值排到最后
+
+        natural1.compound(natural1);//合成另一个比较器,以处理当前排序器中的相等情况,即添加第二个比较器
+
+        //onResultOf:将function应用在各个元素上之后, 在使用原始ordering进行排序
+        Collections.sort(list,natural1.onResultOf(x->x*(-1)));//元素变为负数再排序
+        list.forEach(x-> System.out.print(x+" ")); //9, 7, 5, 4, 3
+        System.out.println();
+
+        // 使用排序器
+        Ordering<Comparable> natural3 = Ordering.natural();
+        List<Integer> list02 = Lists.newArrayList(6,4,9,3,1,5,3);
+        /**
+         * greatestOf: 获取可迭代对象中最大的k个元素,并按从大到小排序,返回一个集合
+         * leastOf: 获取最小的几个,并按从小到大排序
+         */
+        natural3.greatestOf(list02,1).forEach(x-> System.out.println(x)); //9
+        natural3.leastOf(list02,1).forEach(x-> System.out.println(x)); //1
+        //返回集合的一个排好序的副本
+        natural3.sortedCopy(list02);
+        natural3.immutableSortedCopy(list02); //返回不可变的排序副本
+        /**
+         * isOrdered: 判断是否已经按排序器有序,元素不能少于2,允许有相等元素
+         * isStrictlyOrdered: 是否严格排序,不允许有相等元素
+         */
+        Collections.sort(list02,natural3);
+        natural3.isOrdered(list02);//true
+        natural3.isStrictlyOrdered(list02); //false
+        //其他直接比较元素
+        System.out.println(natural3.compare(1,2));
+        System.out.println(natural3.max(5,6));
+        System.out.println(natural3.min(list02));
+    }
+}

+ 56 - 0
guavaGoogle/src/main/java/org/example/base/PreconditionsGuava.java

@@ -0,0 +1,56 @@
+package org.example.base;
+
+import com.google.common.base.Preconditions;
+
+import java.util.Arrays;
+
+// 前置条件
+
+public class PreconditionsGuava {
+    private String label;
+
+    private int[] values = new int[5];
+
+    private int currentIndex;
+
+    public PreconditionsGuava(String label) {
+        this.label = Preconditions.checkNotNull(label, "Label can't not be null");
+    }
+
+    public void updateCurrentIndexValue(int index, int valueToSet) {
+        // check index valid first
+        this.currentIndex = Preconditions.checkElementIndex(index, values.length, "Index out of bounds for values.");
+        // validate valueToSet
+        Preconditions.checkArgument(valueToSet <= 100, "Value can't be more than 100");
+        values[this.currentIndex] = valueToSet;
+    }
+
+    public void doOperation() {
+        Preconditions.checkState(validateObjectState(), "Can't perform operation.");
+    }
+
+    private boolean validateObjectState() {
+        return this.label.equalsIgnoreCase("open") && values[this.currentIndex] == 10;
+    }
+
+    public static void main(String[] args) {
+        PreconditionsGuava demo = new PreconditionsGuava("open");
+
+        demo.updateCurrentIndexValue(4, 10);
+
+        demo.doOperation();
+
+        System.out.println(demo.label);
+
+        System.out.println(Arrays.toString(demo.values));
+
+        System.out.println(demo.validateObjectState());
+
+        PreconditionsGuava demo1 = new PreconditionsGuava(null);
+
+        demo1.updateCurrentIndexValue(1, 1);
+
+        demo1.doOperation();
+
+    }
+}

+ 41 - 0
guavaGoogle/src/main/java/org/example/cache/CacheEmployee.java

@@ -0,0 +1,41 @@
+package org.example.cache;
+
+import com.google.common.base.MoreObjects;
+
+public class CacheEmployee {
+    String name;
+    String dept;
+    String emplD;
+
+    public CacheEmployee(String name, String dept, String empID){
+        this.name = name;
+        this.dept = dept;
+        this.emplD = empID;
+    }
+    public String getName() {
+        return name;
+    }
+    public void setName(String name) {
+        this.name = name;
+    }
+    public String getDept() {
+        return dept;
+    }
+    public void setDept(String dept) {
+        this.dept = dept;
+    }
+    public String getEmplD() {
+        return emplD;
+    }
+    public void setEmplD(String emplD) {
+        this.emplD = emplD;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(CacheEmployee.class)
+                .add("Name", name)
+                .add("Department", dept)
+                .add("Emp Id", emplD).toString();
+    }
+}

+ 36 - 0
guavaGoogle/src/main/java/org/example/collections/ImmutableGuava.java

@@ -0,0 +1,36 @@
+package org.example.collections;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.Lists;
+
+public class ImmutableGuava {
+    public static void main(String[] args) {
+        //建立 3钟方式
+        //一、of方法
+        ImmutableList<String> immutableList = ImmutableList.of("1", "3", "2");
+        System.out.println(immutableList);
+        //二、copyOf方法
+        ImmutableList<Object> immutableList1 = ImmutableList.copyOf(Lists.newArrayList(1, "abc", 3d));
+        System.out.println(immutableList1);
+        //三、builder构建
+        ImmutableList<Integer> immutableList2 = ImmutableList.<Integer>builder().add(3).add(5).add(7).build();
+        System.out.println(immutableList2);
+
+        ImmutableSet<String> immutableSet = ImmutableSet.of("beibei", "jingjing", "huanhuan");
+        System.out.println(immutableSet);
+        //不可变集合均可以使用asList方法返回一个ImmutableList视图
+        ImmutableList<String> immutableSetToList = immutableSet.asList();
+        System.out.println(immutableSetToList);
+
+        //会自动排序
+        ImmutableSortedSet<String> immutableSortedSet = ImmutableSortedSet.of("1", "32", "3");
+        System.out.println(immutableSortedSet);
+
+        ImmutableMap<String, Integer> immutableMap = ImmutableMap.of("1", 11, "2", 22);
+        System.out.println(immutableMap);
+        System.out.println(immutableMap.asMultimap());
+    }
+}

+ 57 - 0
guavaGoogle/src/main/java/org/example/collections/MultisetGuava.java

@@ -0,0 +1,57 @@
+package org.example.collections;
+
+import com.google.common.collect.HashMultiset;
+import com.google.common.collect.Multiset;
+
+import java.util.Iterator;
+import java.util.Set;
+
+public class MultisetGuava {
+    public static void main(String args[]){
+        // 创建 multiset 集合
+        Multiset<String> multiset = HashMultiset.create();
+        multiset.add("a");
+        multiset.add("b");
+        multiset.add("c");
+        multiset.add("d");
+        multiset.add("a");
+        multiset.add("b");
+        multiset.add("c");
+        multiset.add("b");
+        multiset.add("b");
+        multiset.add("b");
+
+        // 个数
+        System.out.println("Occurrence of 'b' : " + multiset.count("b"));
+        System.out.println("Total Size : " + multiset.size());
+
+        // 遍历
+        Set<String> set = multiset.elementSet();
+        System.out.print("Set [");
+        for (String s : set) {
+            System.out.print(s);
+        }
+        System.out.println("]");
+
+        // 使用迭代器
+        Iterator<String> iterator = multiset.iterator();
+        System.out.print("MultiSet [");
+        while (iterator.hasNext()) {
+            System.out.print(iterator.next());
+        }
+        System.out.println("]");
+
+        // 不同元素的个数
+        System.out.println("MultiSet [");
+        for (Multiset.Entry<String> entry : multiset.entrySet()) {
+            System.out.println("    Element: " + entry.getElement() + ", Occurrence(s): " + entry.getCount());
+        }
+        System.out.println("]");
+
+        // 删除元素
+        multiset.remove("b", 2);
+
+        // 查找元素
+        System.out.println("Occurence of 'b' : " + multiset.count("b"));
+    }
+}

+ 34 - 0
guavaGoogle/src/main/java/org/example/concurrency/AbstractExecutionThreadServiceImpl.java

@@ -0,0 +1,34 @@
+package org.example.concurrency;
+
+import com.google.common.util.concurrent.AbstractExecutionThreadService;
+import com.google.common.util.concurrent.Uninterruptibles;
+
+import java.util.concurrent.TimeUnit;
+
+public class AbstractExecutionThreadServiceImpl extends AbstractExecutionThreadService {
+
+    private volatile boolean running = true;
+    @Override
+    protected void run() throws Exception {
+        while (running) {
+            try {
+                // 等待2s
+                Uninterruptibles.sleepUninterruptibly(2, TimeUnit.SECONDS);
+                System.out.println("do our work.....");
+            } catch (Exception e) {
+                //TODO: 处理异常,这里如果抛出异常,会使服务状态变为failed同时导致任务终止。
+            }
+        }
+    }
+    @Override
+    protected void triggerShutdown() {
+        //TODO: 如果我们的run方法中有无限循环啥的,可以在这里置状态,让退出无限循环,,stopAsync()里面会调用到该方法
+        running = false; //这里我们改变状态值,run方法中就能够得到响应。=
+    }
+
+    @Override
+    protected void shutDown() throws Exception {
+        //TODO: 可以做一些清理操作,比如关闭连接啥的。shutDown() 是在线程的具体实现里面调用的
+    }
+
+}

+ 35 - 0
guavaGoogle/src/main/java/org/example/concurrency/AbstractScheduledServiceImpl.java

@@ -0,0 +1,35 @@
+package org.example.concurrency;
+
+import com.google.common.util.concurrent.AbstractScheduledService;
+
+import java.util.concurrent.TimeUnit;
+
+public class AbstractScheduledServiceImpl extends AbstractScheduledService {
+
+
+    @Override
+    protected void startUp() throws Exception {
+        //TODO: 做一些初始化操作
+    }
+
+    @Override
+    protected void shutDown() throws Exception {
+        //TODO: 可以做一些清理操作,比如关闭连接啥的。shutDown() 是在线程的具体实现里面调用的
+    }
+
+    @Override
+    protected void runOneIteration() throws Exception {
+        // 每次周期任务的执行逻辑
+        try {
+            System.out.println("do work....");
+        } catch (Exception e) {
+            //TODO: 处理异常,这里如果抛出异常,会使服务状态变为failed同时导致任务终止。
+        }
+    }
+
+    @Override
+    protected Scheduler scheduler() {
+        // 5s执行一次的Scheduler
+        return Scheduler.newFixedDelaySchedule(1, 5, TimeUnit.SECONDS);
+    }
+}

+ 18 - 0
guavaGoogle/src/main/java/org/example/eventBus/OrderEventListener.java

@@ -0,0 +1,18 @@
+package org.example.eventBus;
+
+import com.google.common.eventbus.Subscribe;
+
+public class OrderEventListener {
+
+    /**
+     * 如果发送了OrderMessage消息,会进入到该函数的处理
+     * @param event 消息
+     */
+    @Subscribe
+    public void dealWithEvent(OrderMessage event) {
+        // TODO: 收到EventTest消息之后,做相应的处理
+        System.out.println("我收到了您的命令,命令内容为:" + event.getOrderContent());
+    }
+
+}
+

+ 19 - 0
guavaGoogle/src/main/java/org/example/eventBus/OrderMessage.java

@@ -0,0 +1,19 @@
+package org.example.eventBus;
+
+public class OrderMessage {
+
+    /**
+     * 命令对应的内容
+     */
+    private String orderContent;
+
+
+    public String getOrderContent() {
+        return orderContent;
+    }
+
+    public void setOrderContent(String orderContent) {
+        this.orderContent = orderContent;
+    }
+}
+

+ 6 - 0
guavaGoogle/src/main/java/org/example/hasing/Male.java

@@ -0,0 +1,6 @@
+package org.example.hasing;
+
+
+public enum  Male {
+    man, woman;
+}

+ 49 - 0
guavaGoogle/src/main/java/org/example/hasing/Person.java

@@ -0,0 +1,49 @@
+package org.example.hasing;
+
+public class Person {
+    private int age;
+    private String name;
+    private String address;
+    private long phoneNumber;
+    private Male male;
+
+    public int getAge() {
+        return age;
+    }
+
+    public void setAge(int age) {
+        this.age = age;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    public long getPhoneNumber() {
+        return phoneNumber;
+    }
+
+    public void setPhoneNumber(long phoneNumber) {
+        this.phoneNumber = phoneNumber;
+    }
+
+    public Male getMale() {
+        return male;
+    }
+
+    public void setMale(Male male) {
+        this.male = male;
+    }
+}

+ 63 - 0
guavaGoogle/src/main/java/org/example/io/IOOperation.java

@@ -0,0 +1,63 @@
+package org.example.io;
+
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Charsets;
+import com.google.common.base.Splitter;
+import com.google.common.collect.HashMultiset;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Multiset;
+import com.google.common.hash.HashCode;
+import com.google.common.hash.Hashing;
+import com.google.common.io.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+public class IOOperation {
+    public static void main(String[] args) throws IOException {
+        //guava提供了一个源与汇的概念对应读写字节字符共有4个类ByteSource,CharSource,ByteSink,CharSink
+        URL url = new URL("http://localhost:8080/queryAll");
+        File file = new File("./temp.txt");
+        Resources.toByteArray(url);//从url中获得字节数组
+        Files.toByteArray(file);//从文件中获得字节数组
+        CharSource charSource = Files.asCharSource(file, Charsets.UTF_8);//获得字符源
+        ByteSource byteSource = Files.asByteSource(file);//获得字节源
+        Resources.asCharSource(url, Charsets.UTF_8);//从url中获得字符源
+        Resources.asByteSource(url);//从url中获得字节源
+
+        CharSink charSink = Files.asCharSink(file, Charsets.UTF_8, FileWriteMode.APPEND);//获得字符汇 以append追加方式(覆盖方式可以省略)
+        ByteSink byteSink = Files.asByteSink(file, FileWriteMode.APPEND);//或者字节汇 以append追加方式(覆盖方式可以省略)
+
+        byteSource.asCharSource(Charsets.UTF_8);//字节源转字符源
+        byteSink.asCharSink(Charsets.UTF_8);//字节汇转字符汇
+        byte[] bytes = byteSource.read();//读取出byte[]
+        String string = charSource.read();//读取出String
+        byteSource.copyTo(byteSink);//字节源copy到汇 可以使用OutputStream
+        charSource.copyTo(charSink);//字符源copy到汇 可以使用Appendable
+        byteSink.write(bytes);//写入字节
+        charSink.write(string);//写入字符(使用的是CharSequence,可以用String)
+
+//案例
+//逐行读取 以utf-8编码
+        ImmutableList<String> lines = Files.asCharSource(file, Charsets.UTF_8).readLines();
+        System.out.println(lines);
+
+//读取单词
+        Multiset<String> wordOccurrences = HashMultiset.create(
+                //以空格拆分
+                Splitter.on(CharMatcher.whitespace())
+                        .trimResults()
+                        .omitEmptyStrings()
+                        .split(Files.asCharSource(file, Charsets.UTF_8).read()));
+        System.out.println(wordOccurrences);
+
+        //获取文件按照sha1生成的hash码
+        HashCode hash = Files.asByteSource(file).hash(Hashing.sha1());
+        System.out.println(hash);
+
+//File的工具类Files
+//将url资源copy到file中
+        Resources.asByteSource(url).copyTo(Files.asByteSink(file));
+    }
+}

+ 25 - 0
guavaGoogle/src/main/java/org/example/math/MathGuava.java

@@ -0,0 +1,25 @@
+package org.example.math;
+
+import com.google.common.math.*;
+
+import java.math.BigInteger;
+import java.math.RoundingMode;
+
+import static java.math.RoundingMode.CEILING;
+import static java.math.RoundingMode.FLOOR;
+
+public class MathGuava {
+    public static void main(String[] args) {
+        int logFloor = LongMath.log2(3, FLOOR);
+        int mustNotOverflow = IntMath.checkedMultiply(121, 8746);
+        long quotient = LongMath.divide(18, 3, RoundingMode.UNNECESSARY); // fail fast on non-multiple of 3
+        BigInteger nearestInteger = DoubleMath.roundToBigInteger(348.33, RoundingMode.HALF_EVEN);
+        BigInteger sideLength = BigIntegerMath.sqrt(new BigInteger(String.valueOf(144)), CEILING);
+
+        System.out.println(logFloor);
+        System.out.println(mustNotOverflow);
+        System.out.println(quotient);
+        System.out.println(nearestInteger);
+        System.out.println(sideLength);
+    }
+}

+ 50 - 0
guavaGoogle/src/test/java/org/example/base/RangeGuava.java

@@ -0,0 +1,50 @@
+package org.example.base;
+
+import com.google.common.collect.ContiguousSet;
+import com.google.common.collect.DiscreteDomain;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Range;
+import org.junit.Test;
+
+import java.util.Set;
+
+/**
+ * 离散域 DiscreteDomain
+ * Range
+ */
+
+public class RangeGuava {
+        @Test
+        public void test6() {
+                Range<Integer> range = Range.closed(20, 30);
+                print("closed", ContiguousSet.create(range, DiscreteDomain.integers()));
+
+                range = Range.open(20, 30);
+                print("open", ContiguousSet.create(range, DiscreteDomain.integers()));
+
+                range = Range.openClosed(20, 30);
+                print("openClosed", ContiguousSet.create(range, DiscreteDomain.integers()));
+
+                range = Range.closedOpen(20, 30);
+                print("closedOpen", ContiguousSet.create(range, DiscreteDomain.integers()));
+
+                range = Range.greaterThan(20);
+                System.out.println("greaterThan: " + ContiguousSet.create(range, DiscreteDomain.integers()).toString());
+
+                range = Range.atLeast(20);
+                System.out.println("atLeast: " + ContiguousSet.create(range, DiscreteDomain.integers()).toString());
+
+                range = Range.lessThan(30);
+                System.out.println("lessThan: " + ContiguousSet.create(range, DiscreteDomain.integers()).toString());
+
+                range = Range.atMost(30);
+                System.out.println("atMost: " + ContiguousSet.create(range, DiscreteDomain.integers()).toString());
+
+                range = Range.all();
+                System.out.println("all: " + ContiguousSet.create(range, DiscreteDomain.integers()).toString());
+        }
+
+        public static void print(String type, Set<Integer> ranges) {
+                System.out.println(type + ":" + ranges + "      list:" + Lists.newArrayList(ranges));
+        }
+}

+ 60 - 0
guavaGoogle/src/test/java/org/example/base/StopwatchTest.java

@@ -0,0 +1,60 @@
+package org.example.base;
+
+import com.google.common.base.Stopwatch;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Stopwatch 测试
+ */
+public class StopwatchTest {
+
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @Test
+    public void test1() throws Exception {
+        String orderNo = "12345678";
+
+        logger.info("订单 [{}] 开始处理", orderNo);
+        Stopwatch stopwatch = Stopwatch.createStarted();
+
+        TimeUnit.SECONDS.sleep(1);  // 1秒处理时间
+
+        logger.info("订单 [{}] 处理完成,耗时 [{}]", orderNo, stopwatch.stop());
+
+    }
+
+    @Test
+    public void test2() throws Exception {
+        // 创建stopwatch并开始计时
+        Stopwatch stopwatch = Stopwatch.createStarted();
+        Thread.sleep(1980);
+
+        // 以秒打印从计时开始至现在的所用时间,向下取整
+        System.out.println(stopwatch.elapsed(TimeUnit.SECONDS)); // 1
+
+        // 停止计时
+        stopwatch.stop();
+        System.out.println(stopwatch.elapsed(TimeUnit.SECONDS)); // 1
+
+        // 再次计时
+        stopwatch.start();
+        Thread.sleep(100);
+        System.out.println(stopwatch.elapsed(TimeUnit.SECONDS)); // 2
+
+        // 重置并开始
+        stopwatch.reset().start();
+        Thread.sleep(1030);
+
+        // 检查是否运行
+        System.out.println(stopwatch.isRunning()); // true
+        long millis = stopwatch.elapsed(TimeUnit.MILLISECONDS); // 1034
+        System.out.println(millis);
+
+        // 打印
+        System.out.println(stopwatch.toString()); // 1.034 s
+    }
+}

+ 65 - 0
guavaGoogle/src/test/java/org/example/base/ThrowablesTests.java

@@ -0,0 +1,65 @@
+package org.example.base;
+
+import com.google.common.base.Throwables;
+import org.junit.Test;
+
+// Throwables
+
+public class ThrowablesTests {
+
+    @Test
+    public void test1() {
+        ThrowablesTests tester = new ThrowablesTests();
+        try {
+            tester.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));
+        }
+    }
+
+    @Test
+    public void test2() {
+        ThrowablesTests tester = new ThrowablesTests();
+        try {
+            tester.showcaseThrowables1();
+        } catch (Exception e) {
+            System.out.println(Throwables.getStackTraceAsString(e));
+        }
+    }
+
+    public void showcaseThrowables() throws InvalidInputException {
+        try {
+            sqrt(-3.0);
+        } catch (Throwable e) {
+            //check the type of exception and throw it
+            Throwables.propagateIfInstanceOf(e, InvalidInputException.class);
+            Throwables.propagate(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];
+    }
+
+    class InvalidInputException extends Exception {
+    }
+}

+ 117 - 0
guavaGoogle/src/test/java/org/example/cache/CacheTest.java

@@ -0,0 +1,117 @@
+package org.example.cache;
+
+import com.google.common.cache.*;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.assertj.core.util.Lists;
+import org.example.cache.CacheEmployee;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.*;
+
+/**
+ * 缓存测试
+ */
+public class CacheTest {
+
+    @Test
+    public void test1() {
+        // 根据员工ID为员工创建缓存
+        // 移除监听器
+        LoadingCache<String, Object> employeeCache = CacheBuilder.newBuilder()
+                .maximumSize(100) // 最多可以缓存100条记录
+                .expireAfterAccess(30, TimeUnit.MINUTES) // 缓存将在访问30分钟后过期
+                .removalListener((RemovalListener<String, Object>) notification -> System.out.println("notification:"+notification))
+                .build(new CacheLoader<String, Object>() {
+
+                    // 通常重写一个 load 方法即可
+                    @Override
+                    public Object load(String key) throws Exception {
+                        // 数据库加载
+                        return getFromDatabase(key);
+                    }
+
+                    @Override
+                    public ListenableFuture<Object> reload(String key, Object oldValue) throws Exception {
+                        return super.reload(key, oldValue);
+                    }
+                });
+
+
+        // 1、单个查询
+        System.out.println("1、单个查询");
+        try {
+            // 在第一次调用时,缓存将填充相应的员工记录
+            System.out.println("调用 #1");
+            System.out.println(employeeCache.get("100"));
+            System.out.println(employeeCache.get("103"));
+            System.out.println(employeeCache.get("110"));
+
+            // 第二次调用时,将从缓存中返回数据
+            System.out.println("\n调用 #2");
+            System.out.println(employeeCache.get("100"));
+            System.out.println(employeeCache.get("103"));
+            System.out.println(employeeCache.get("110"));
+
+        } catch (ExecutionException e) {
+            e.printStackTrace();
+        }
+
+        // 第三次调用时 getUnchecked 不执行检查
+        System.out.println("\n调用 #3");
+        System.out.println(employeeCache.getUnchecked("100"));
+        System.out.println(employeeCache.getUnchecked("103"));
+        System.out.println(employeeCache.getUnchecked("110"));
+
+        // 2、批量查询
+        try {
+            System.out.println("\n2、批量查询");
+            ImmutableMap<String, Object> cacheAll = employeeCache.getAll(Lists.newArrayList("100", "103", "110"));
+            cacheAll.forEach((k, v) -> System.out.println("K:" + k + ",V:" + v));
+
+            // 3、具有回调的查询
+            System.out.println("\n3、具有回调的查询");
+            String key = "001";
+            System.out.println(employeeCache.get(key, new Callable<CacheEmployee>() {
+                @Override
+                public CacheEmployee call() throws Exception {
+                    return getFromDatabase(key);
+                }
+            }));
+
+            // lambda写法
+            System.out.println(employeeCache.get(key, (Callable<CacheEmployee>) () -> getFromDatabase(key)));
+
+            // 4、显示插入 put
+            System.out.println("\n4、显示插入");
+            employeeCache.put("001","听风");
+            System.out.println(employeeCache.get("001"));
+
+            // 5、更改视图
+            ConcurrentMap<String, Object> asMap = employeeCache.asMap();
+            asMap.put("100","程序喵");
+            employeeCache.getAll(Lists.newArrayList("100", "103", "110")).forEach((k, v) -> System.out.println("K:" + k + ",V:" + v));
+
+        } catch (ExecutionException e) {
+            e.printStackTrace();
+        }
+
+        // 6、清除所有缓存
+        System.out.println("\n6、清除所有缓存,调用移除监听器");
+        employeeCache.invalidateAll();
+    }
+
+    private static CacheEmployee getFromDatabase(String empId) {
+        Map<String, CacheEmployee> database = new HashMap();
+        database.put("100", new CacheEmployee("Mahesh", "Finance", "100"));
+        database.put("103", new CacheEmployee("Rohan", "IT", "103"));
+        database.put("110", new CacheEmployee("Sohan", "Admin", "110"));
+
+        database.put("001", new CacheEmployee("Tingfeng", "Admin", "001"));
+        System.out.println("数据库命中" + empId);
+        return database.get(empId);
+    }
+
+}

+ 29 - 0
guavaGoogle/src/test/java/org/example/collections/BimapTest.java

@@ -0,0 +1,29 @@
+package org.example.collections;
+
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import org.junit.Test;
+
+public class BimapTest{
+
+    @Test
+    public void test1(){
+        BiMap<String, String> upperToSmall = HashBiMap.create();
+        upperToSmall.put("A", "a");
+        upperToSmall.put("B", "b");
+        upperToSmall.put("C", "c");
+
+        upperToSmall.forcePut("D","c");
+
+        System.out.println(upperToSmall.get("D"));  // c
+
+        BiMap<String, String> smallToUpper = upperToSmall.inverse();
+        System.out.println(smallToUpper.get("c"));  // D
+
+        smallToUpper.put("E","e");
+
+        System.out.println(upperToSmall);   // {A=a, B=b, D=c, e=E}
+        System.out.println(smallToUpper);   // {a=A, b=B, c=D, E=e}
+    }
+
+}

+ 199 - 0
guavaGoogle/src/test/java/org/example/collections/MapsTest.java

@@ -0,0 +1,199 @@
+package org.example.collections;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.*;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.junit.Test;
+
+import java.util.*;
+
+public class MapsTest {
+
+    /**
+     * newHashMap
+     * newHashMapWithExpectedSize
+     * newLinkedHashMap
+     * 4 种方式遍历
+     */
+    @Test
+    public void test() {
+        Map<Integer, Integer> map0 = Maps.newHashMap();
+        for (int i = 0; i < 10; i++) {
+            map0.put(i, i);
+        }
+        System.out.println("map0:" + map0);     // map0:{0=0, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9}
+
+        Map<Integer, Integer> map1 = Maps.newHashMap(map0);
+        map1.put(10, 10);
+        System.out.println("map1:" + map1);     // map1:{0=0, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9, 10=10}
+
+        Map<Integer, Integer> map2 = Maps.newHashMapWithExpectedSize(3);
+        map2.put(1, 1);
+        map2.put(2, 2);
+        map2.put(3, 3);
+        System.out.println("map2:" + map2);     // map2:{1=1, 2=2, 3=3}
+
+        Map<Integer, Integer> map3 = Maps.newLinkedHashMap(map1);
+        map3.put(11, 11);
+        System.out.println("map3:" + map3);     // map3:{0=0, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9, 10=10, 11=11}
+
+        outMapKeyValue(map3);
+
+    }
+
+    /**
+     * 遍历Map的四种方法
+     */
+    private static void outMapKeyValue(Map<Integer, Integer> map3) {
+        System.out.println("\n1.通过Map.entrySet遍历key和value");
+        for (Map.Entry<Integer, Integer> integerEntry : map3.entrySet()) {
+            System.out.println("key:" + integerEntry.getKey() + " value:" + integerEntry.getValue());
+        }
+
+        System.out.println("\n2.通过Map.entrySet使用iterator遍历key和value");
+        Iterator<Map.Entry<Integer, Integer>> it = map3.entrySet().iterator();
+        while (it.hasNext()) {
+            Map.Entry<Integer, Integer> entry = it.next();
+            System.out.println("key:" + entry.getKey() + " value:" + entry.getValue());
+        }
+
+        System.out.println("\n3.通过Map.keySet遍历key;根据key得到value");
+        for (Integer integer : map3.keySet()) {
+            System.out.println("key:" + integer + " value:" + map3.get(integer));
+        }
+
+        System.out.println("\n4.通过Map.values()遍历所有的value,但不能遍历key");
+        for (Integer integer : map3.values()) {
+            System.out.println("value:" + integer);
+        }
+    }
+
+    /**
+     * difference:返回两个给定map之间的差异。
+     */
+    @Test
+    public void difference() {
+        Map<String, String> map1 = new HashMap<String, String>() {
+            {
+                put("a", "1");
+            }
+        };
+        Map<String, String> map2 = new HashMap<String, String>() {
+            {
+                put("b", "2");
+            }
+        };
+        Map<String, String> map3 = new HashMap<String, String>() {
+            {
+                put("a", "3");
+            }
+        };
+        Map<String, String> map4 = new HashMap<String, String>() {
+            {
+                put("a", "1");
+            }
+        };
+        Map<String, String> map5 = ImmutableMap.of("a", "1");
+
+        System.out.println("\nMaps.difference(map1, map4)");
+        differencePrint(map1, map4);
+
+        System.out.println("\nMaps.difference(map1, map2)");
+        differencePrint(map1, map2);
+
+        System.out.println("\nMaps.difference(map1, map3)");
+        differencePrint(map1, map3);
+
+        System.out.println("\nMaps.difference(map1, map5)");
+        differencePrint(map1, map5);
+    }
+
+    private void differencePrint(Map<String, String> map1, Map<String, String> map4) {
+        MapDifference<String, String> difference = Maps.difference(map1, map4);
+        System.out.println(difference.areEqual());
+        System.out.println(difference.entriesInCommon());
+        System.out.println(difference.entriesOnlyOnRight());
+        System.out.println(difference.entriesOnlyOnLeft());
+        System.out.println(difference.entriesDiffering());
+        System.out.println(difference);
+    }
+
+    /**
+     * transformValues:返回一个map映射,其键值为给定fromMap的键值,其value为给定formMap中value通过Function转换后的值
+     * transformEntries:返回一个map映射, 其Entry为给定fromMap.Entry通过给定EntryTransformer转换后的值
+     */
+    @Test
+    public void transformValues_transformEntries() {
+        Map<String, Boolean> fromMap = Maps.newHashMap();
+        fromMap.put("key", true);
+        fromMap.put("value", false);
+        // 对传入的元素取反
+        System.out.println(Maps.transformValues(fromMap, (Function<Boolean, Object>) input -> !input));        // 输出 {value=true, key=false}
+
+        // value为假,则key变大写
+        Maps.EntryTransformer<String, Boolean, String> entryTransformer = (key, value) -> value ? key : key.toUpperCase();
+        System.out.println(Maps.transformEntries(fromMap, entryTransformer));       // 输出 {value=VALUE, key=key}
+    }
+
+    /**
+     * filterKeys:返回给定unfilteredMap中的键值通过给定keyPredicate过滤后的map映射
+     * filterValues:返回给定unfilteredMap中的value值通过给定keyPredicate过滤后的map映射
+     * filterEntries:返回给定unfilteredMap.Entry中的Entry值通过给定entryPredicate过滤后的map映射
+     */
+    @Test
+    public void filterKeys_filterValues_filterEntries() {
+        Map<String, Boolean> fromMap = ImmutableMap.of("abc", true, "bcd", false, "xyz", true);
+
+        Map<String, Boolean> keysMap = Maps.filterKeys(fromMap, new Predicate<String>() {
+            @Override
+            public boolean apply(@Nullable String input) {
+                // 过滤Map中键值包含字母y的元素
+                return input.contains("y");
+            }
+        });
+        System.out.println(keysMap);      // {xyz=true}
+
+        // 过滤Map中key包含字母b的元素
+        System.out.println(Maps.filterKeys(fromMap, input -> input.contains("b")));              // {abc=true, bcd=false}
+
+        // 过滤Map中value值为假的元素
+        Map<String, Boolean> booleanMap = Maps.filterValues(fromMap, new Predicate<Boolean>() {
+            @Override
+            public boolean apply(@Nullable Boolean input) {
+                return !input;
+            }
+        });
+        System.out.println(booleanMap);        // {bcd=false}
+        System.out.println(Maps.filterValues(fromMap, input -> input));   // {abc=true, xyz=true}
+
+        // 过滤Map.Entry中getValue()为真的元素
+        Map<String, Boolean> filterEntries = Maps.filterEntries(fromMap, new Predicate<Map.Entry<String, Boolean>>() {
+            @Override
+            public boolean apply(Map.@Nullable Entry<String, Boolean> input) {
+                return input.getValue();
+            }
+        });
+        System.out.println(filterEntries);      // {abc=true, xyz=true}
+    }
+
+    /**
+     * asMap 视图
+     * toMap:返回一个不可变的ImmutableMap实例,其键值为给定keys中去除重复值后的值,其值为键被计算了valueFunction后的值
+     * uniqueIndex:返回一个不可变的ImmutableMap实例,其value值为按照给定顺序的给定的values值,键值为相应的值经过给定Function计算后的值
+     */
+    @Test
+    public void testMaps() {
+        Set<String> set = Sets.newHashSet("a", "b", "c");
+        // Function:大写转换
+        Function<String, String> function = input -> input.toUpperCase();
+        System.out.println(Maps.asMap(set, function));          // {b=B, c=C, a=A}
+
+        List<String> keys = Lists.newArrayList("a", "b", "c", "a");
+        System.out.println(Maps.toMap(keys, function));         // {a=A, b=B, c=C}
+
+        List<String> values = Lists.newArrayList("a", "b", "c", "d");
+        System.out.println(Maps.uniqueIndex(values, function));     // {A=a, B=b, C=c, D=d}
+    }
+
+}

+ 107 - 0
guavaGoogle/src/test/java/org/example/collections/MultimapsTest.java

@@ -0,0 +1,107 @@
+package org.example.collections;
+
+import com.google.common.collect.*;
+import org.junit.Test;
+
+public class MultimapsTest {
+
+    @Test
+    public void asMap() {
+        ListMultimap<String, String> listMultimap = LinkedListMultimap.create();
+        listMultimap.put("foo", "A");
+        listMultimap.put("foo", "B");
+        listMultimap.put("foo", "C");
+
+        // 遍历
+        listMultimap.forEach((k, v) -> System.out.println("k:" + k + ", v:" + v));
+
+        System.out.println(listMultimap);
+    }
+
+
+    @Test
+    public void containsOccurrences(){
+        Multiset<String> set1 = HashMultiset.create();
+        set1.add("a", 2);
+        set1.add("b");
+        set1.add("b");
+
+        Multiset<String> set2 = HashMultiset.create();
+        set2.add("a", 5);
+
+        System.out.println(set1.containsAll(set2)); // true
+
+        System.out.println(Multisets.containsOccurrences(set1, set2)); // returns false
+        System.out.println(Multisets.containsOccurrences(set1, set1)); // returns true
+        System.out.println(set2.remove("a",2));    // 5
+        System.out.println(set2.size());            // 3
+        System.out.println(set2.removeAll(set1));   // true
+        System.out.println(set2.size());            // 0
+        System.out.println(set2.isEmpty());         // true
+    }
+
+    @Test
+    public void copyHighestCountFirst(){
+        Multiset<String> multiset = HashMultiset.create();
+        multiset.add("a", 3);
+        multiset.add("b", 5);
+        multiset.add("c", 1);
+        multiset.add("a");
+        multiset.add("a");
+        multiset.add("a");
+
+        System.out.println(multiset.count("a"));        // 6
+        System.out.println(multiset.size());                    // 12
+
+        ImmutableMultiset<String> highestCountFirst = Multisets.copyHighestCountFirst(multiset);
+
+        System.out.println(highestCountFirst.size());           // 12
+        System.out.println(highestCountFirst.entrySet());       // [a x 6, b x 5, c]
+        System.out.println(highestCountFirst.elementSet());     // [a, b, c]
+    }
+
+    @Test
+    public void retainOccurrences(){
+        Multiset<String> set1 = HashMultiset.create();
+        set1.add("a", 2);
+        set1.add("b");
+        set1.add("b");
+
+        Multiset<String> set2 = HashMultiset.create();
+        set2.add("a", 5);
+
+        System.out.println(set1);       // [a x 2, b x 2]
+        System.out.println(set2);       // [a x 5]
+
+        Multisets.retainOccurrences(set1, set2); // 确保set1 每个元素的出现次数<= set2
+
+        System.out.println("\n"+set1);  // [a x 2]
+        System.out.println(set2);       // [a x 5]
+    }
+
+    @Test
+    public void difference_sum_union(){
+        Multiset<String> set1 = HashMultiset.create();
+        set1.add("a", 3);
+        set1.add("b", 2);
+        set1.add("c", 1);
+
+        Multiset<String> set2 = HashMultiset.create();
+        set2.add("a");
+        set2.add("c");
+        set2.add("e");
+
+        // 差集
+        Multiset<String> differenceSet = Multisets.difference(set1, set2);
+        System.out.println(differenceSet);  // [a x 2, b x 2]
+
+        // 合集
+        Multiset<String> sumSet = Multisets.sum(set1, set2);
+        System.out.println(sumSet);         // [a x 4, b x 2, c x 2, e]
+
+        // 并集
+        Multiset<String> unionSet = Multisets.union(set1, set2);
+        System.out.println(unionSet);       // [a x 3, b x 2, c, e]
+    }
+
+}

+ 49 - 0
guavaGoogle/src/test/java/org/example/collections/RangeMapTest.java

@@ -0,0 +1,49 @@
+package org.example.collections;
+
+import com.google.common.collect.Range;
+import com.google.common.collect.RangeMap;
+import com.google.common.collect.TreeRangeMap;
+import org.junit.Test;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+public class RangeMapTest {
+    @Test
+    public void test1(){
+        RangeMap<Integer, String> rangeMap = TreeRangeMap.create();
+        rangeMap.put(Range.closed(1, 10), "aaa");
+        System.out.println(rangeMap);
+
+        rangeMap.put(Range.open(3, 6), "bbb");
+        System.out.println(rangeMap);
+
+        rangeMap.put(Range.openClosed(10, 20), "aaa");
+        System.out.println(rangeMap);
+
+        rangeMap.put(Range.closed(20, 20), "aaa");
+        System.out.println(rangeMap);
+
+        rangeMap.remove(Range.closed(5, 11));
+        System.out.println(rangeMap);
+
+        // 遍历:
+        // 方法1
+        // Map<Range<Integer>, String> rangeStringMap = rangeMap.asDescendingMapOfRanges();  // 倒序
+        Map<Range<Integer>, String> rangeStringMap = rangeMap.asMapOfRanges();
+        rangeStringMap.forEach((k, v) -> System.out.println("Key:" + k + ",Value:" + v));
+
+        // 方法2
+        Map<Range<Integer>, String> rangeStringMap1 = rangeMap.asMapOfRanges();
+        Set<Map.Entry<Range<Integer>, String>> entries = rangeStringMap1.entrySet();
+        Iterator<Map.Entry<Range<Integer>, String>> iterator = entries.iterator();
+        while (iterator.hasNext()) {
+            Map.Entry<Range<Integer>, String> next = iterator.next();
+            System.out.println("Key:" + next.getKey() + ",Value:" + next.getValue());
+        }
+
+        Set<Range<Integer>> rangeSet = rangeMap.asMapOfRanges().keySet();
+        rangeSet.forEach(System.out::println);
+    }
+}

+ 69 - 0
guavaGoogle/src/test/java/org/example/collections/RangeSetTest.java

@@ -0,0 +1,69 @@
+package org.example.collections;
+
+import com.google.common.collect.Range;
+import com.google.common.collect.RangeSet;
+import com.google.common.collect.TreeRangeSet;
+import org.junit.Test;
+
+import java.util.Iterator;
+
+public class RangeSetTest {
+    @Test
+    public void testRangeSet(){
+        RangeSet rangeSet = TreeRangeSet.create();
+        rangeSet.add(Range.closed(1, 10));
+        System.out.println(rangeSet);   // [[1..10]]
+
+        rangeSet.add(Range.closedOpen(11, 15));
+        System.out.println(rangeSet);   // [[1..10], [11..15)]
+
+        rangeSet.add(Range.open(15, 20));
+        System.out.println(rangeSet);   // [[1..10], [11..15), (15..20)]
+
+        rangeSet.add(Range.openClosed(0, 0));
+        System.out.println(rangeSet);   // [[1..10], [11..15), (15..20)]
+
+        rangeSet.remove(Range.open(5, 10));
+        System.out.println(rangeSet);   // [[1..5], [10..10], [11..15), (15..20)]\
+
+        // 遍历:
+        // 方法1
+        // rangeSet.asDescendingSetOfRanges().forEach(System.out::println);  // 倒序
+        Iterator<Range> iterator = rangeSet.asRanges().iterator();
+        while(iterator.hasNext()){
+            Range next = iterator.next();
+            System.out.println(next);
+        }
+
+         // 方法2
+        rangeSet.asRanges().forEach(System.out::println);
+
+        // 互补范围
+        RangeSet complement = rangeSet.complement();
+        System.out.println(complement);
+
+        // 包含
+        boolean isIn = rangeSet.contains(15);
+        System.out.println(isIn);   // false,因为上述范围不包含元素15.
+
+        // 查找范围
+        // 元素是在rangeSet中哪个范围里面
+        Range integerRange = rangeSet.rangeContaining(17);
+        System.out.println(integerRange);   // 输出 `(15..20)`,因为17被包含在 `(15..20)`中 ,所以输出这个范围。
+        // 某个范围是否包含在rangeSet的范围中
+        boolean encloses = rangeSet.encloses(Range.closedOpen(18, 20));
+        System.out.println(encloses);   // true.因为范围(18,20)包含在范围(15,20)中
+        encloses = rangeSet.encloses(Range.closedOpen(5, 20));
+        System.out.println(encloses);   // false 因为范围(5,20)不被rangeSet中任何范围包含.
+
+        RangeSet<Integer> rangeSet1 = TreeRangeSet.create();
+        rangeSet1.add(Range.closed(1, 10));      // {[1,10]}
+        rangeSet1.add(Range.closedOpen(11, 15)); // 不相连区间:{[1,10], [11,15)}
+        rangeSet1.add(Range.closedOpen(15, 20)); // 相连区间; {[1,10], [11,20)}
+        rangeSet1.add(Range.openClosed(0, 0));   // 空区间; {[1,10], [11,20)}
+        rangeSet1.remove(Range.open(5, 10));     // 分割[1, 10]; {[1,5], [10,10], [11,20)}
+
+
+    }
+
+}

+ 137 - 0
guavaGoogle/src/test/java/org/example/collections/TableTest.java

@@ -0,0 +1,137 @@
+package org.example.collections;
+
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.Table;
+import org.junit.Test;
+
+import java.util.Map;
+import java.util.Set;
+
+public class TableTest {
+
+    /**
+     * 双键的 Map --> Table --> rowKey+columnKye+value
+     */
+    @Test
+    public void test1() {
+        Table<Object, Object, Object> table = HashBasedTable.create();
+        table.put("jack", "java", 98);
+        table.put("jack", "php", 65);
+        table.put("jack", "ui", 80);
+        table.put("jack", "mysql", 86);
+
+        // 遍历
+        Set<Table.Cell<Object, Object, Object>> cells = table.cellSet();
+        cells.forEach(c -> System.out.println(c.getRowKey() + "-" + c.getColumnKey() + " : " + c.getValue()));
+
+        /**
+         * 执行结果
+         *
+         * jack-java : 98
+         * jack-php : 65
+         * jack-ui : 80
+         * jack-mysql : 86
+         */
+    }
+
+    @Test
+    public void test2() {
+        //Table<R,C,V> == Map<R,Map<C,V>>
+        /*
+         *  Company: IBM, Microsoft, TCS
+         *  IBM         -> {101:Mahesh, 102:Ramesh, 103:Suresh}
+         *  Microsoft     -> {101:Sohan, 102:Mohan, 103:Rohan }
+         *  TCS         -> {101:Ram, 102: Shyam, 103: Sunil }
+         *
+         * */
+        Table<String, String, String> table = HashBasedTable.create();
+
+        // 使用员工详细信息初始化表
+        table.put("IBM", "101", "Mahesh");
+        table.put("IBM", "102", "Ramesh");
+        table.put("IBM", "103", "Suresh");
+
+        table.put("Microsoft", "111", "Sohan");
+        table.put("Microsoft", "112", "Mohan");
+        table.put("Microsoft", "113", "Rohan");
+
+        table.put("TCS", "121", "Ram");
+        table.put("TCS", "122", "Shyam");
+        table.put("TCS", "123", "Sunil");
+
+        // 获取与IBM对应的Map
+        Map<String, String> ibmMap = table.row("IBM");
+
+        System.out.println("IBM员工名单");
+        for (Map.Entry<String, String> entry : ibmMap.entrySet()) {
+            System.out.println("Emp Id: " + entry.getKey() + ", Name: " + entry.getValue());
+        }
+        System.out.println();
+
+        // 获取表格的所有唯一键
+        Set<String> employers = table.rowKeySet();
+        System.out.print("Employers: ");
+        employers.forEach(e -> System.out.print(e + " "));
+        System.out.println("\n");
+
+        // 得到一个对应102的Map
+        Map<String, String> EmployerMap = table.column("102");
+        for (Map.Entry<String, String> entry : EmployerMap.entrySet()) {
+            System.out.println("Employer: " + entry.getKey() + ", Name: " + entry.getValue());
+        }
+    }
+
+    @Test
+    public void test3() {
+        Table<String, Integer, Integer> table = HashBasedTable.create();
+        table.put("A", 1, 100);
+        table.put("A", 2, 101);
+        table.put("B", 1, 200);
+        table.put("B", 2, 201);
+
+        /**
+         *  contains(Object rowKey, Object columnKey):
+         *  Table中是否存在指定rowKey和columnKey的映射关系
+         */
+        boolean containsA3 = table.contains("A", 3); // false
+        boolean containColumn2 = table.containsColumn(2); // true
+        boolean containsRowA = table.containsRow("A");  // true
+        boolean contains201 = table.containsValue(201);  // true
+
+        /**
+         * remove(Object rowKey, Object columnKey):
+         * 删除Table中指定行列值的映射关系
+         */
+        table.remove("A", 2);
+
+        /**
+         * get(Object rowKey, Object columnKey):
+         * 获取Table中指定行列值的映射关系
+         */
+        table.get("B", 2);
+
+        /**
+         * column(C columnKey):返回指定columnKey下的所有rowKey与value映射
+         */
+        Map<String, Integer> columnMap = table.column(2);
+
+        /**
+         * row(R rowKey):返回指定rowKey下的所有columnKey与value映射
+         */
+        Map<Integer, Integer> rowMap = table.row("B");
+
+        /**
+         * 返回以Table.Cell<R, C, V>为元素的Set集合
+         * 类似于Map.entrySet
+         */
+        Set<Table.Cell<String, Integer, Integer>> cells = table.cellSet();
+        for (Table.Cell<String, Integer, Integer> cell : cells) {
+            //获取cell的行值rowKey
+            cell.getRowKey();
+            //获取cell的列值columnKey
+            cell.getColumnKey();
+            //获取cell的值value
+            cell.getValue();
+        }
+    }
+}

+ 52 - 0
guavaGoogle/src/test/java/org/example/concurrency/AbstractExecutionThreadServiceTest.java

@@ -0,0 +1,52 @@
+package org.example.concurrency;
+
+import com.google.common.util.concurrent.MoreExecutors;
+import com.google.common.util.concurrent.Service;
+import com.google.common.util.concurrent.Uninterruptibles;
+import org.junit.Test;
+
+import java.util.concurrent.TimeUnit;
+
+public class AbstractExecutionThreadServiceTest {
+    @Test
+    public void abstractExecutionThreadServiceTest() {
+        // 定义我们自定义的AbstractExecutionThreadServiceImpl的类对象
+        AbstractExecutionThreadServiceImpl service = new AbstractExecutionThreadServiceImpl();
+        // 添加状态监听
+        service.addListener(new Service.Listener() {
+            @Override
+            public void starting() {
+                System.out.println("服务开始启动");
+            }
+
+            @Override
+            public void running() {
+                System.out.println("服务开始运行");
+            }
+
+            @Override
+            public void stopping(Service.State from) {
+                System.out.println("服务关闭中");
+            }
+
+            @Override
+            public void terminated(Service.State from) {
+                System.out.println("服务终止");
+            }
+
+            @Override
+            public void failed(Service.State from, Throwable failure) {
+                System.out.println("失败,cause:" + failure.getCause());
+            }
+        }, MoreExecutors.directExecutor());
+        // 启动服务
+        service.startAsync().awaitRunning();
+        System.out.println("服务状态为:" + service.state());
+        // 等待30s
+        Uninterruptibles.sleepUninterruptibly(30, TimeUnit.SECONDS);
+        // 停止服务
+        service.stopAsync().awaitTerminated();
+
+        System.out.println("服务状态为:" + service.state());
+    }
+}

+ 53 - 0
guavaGoogle/src/test/java/org/example/concurrency/AbstractScheduledServiceImplTest.java

@@ -0,0 +1,53 @@
+package org.example.concurrency;
+
+import com.google.common.util.concurrent.MoreExecutors;
+import com.google.common.util.concurrent.Service;
+import com.google.common.util.concurrent.Uninterruptibles;
+import org.junit.Test;
+
+import java.util.concurrent.TimeUnit;
+
+public class AbstractScheduledServiceImplTest {
+    @Test
+    public void abstractScheduledServiceImplTest() {
+        // 定义AbstractScheduledServiceImpl对象
+        AbstractScheduledServiceImpl service = new AbstractScheduledServiceImpl();
+        // 添加状态监听器
+        service.addListener(new Service.Listener() {
+            @Override
+            public void starting() {
+                System.out.println("服务开始启动.....");
+            }
+
+            @Override
+            public void running() {
+                System.out.println("服务开始运行");
+            }
+
+            @Override
+            public void stopping(Service.State from) {
+                System.out.println("服务关闭中");
+            }
+
+            @Override
+            public void terminated(Service.State from) {
+                System.out.println("服务终止");
+            }
+
+            @Override
+            public void failed(Service.State from, Throwable failure) {
+                System.out.println("失败,cause:" + failure.getCause());
+            }
+        }, MoreExecutors.directExecutor());
+        // 启动任务
+        service.startAsync().awaitRunning();
+        System.out.println("服务状态为:" + service.state());
+
+        // 等待30s
+        Uninterruptibles.sleepUninterruptibly(30, TimeUnit.SECONDS);
+
+        // 关闭任务
+        service.stopAsync().awaitTerminated();
+        System.out.println("服务状态为:" + service.state());
+    }
+}

+ 62 - 0
guavaGoogle/src/test/java/org/example/concurrency/ListenableFutureGuava.java

@@ -0,0 +1,62 @@
+package org.example.concurrency;
+
+import com.google.common.util.concurrent.*;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+public class ListenableFutureGuava {
+
+    public static void main(String[] args) {
+
+        ListeningExecutorService service = MoreExecutors.listeningDecorator(
+                Executors.newFixedThreadPool(10));
+
+
+        final ListenableFuture<AResult> listenableFuture = service.submit(() -> {
+            try {
+                TimeUnit.SECONDS.sleep(5);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+            return new AResult(30, "male", 1);
+
+        });
+
+
+        Futures.addCallback(listenableFuture,
+                new FutureCallback<AResult>() {
+                    @Override
+                    public void onSuccess(AResult aResult) {
+                        log.info("计算成功,{}",aResult);
+//                        service.shutdown();
+                    }
+
+                    @Override
+                    public void onFailure(Throwable throwable) {
+
+                        log.error("计算错误",throwable);
+
+                    }
+                },service);
+
+    }
+
+    @Data
+    @AllArgsConstructor
+    public static class AResult{
+
+        private Integer age;
+
+        private String sex;
+
+        private Integer id;
+
+
+    }
+
+}

+ 54 - 0
guavaGoogle/src/test/java/org/example/concurrency/ServiceManagerTest.java

@@ -0,0 +1,54 @@
+package org.example.concurrency;
+
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Service;
+import com.google.common.util.concurrent.ServiceManager;
+import com.google.common.util.concurrent.Uninterruptibles;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+
+public class ServiceManagerTest {
+    @Test
+    public void serviceManagerTest() {
+        // 定义两个服务
+        AbstractExecutionThreadServiceImpl service0 = new AbstractExecutionThreadServiceImpl();
+        AbstractScheduledServiceImpl service1 = new AbstractScheduledServiceImpl();
+        List<Service> serviceList = Lists.newArrayList(service0, service1);
+        // ServiceManager里面管理这两个服务
+        ServiceManager serviceManager = new ServiceManager(serviceList);
+        // 添加监听
+        serviceManager.addListener(new ServiceManager.Listener() {
+            @Override
+            public void healthy() {
+                super.healthy();
+                System.out.println("healthy");
+            }
+
+            @Override
+            public void stopped() {
+                super.stopped();
+                System.out.println("stopped");
+            }
+
+            @Override
+            public void failure(Service service) {
+                super.failure(service);
+                System.out.println("failure");
+            }
+        }, new Executor() {
+            @Override
+            public void execute(Runnable command) {
+                System.out.println(1);
+            }
+        });
+        // 启动服务,等待所有的服务都达到running状态
+        serviceManager.startAsync().awaitHealthy();
+        // 等待30s
+        Uninterruptibles.sleepUninterruptibly(30, TimeUnit.SECONDS);
+        // 停止服务
+//        serviceManager.stopAsync().awaitStopped();
+    }
+}

+ 20 - 0
guavaGoogle/src/test/java/org/example/eventBus/EventBusTest.java

@@ -0,0 +1,20 @@
+package org.example.eventBus;
+
+import com.google.common.eventbus.EventBus;
+import org.junit.Test;
+
+public class EventBusTest {
+    @Test
+    public void eventBus() {
+        // 定义一个EventBus对象,因为我这里是测试,才这样写的。实际你应该定义一个单例获取其他的方式
+        EventBus eventBus = new EventBus("test");
+        // 注册监听者
+        eventBus.register(new OrderEventListener());
+        OrderMessage orderMessage = new OrderMessage();
+        orderMessage.setOrderContent("Guava!!!");
+        // 发布消息
+        eventBus.post(orderMessage);
+
+    }
+
+}

+ 82 - 0
guavaGoogle/src/test/java/org/example/functional/FunctionsPredicatesTest.java

@@ -0,0 +1,82 @@
+package org.example.functional;
+
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class FunctionsPredicatesTest {
+    @Test
+    public void test1() {
+        Map<String, Long> stringLong = new HashMap<String, Long>();
+        stringLong.put("key1", 1L);
+        stringLong.put("key2", 2L);
+        //将Map实例转换为Function实例
+        Function<String, Long> stringLongFunction = Functions.forMap(stringLong, 0L);
+        // 1
+        System.out.println(stringLongFunction.apply("key1"));
+        /* 第一个Function是定义转换规则,对第二个Function的value进行处理,
+         * 下面栗子里,用新建的Function对stringLongFunction的value进行处理,规则就是重写的apply()方法
+         */
+        Function<String, String> compose = Functions.compose(new Function<Long, String>() {
+            @Override
+            public String apply(Long input) {
+                return input * input + "";
+            }
+        }, stringLongFunction);
+        Function<String, String> compose1 = Functions.compose(new Function<String, String>() {
+            @Override
+            public String apply(String input) {
+                return input + input;
+            }
+        }, compose);
+        // 44 = "2*2" + "2*2" 注意这个是对上面compose进行的处理
+        System.out.println(compose1.apply("key2"));
+    }
+
+
+    @Test
+    public void test3() {
+        Map<String, Long> stringLong = new HashMap<String, Long>();
+        stringLong.put("key1", 1L);
+        stringLong.put("key3", 3L);
+        Function<String, Long> stringLongFunction = Functions.forMap(stringLong, 0L);
+        //true,false
+        System.out.println(Predicates.alwaysTrue().apply(1));
+        System.out.println(Predicates.isNull().apply(1));
+
+        //多个组合
+        Predicate<Object> or = Predicates.or(Predicates.isNull(), Predicates.notNull());
+        //true,true
+        System.out.println(or.apply(null));
+        System.out.println(or.apply("1"));
+        Predicate<Long> and = Predicates.and(new Predicate<Long>() {
+            @Override
+            public boolean apply(Long input) {
+                return input < 5;
+            }
+        }, new Predicate<Long>() {
+            @Override
+            public boolean apply(Long input) {
+                return input > 2;
+            }
+        });
+        Predicate<String> compose = Predicates.compose(and, stringLongFunction);
+        System.out.println("--------Predicate----------");
+        //false,true
+        System.out.println(compose.apply("key1"));
+        System.out.println(compose.apply("key3"));
+
+        //转换为Function
+        Function<Long, Boolean> longBoolean = Functions.forPredicate(and);
+        System.out.println("--------Predicate-Function---------");
+        //true,false
+        System.out.println(longBoolean.apply(3L));
+        System.out.println(longBoolean.apply(6L));
+
+    }
+}

+ 101 - 0
guavaGoogle/src/test/java/org/example/hashing/HashingTest.java

@@ -0,0 +1,101 @@
+package org.example.hashing;
+
+import com.google.common.base.Charsets;
+import com.google.common.hash.*;
+import org.example.hasing.Male;
+import org.example.hasing.Person;
+import org.junit.Test;
+
+public class HashingTest {
+
+    @Test
+    public void test() {
+        String input = "hello, world";
+        // 计算MD5
+        System.out.println(Hashing.md5().hashBytes(input.getBytes()).toString());
+        System.out.println(Hashing.md5().hashUnencodedChars(input).toString());
+
+        System.out.println(Hashing.farmHashFingerprint64().hashBytes(input.getBytes()));
+        System.out.println(Hashing.farmHashFingerprint64().hashUnencodedChars(input).toString());
+
+        // 计算sha256
+        System.out.println(Hashing.sha256().hashBytes(input.getBytes()).toString());
+        System.out.println(Hashing.sha256().hashUnencodedChars(input).toString());
+
+        // 计算sha512
+        System.out.println(Hashing.sha512().hashBytes(input.getBytes()).toString());
+        System.out.println(Hashing.sha512().hashUnencodedChars(input).toString());
+
+        // 计算crc32
+        System.out.println(Hashing.crc32().hashBytes(input.getBytes()).toString());
+        System.out.println(Hashing.crc32().hashUnencodedChars(input).toString());
+
+        // 计算adler32
+        System.out.println(Hashing.adler32().hashBytes(input.getBytes()).toString());
+        System.out.println(Hashing.adler32().hashUnencodedChars(input).toString());
+
+        // 计算crc32c
+        System.out.println(Hashing.crc32c().hashBytes(input.getBytes()).toString());
+        System.out.println(Hashing.crc32c().hashUnencodedChars(input).toString());
+
+        // 计算murmur3_32
+        System.out.println(Hashing.murmur3_32().hashBytes(input.getBytes()).toString());
+        System.out.println(Hashing.murmur3_32().hashUnencodedChars(input).toString());
+
+        // 计算murmur3_128
+        System.out.println(Hashing.murmur3_128().hashBytes(input.getBytes()).toString());
+        System.out.println(Hashing.murmur3_128().hashUnencodedChars(input).toString());
+
+        // 计算sha384
+        System.out.println(Hashing.sha384().hashBytes(input.getBytes()).toString());
+        System.out.println(Hashing.sha384().hashUnencodedChars(input).toString());
+
+        // 计算sipHash24
+        System.out.println(Hashing.sipHash24().hashBytes(input.getBytes()).toString());
+        System.out.println(Hashing.sipHash24().hashUnencodedChars(input).toString());
+    }
+
+    @Test
+    public void test2() {
+//        HashFunction function_0 = Hashing.md5();
+//        HashFunction function_1 = Hashing.md5();
+        HashFunction function_0 = Hashing.murmur3_128();
+        HashFunction function_1 = Hashing.murmur3_128();
+
+        Person person = new Person();
+        person.setAge(27);
+        person.setName("hahahah");
+        person.setAddress("北京三里屯");
+        person.setPhoneNumber(16666666666L);
+        person.setMale(Male.man);
+
+        HashCode code_0 = function_0.newHasher()
+                .putInt(person.getAge())
+                .putString(person.getName(), Charsets.UTF_8)
+                .putString(person.getAddress(), Charsets.UTF_8)
+                .putLong(person.getPhoneNumber())
+                .putObject(person.getMale(), new Funnel<Male>() {
+                    @Override
+                    public void funnel(Male from, PrimitiveSink into) {
+                        into.putString(from.name(), Charsets.UTF_8);
+                    }
+                }).hash();
+
+        HashCode code_1 = function_1.newHasher()
+                .putInt(person.getAge())
+                .putString(person.getName(), Charsets.UTF_8)
+                .putString(person.getAddress(), Charsets.UTF_8)
+                .putLong(person.getPhoneNumber())
+                .putObject(person.getMale(), new Funnel<Male>() {
+                    @Override
+                    public void funnel(Male from, PrimitiveSink into) {
+                        into.putString(from.name(), Charsets.UTF_8);
+                    }
+                }).hash();
+
+        System.out.println(code_0.asLong());
+        System.out.println(code_1.asLong());
+
+        System.out.println(code_0.equals(code_1));
+    }
+}

+ 286 - 0
guavaGoogle/src/test/java/org/example/primitives/IntsTest.java

@@ -0,0 +1,286 @@
+package org.example.primitives;
+
+import com.google.common.base.Converter;
+import com.google.common.collect.Lists;
+import com.google.common.primitives.Ints;
+import org.assertj.core.api.Assertions;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class IntsTest {
+
+    /**
+     * asList 基本类型数组转化为包装类List
+     */
+    @Test
+    public void asList() {
+        int[] intArray = {1, 2, 3, 4, 5};
+
+        List<Integer> result = Ints.asList(intArray);
+        System.out.println(result);     // [1, 2, 3, 4, 5]
+
+        result = Ints.asList(3, 5, 2, 10, 8, 6);
+        System.out.println(result);     // [3, 5, 2, 10, 8, 6]
+    }
+
+    /**
+     * checkedCast long转int,如果long值超出int范围抛IllegalArgumentException
+     */
+    @Test
+    public void checkedCastTest() {
+        long input = 9998L;
+        int result = Ints.checkedCast(input);
+        System.out.println(result);     // 9998
+
+        long input1 = 2147483648L;
+//        long input1 = 2147483648123L;
+        System.out.println(Assertions.assertThatThrownBy(() -> Ints.checkedCast(input1)).isInstanceOf(IllegalArgumentException.class)
+                .hasMessage("Out of range: 2147483648").hasNoCause());
+    }
+
+    /**
+     * compare 比较两个int值的大小
+     */
+    @Test
+    public void compareTest() {
+        assertEquals(-1, Ints.compare(1, 2));
+        assertEquals(0, Ints.compare(1, 1));
+        assertEquals(1, Ints.compare(2, 1));
+    }
+
+    /**
+     * concat 将多个int数组拼接成一个数组
+     */
+    @Test
+    public void concatTest() {
+        int[] array1 = {1, 2, 3};
+        int[] array2 = {4, 5, 6};
+        int[] array3 = {7, 8};
+        int[] result = Ints.concat(array1, array2, array3);
+        System.out.println(result.length);  // 8
+    }
+
+    /**
+     * constrainToRange 如果一个数字在某个范围内则输出该数字,否则输出范围的最大值或最小值
+     */
+    @Test
+    public void constrainToRangeTest() {
+        int result = Ints.constrainToRange(5, 0, 9);
+        System.out.println(result);     // 5
+        System.out.println(Ints.constrainToRange(10, 0, 9));    // 9
+        System.out.println(Ints.constrainToRange(-1, 0, 9));    // 0
+    }
+
+    /**
+     * contains 判断一个int数是否在int数组内
+     */
+    @Test
+    public void containsTest() {
+        int[] array = {1, 2, 3, 4};
+        System.out.println(Ints.contains(array, 3));    // true
+    }
+
+    /**
+     * ensureCapacity 确保数组拥有一个最小的长度
+     */
+    @Test
+    public void ensureCapacityTest() {
+        int[] array = {1, 2, 3, 4};
+        int[] result = Ints.ensureCapacity(array, 6, 3);
+        System.out.println(result.length);              // 9
+        System.out.println(Arrays.toString(result));    // [1, 2, 3, 4, 0, 0, 0, 0, 0]
+
+        result = Ints.ensureCapacity(array, 3, 3);
+        System.out.println(result.length);              // 4
+        System.out.println(Arrays.toString(result));    // [1, 2, 3, 4]
+    }
+
+    /**
+     * fromByteArray 通过byte数组前四个元素转int值
+     * 使用字节数组的前 Prims.BYTES 个字节,按大字节序返回原生类型值;如果 bytes.length <= Prims.BYTES,抛出IAE
+     */
+    @Test
+    public void fromByteArrayTest() {
+        byte[] byteArray = {1, 1, 1, 1};
+        int result = Ints.fromByteArray(byteArray);
+        System.out.println(result);     // 16843009
+    }
+
+    /**
+     * fromBytes 通过四个byte元素转int值
+     *
+     * 接受 Prims.BYTES 个字节参数,按大字节序返回原生类型值
+     */
+    @Test
+    public void fromBytesTest() {
+        int result = Ints.fromBytes((byte) 1, (byte) 1, (byte) 1, (byte) 1);
+        System.out.println(result);     // 16843009
+    }
+
+    /**
+     * hashCode 返回int值的hashCode(元素值)
+     */
+    @Test
+    public void hashCodeTest() {
+        int hashCode = Ints.hashCode(1);
+        System.out.println(hashCode);      // 1
+    }
+
+    /**
+     * indexOf 返回一个int值在数组中的第一个index,没匹配到返回-1
+     */
+    @Test
+    public void indexOfTest() {
+        int[] array = {1, 2, 3, 4, 3};
+        System.out.println(Ints.indexOf(array, 3)); // 2
+        System.out.println(Ints.indexOf(array, 5)); // -1
+    }
+
+    /**
+     * arrayIndexOf 返回int数组在另一个数组中的第一个index,没匹配到返回-1
+     */
+    @Test
+    public void arrayIndexOf() {
+        int[] array = {1, 2, 3, 4, 6, 5, 8};
+        int[] target = {6, 5};
+        System.out.println(Ints.indexOf(array, target));    // 4
+    }
+
+    /**
+     * join 通过连接符连接数组转成String
+     */
+    @Test
+    public void joinTest() {
+        String str = "-";
+        System.out.println(Ints.join(str, 1, 2, 3));    // 1-2-3
+    }
+
+    /**
+     * lastIndexOf 返回一个int值在数组中的最后一个index,没匹配到返回-1
+     */
+    @Test
+    public void lastIndexOfTest() {
+        int[] array = {1, 2, 3, 4, 3};
+        System.out.println(Ints.lastIndexOf(array, 3));     // 4
+        System.out.println(Ints.lastIndexOf(array, 5));     // -1
+    }
+
+    /**
+     * lexicographicalComparator
+     * 返回一个int[]比较器,比较规则是从index0开始比较两个数组对应index上的元素大小,返回比较结果,到其中一个数组结束都完全一致,则通过长度比较,长度大的那个数组大
+     * 比对方大的元素数量相同时,也就是第一个不必第二个大所以同样返回-1
+     */
+    @Test
+    public void lexicographicalComparatorTest() {
+        Comparator<int[]> comparator = Ints.lexicographicalComparator();
+        int[] array1 = {1, 2, 3};
+        int[] array2 = {1, 3, 3};
+        int result = comparator.compare(array1, array2);
+        System.out.println(result);     // -1
+    }
+
+    /**
+     * max 返回一个数组的最大元素
+     * min 返回一个数组的最小元素
+     */
+    @Test
+    public void maxMinTest() {
+        int[] array = {1, 16, 3, 5, 3};
+        System.out.println(Ints.max(array));    // 16
+        System.out.println(Ints.min(array));    // 1
+    }
+
+    /**
+     * reverse 将数组反转
+     */
+    @Test
+    public void reverseTest() {
+        int[] array = {1, 16, 3, 5, 3};
+        Ints.reverse(array);
+        System.out.println(Ints.asList(array));    //  [3, 5, 3, 16, 1]
+
+        /* 将数组指定范围的元素反转(范围左闭右开) */
+        int[] array1 = {1, 16, 8, 5, 3};
+        Ints.reverse(array1, 0, 3);
+        System.out.println( Ints.asList(array1));   // [8, 16, 1, 5, 3]
+    }
+
+    /**
+     * saturatedCast 将long转化为int,超出int范围转化为2147483647
+     */
+    @Test
+    public void saturatedCastTest() {
+        long input = 9998L;
+        int result = Ints.saturatedCast(input);
+        System.out.println(result);     // 9998
+
+        input = 2147483648L;
+        result = Ints.saturatedCast(input);
+        System.out.println(result);     // 2147483647
+    }
+
+    /**
+     * sortDescending 数组按逆序排序
+     */
+    @Test
+    public void sortDescendingTest() {
+        int[] array = {1, 16, 8, 5, 3};
+        Ints.sortDescending(array);
+        System.out.println(Ints.asList(array));         // [16, 8, 5, 3, 1]
+
+        /*将一定范围内的数组按照逆序排序(范围左闭右开)*/
+        int[] array1 = {1, 16, 8, 5, 3};
+        Ints.sortDescending(array1, 0, 3);
+        System.out.println(Ints.asList(array1));        // [16, 8, 1, 5, 3]
+    }
+
+    /**
+     * stringConverter 返回String与Integer的转换器
+     */
+    @Test
+    public void stringConverterTest() {
+        Converter<String, Integer> converter = Ints.stringConverter();
+        int num = converter.convert("123");
+        System.out.println(num);        // 123
+    }
+
+    /**
+     * toArray List转数组
+     */
+    @Test
+    public void toArrayTest() {
+        List<Integer> list = Lists.newArrayList(1, 2, 3, 4);
+        int[] arr = Ints.toArray(list);
+        System.out.println(Arrays.toString(arr));   // [1, 2, 3, 4]
+    }
+
+    /**
+     * toByteArray int值转byte数组
+     */
+    @Test
+    public void toByteArrayTest() {
+        byte[] byteArray = Ints.toByteArray(1);
+        System.out.println(Arrays.toString(byteArray));     // [0, 0, 0, 1]
+    }
+
+    /**
+     * tryParse 十进制String转Integer, 如果String值存在非法字符,转为null
+     */
+    @Test
+    public void tryParseTest() {
+        Integer result = Ints.tryParse("1234");
+        System.out.println(result.intValue());                 // 1234
+        System.out.println(Ints.tryParse("1234ahd"));   // null
+
+        /* radix进制String转Integer, 如果String值存在非法字符,转为null */
+        Integer result1 = Ints.tryParse("0110", 2);
+        System.out.println(result1.intValue());                // 6
+        System.out.println(Ints.tryParse("0110ahd"));   // null
+    }
+
+}

+ 26 - 0
guavaGoogle/src/test/java/org/example/reflection/GuavaReflectionExample.java

@@ -0,0 +1,26 @@
+package org.example.reflection;
+
+import com.google.common.reflect.Reflection;
+
+import java.lang.reflect.Field;
+
+public class GuavaReflectionExample {
+    private int myField;
+
+    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
+        GuavaReflectionExample example = new GuavaReflectionExample();
+        Field field = GuavaReflectionExample.class.getDeclaredField("myField");
+
+        Reflection.initialize(example.getClass());
+
+        // Make the field accessible if it's private or protected
+        field.setAccessible(true);
+
+        // Set the field value
+        field.set(example, 42);
+
+        System.out.println(example.myField); // prints 42
+
+        System.out.println(Reflection.getPackageName(GuavaReflectionExample.class));
+    }
+}

+ 26 - 0
guavaGoogle/src/test/java/org/example/string/CaseFormatTest.java

@@ -0,0 +1,26 @@
+package org.example.string;
+
+import com.google.common.base.CaseFormat;
+import com.google.common.base.Converter;
+import junit.framework.TestCase;
+
+public class CaseFormatTest extends TestCase {
+
+    /**
+     * converterTo 格式器转化为targetFormat格式
+     */
+    public void testConverterTo() {
+        Converter<String, String> camelConverter = CaseFormat.LOWER_CAMEL.converterTo(CaseFormat.UPPER_UNDERSCORE);
+        System.out.println(camelConverter.convert("input_camel"));  // INPUT_CAMEL
+    }
+
+    /**
+     * to 转换指定类型字符串
+     */
+    public void testTo() {
+        String input = "ting-feng";
+        System.out.println(CaseFormat.LOWER_HYPHEN.to(CaseFormat.LOWER_CAMEL, input));      // tingFeng
+        System.out.println(CaseFormat.LOWER_HYPHEN.to(CaseFormat.LOWER_UNDERSCORE, input)); // ting_feng
+        System.out.println(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, input));      // TingFeng
+    }
+}

+ 207 - 0
guavaGoogle/src/test/java/org/example/string/CharMatcherTest.java

@@ -0,0 +1,207 @@
+package org.example.string;
+
+import com.google.common.base.CharMatcher;
+import junit.framework.TestCase;
+
+public class CharMatcherTest extends TestCase {
+
+    /**
+     * collapseFrom 配到的字符做替换
+     */
+    public void testCollapseFrom() {
+        String input = "     Ting Feng        ";
+        String result = CharMatcher.breakingWhitespace().collapseFrom(input, '*');
+        System.out.println(result);     // *Ting*Feng*
+
+        result = CharMatcher.is(' ').collapseFrom(input, '-');
+        System.out.println(result);     // -Ting-Feng-
+    }
+
+    /**
+     * trimAndCollapseFrom 去掉两边空格,然后执行 collapseFrom 操作
+     */
+    public void testTrimAndCollapseFrom() {
+        String input = "     Ting Feng     ";
+        String result = CharMatcher.breakingWhitespace().trimAndCollapseFrom(input, '-');
+        System.out.println(result);     // Ting-Feng
+
+        result = CharMatcher.is(' ').trimAndCollapseFrom(input, '-');
+        System.out.println(result);     // Ting-Feng
+    }
+
+    /**
+     * trimFrom 去空格
+     * trimLeadingFrom 左边去空格
+     * trimTrailingFrom右边去空格
+     */
+    public void testTrim() {
+        System.out.println(CharMatcher.breakingWhitespace().trimFrom("     Ting Feng     "));           // Ting Feng
+        System.out.println(CharMatcher.breakingWhitespace().trimLeadingFrom("     Ting Feng     "));    // Ting Feng
+        System.out.println(CharMatcher.breakingWhitespace().trimTrailingFrom("     Ting Feng     "));   //      Ting Feng
+    }
+
+    /**
+     * retainFrom 保留匹配到的字符
+     */
+    public void testRetainFrom() {
+        System.out.println(CharMatcher.breakingWhitespace().retainFrom("   Hi 123 Ting 456 Feng  "));   // "         " 空格
+    }
+
+    /**
+     * removeFrom 删除所有匹配的字符
+     */
+    public void testRemoveFrom() {
+        System.out.println(CharMatcher.breakingWhitespace().removeFrom("   Hi 123 Ting 456 Feng  "));   // Hi123Ting456Feng
+    }
+
+    /**
+     * countIn 查找字符在字符串中的个数
+     */
+    public void testCountIn() {
+        System.out.println(CharMatcher.is('a').countIn("TingFeng Sharing the Google Guava Used"));  // 3
+
+        String input = "H*el.lo,}12";
+        CharMatcher matcher = CharMatcher.forPredicate(Character::isLetterOrDigit);
+        System.out.println(matcher.retainFrom(input));  // Hello12
+        System.out.println(matcher.countIn(input));     // 7
+
+        matcher = CharMatcher.inRange('a', 'l');
+        System.out.println(matcher.countIn(input));     // 3
+    }
+
+    /**
+     * indexIn 匹配到的第一个字符的index
+     * lastIndexIn 匹配到的最后一个字符的index
+     */
+    public void testIndexIn_lastIndexIn() {
+        String input = "**el.lo,}12";
+        CharMatcher matcher = CharMatcher.forPredicate(Character::isLetterOrDigit);
+        System.out.println(matcher.indexIn(input));             // 2
+        System.out.println(matcher.indexIn(input, 4));    // 5
+
+        System.out.println(matcher.lastIndexIn(input));         // 10
+    }
+
+    /**
+     * is 匹配参数之内的所有字符
+     * isNot 匹配参数之外的所有字符
+     */
+    public void testIs_isNot(){
+        String input = "a, c, z, 1, 2";
+        System.out.println(CharMatcher.is(',').retainFrom(input));   // ,,,,
+        System.out.println(CharMatcher.is(',').removeFrom(input));   // a c z 1 2
+
+        System.out.println(CharMatcher.isNot(',').retainFrom(input));   // a c z 1 2
+        System.out.println(CharMatcher.isNot(',').removeFrom(input));   // ,,,,
+    }
+
+    /**
+     * 匹配java转义字符
+     */
+    public void testJavaIsoControl(){
+        String input = "ab\tcd\nef\bg";
+        CharMatcher matcher = CharMatcher.javaIsoControl();
+        System.out.println(matcher.removeFrom(input));  // abcdefg
+    }
+
+    /**
+     * 两个 Matcher 同时匹配
+     */
+    public void testDoubleMatcher() {
+        CharMatcher matcher0 = CharMatcher.forPredicate(Character::isLetterOrDigit);
+        CharMatcher matcher1 = CharMatcher.forPredicate(Character::isLowerCase);
+
+        String result = matcher0.and(matcher1).retainFrom("H*el.lo,}12");
+        System.out.println(result); // ello
+    }
+
+    /**
+     * matchesAllOf 判断sequence所有字符是否都被charMatcher匹配
+     * matchesAnyOf 判断sequence中是否存在字符被charMatcher匹配
+     * matchesNoneOf 判断sequence所有字符是否都没被charMatcher匹配
+     */
+    public void test_matchesAllOf_matchesAnyOf_matchesNoneOf(){
+        String input = "**e,l.lo,}12";
+
+        CharMatcher matcher = CharMatcher.is(',');
+        System.out.println(matcher.matchesAllOf(input));    // false
+
+        matcher = CharMatcher.is(',');
+        System.out.println(matcher.matchesAnyOf(input));    // true
+
+        matcher = CharMatcher.is('?');
+        System.out.println(matcher.matchesNoneOf(input));   // true
+    }
+
+    /**
+     * 匹配任意字符
+     */
+    public void testAny() {
+        String input = "H*el.lo,}12";
+
+        CharMatcher matcher = CharMatcher.any();
+        String result = matcher.retainFrom(input);
+        System.out.println(result); //  H*el.lo,}12
+
+        matcher = CharMatcher.anyOf("Hel");
+        System.out.println(matcher.retainFrom(input)); // Hell
+        System.out.println(matcher.removeFrom(input)); // *.o,}12
+    }
+
+    /**
+     * 匹配 Ascii
+     */
+    public void testAscii() {
+        String input = "あH*el.lo,}12";
+
+        CharMatcher matcher = CharMatcher.ascii();
+        System.out.println(matcher.retainFrom(input));  // H*el.lo,}12
+        System.out.println(matcher.removeFrom(input));  // あ
+    }
+
+    /**
+     * negate 返回与当前CharMatcher相反的CharMatcher
+     */
+    public void testNegate(){
+        String input = "あH*el.lo,}12";
+
+        CharMatcher matcher = CharMatcher.ascii().negate();
+        System.out.println(matcher.retainFrom(input));     //  あ
+        System.out.println(matcher.removeFrom(input));     //  H*el.lo,}12
+    }
+
+    /**
+     * none 不匹配任何字符,与any()相反
+     * noneOf 不匹配CharSequence内的任意一个字符,与anyOf()相反
+     */
+    public void testNone_noneOf(){
+        String input = "H*el.lo,}12";
+        CharMatcher matcher = CharMatcher.none();
+        System.out.println(matcher.retainFrom(input));          // ""
+        System.out.println(matcher.retainFrom(input).length()); // 0
+
+        matcher = CharMatcher.noneOf("Hel");
+        System.out.println(matcher.retainFrom(input));          // *.o,}12
+        System.out.println(matcher.removeFrom(input));          // Hell
+    }
+
+    /**
+     * forPredicate 初始化匹配器
+     */
+    public void testForPredicate() {
+//        CharMatcher charMatcher = CharMatcher.forPredicate(new Predicate<Character>() {
+//            @Override
+//            public boolean apply(@Nullable Character input) {
+//                return Character.isLetterOrDigit(input);
+//            }
+//        });
+
+        // lambda 写法
+        CharMatcher charMatcher = CharMatcher.forPredicate(input -> Character.isLetterOrDigit(input));
+
+        String input = "H*el.lo,}12";
+        System.out.println(charMatcher.retainFrom(input));  // Hello12
+
+    }
+
+}

+ 89 - 0
guavaGoogle/src/test/java/org/example/string/JoinTest.java

@@ -0,0 +1,89 @@
+package org.example.string;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableMap;
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class JoinTest extends TestCase {
+
+    private final List<String> list = Arrays.asList("java", "php", "c#");
+    private final List<String> listWithNull = Arrays.asList("java", "php", "c#", null);
+
+    public void testJoin1() {
+        String join = Joiner.on(":").join(list);
+        System.out.println(join);   // java:php:c#
+    }
+
+    /**
+     * null对象测试
+     */
+    public void testJoin2() {
+        try {
+            String join = Joiner.on(":").join(listWithNull);
+            System.out.println(join);
+        }catch (NullPointerException e){
+            System.out.println("Empty la");
+        }
+    }
+
+    /**
+     * null对象跳过
+     */
+    public void testJoin3() {
+        String join = Joiner.on(":").skipNulls().join(listWithNull);
+        System.out.println(join);   // java:php:c#
+    }
+
+    /**
+     * null对象使用默认值
+     */
+    public void testJoin4() {
+        String join = Joiner.on(":").useForNull("默认值").join(listWithNull);
+        System.out.println(join);   // java:php:c#:默认值
+    }
+
+    /**
+     * appendTo 拼接
+     */
+    public void testJoin5() {
+        StringBuilder builder = new StringBuilder("Hello World");
+        StringBuilder appendResult = Joiner.on(":").useForNull("默认值").appendTo(builder, listWithNull);
+        System.out.println(appendResult);   // Hello Worldjava:php:c#:默认值
+    }
+
+    /**
+     * appendTo 文件
+     *
+     * 将结果输出到文件中
+     */
+    public void testJoin6() {
+        try (FileWriter writer = new FileWriter(new File("./temp.txt"))) {
+            FileWriter fileWriter = Joiner.on(":").useForNull("默认值").appendTo(writer, listWithNull);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * MapJoiner 的使用,将 map 转换为字符串
+     */
+    public void testJoin7() {
+        ImmutableMap<String, String> map = ImmutableMap.of("hello", "java", "hi", "python");
+        String result = Joiner.on(";").withKeyValueSeparator("=").join(map);
+        System.out.println(result); // hello=java;hi=python
+    }
+
+    /**
+     * java8 测试 joining
+     */
+    public void testJoin8() {
+        String collect = listWithNull.stream().filter(s -> s != null && !s.isEmpty()).collect(Collectors.joining(":"));
+        System.out.println(collect);    // java:php:c#
+    }
+}

+ 97 - 0
guavaGoogle/src/test/java/org/example/string/SplitterTest.java

@@ -0,0 +1,97 @@
+package org.example.string;
+
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+import junit.framework.TestCase;
+
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * Splitter 测试
+ */
+public class SplitterTest extends TestCase {
+
+    public void test1() {
+        List<String> list = Splitter.on("!").splitToList("hello!world");
+        System.out.println(list);   // [hello, world]
+    }
+
+    /**
+     * 过滤空
+     */
+    public void test2() {
+        List<String> list = Splitter.on("!").omitEmptyStrings().splitToList("hello ! world!!!!!!");
+        System.out.println(list.size());    // 2
+        System.out.println(list);           // [hello ,  world]
+    }
+
+    /**
+     * 去空格,过滤空
+     */
+    public void test3() {
+        List<String> list = Splitter.on("!").trimResults().omitEmptyStrings().splitToList("hello ! world!  !!!!!");
+        System.out.println(list.size());    // 2
+        System.out.println(list);           // [hello ,  world]
+    }
+
+    /**
+     * 分割限制
+     */
+    public void test4() {
+        List<String> list = Splitter.on("#").limit(3).splitToList("hello#world#java#google#scala");
+        System.out.println(list.size());    // 3
+        System.out.println(list);           // [hello, world, java#google#scala]
+    }
+
+    /**
+     * 按长度分割
+     */
+    public void test5() {
+        List<String> list = Splitter.fixedLength(3).splitToList("aaabbbccccddd");
+        System.out.println(list.size());    // 5
+        System.out.println(list);           // [aaa, bbb, ccc, cdd, d]
+    }
+
+    /**
+     * 正则匹配
+     */
+    public void test6() {
+        /*通过正则表达式初始化拆分器*/
+        String str = "apple.banana,,orange,,.";
+
+        List<String> result = Splitter.onPattern("[.|,]").omitEmptyStrings().trimResults().splitToList(str);
+        System.out.println(result);     // [apple, banana, orange]
+    }
+
+    /**
+     * 正则表达式 + 键值对
+     */
+    public void test7() {
+        Map<String, String> map = Splitter.on(Pattern.compile("\\|"))
+                .trimResults()
+                .omitEmptyStrings()
+                .withKeyValueSeparator("=")
+                .split("hello=HELLO| world=WORLD|||");
+
+        System.out.println(map.size()); // 2
+        System.out.println(map);        // {hello=HELLO, world=WORLD}
+    }
+
+    /**
+     * CharMatcher.anyOf
+     */
+    public void test8() {
+        /*通过Char初始化拆分器,将String分隔为Iterable*/
+        String str = "this, is  , , random , text,";
+        List<String> result = Lists.newArrayList(Splitter.on(',').omitEmptyStrings().trimResults().split(str));
+        System.out.println(result);     // [this, is, random, text]
+
+        String str1 = "~?~this, is~~ , , random , text,";
+        result = Splitter.on(',').omitEmptyStrings().trimResults(CharMatcher.anyOf("~? ")).splitToList(str1);
+        System.out.println(result);     // [this, is, random, text]
+    }
+
+}

+ 68 - 0
guavaGoogle/src/test/java/org/example/string/StringsTest.java

@@ -0,0 +1,68 @@
+package org.example.string;
+
+import com.google.common.base.Strings;
+import org.junit.Test;
+
+/**
+ * Strings 工具
+ */
+public class StringsTest {
+
+    /**
+     * 1、如果为空或null 就返回 null
+     * 2、不为空或null 返回当前值
+     */
+    @Test
+    public void test1() {
+        System.out.println(Strings.emptyToNull(""));            // null
+        System.out.println(Strings.emptyToNull(null));          // null
+        System.out.println(Strings.emptyToNull(" "));
+        System.out.println(Strings.emptyToNull("hello world")); // hello world
+    }
+
+    /**
+     * 空值判断
+     */
+    @Test
+    public void test2() {
+        System.out.println(Strings.isNullOrEmpty(""));      // true
+        System.out.println(Strings.isNullOrEmpty(" "));     // false
+        System.out.println(Strings.isNullOrEmpty(null));    // true
+    }
+
+    /**
+     * 前缀、后缀
+     */
+    @Test
+    public void test3() {
+        System.out.println(Strings.commonPrefix("Hello","Hit"));    // H
+        System.out.println(Strings.commonPrefix("Hello","Xit"));    // 空
+        System.out.println(Strings.commonSuffix("world","xid"));    // d
+        System.out.println(Strings.commonSuffix("world","xic"));    // 空
+    }
+
+    /**
+     * 重复数据
+     */
+    @Test
+    public void test4() {
+        System.out.println(Strings.repeat("TingFeng",3));   // TingFengTingFengTingFeng
+    }
+
+    /**
+     * 数据填充
+     *
+     * 1、设定长度小于等于字符串长度 - 忽略
+     * 2、设定长度大于字符串长度忽略 - 填充
+     */
+    @Test
+    public void test5() {
+        // 向前填充
+        System.out.println(Strings.padStart("Hello",3,'X'));    // Hello
+        System.out.println(Strings.padStart("Hello",8,'X'));    // XXXHello
+        // 向后填充
+        System.out.println(Strings.padEnd("Hello",3,'X'));      // Hello
+        System.out.println(Strings.padEnd("Hello",8,'X'));      // HelloXXX
+    }
+
+}