Google Guava参考笔记

Joiner详细介绍以及和Java8Collector对比

Joiner
    @Test
    public void testJoiner(){
        // 字符串处理Joiner
        final List list = Arrays.asList("a","b","c",null);
//        System.out.println(Joiner.on("#").join(list)); //NullPointerException
        System.out.println(Joiner.on("#").useForNull("default").join(list)); //a#b#c#default
        System.out.println(Joiner.on("#").skipNulls().join(list)); //a#b#c

        final Map map = ImmutableMap.of("h1","v1","h2","v2");
        System.out.println(Joiner.on("#").withKeyValueSeparator("=").join(map)); //h1=v1#h2=v2
    }

Joiner.on("#").useForNull("default").appendTo()也可以写到StringBuilder、StringBuffer、FileWriter等里面

JAVA8中的Collectors实现
String collect = list.stream().filter(item -> item != null && !item.isEmpty()).collect(Collectors.joining("#")); 
System.out.println(collect);//a#b#c

String collect = list.stream()
                .map(item -> item == null || item.isEmpty() ? "default" : item)
                .filter(item -> !item.isEmpty())
                .collect(Collectors.joining("#")); //a#b#c
System.out.println(collect); //a#b#c#default

Guava Splitter详细介绍

Splitter
    @Test
    public void testSplit(){
        String str = "a#b#c#  #e##";
        System.out.println(Splitter.on("#").splitToList(str)); //[a, b, c,   , e, , ]
        System.out.println(Splitter.on("#").omitEmptyStrings().splitToList(str)); //[a, b, c,   , e]
        System.out.println(Splitter.on("#").trimResults().omitEmptyStrings().splitToList(str)); //[a, b, c, e]
        System.out.println(Splitter.fixedLength(4).splitToList(str)); //[a#b#, c#  , #e##]
        System.out.println(Splitter.on("#").limit(2).splitToList(str)); //[a, b#c#  #e##] 两个元素

        String str2 = "a1=a;b1=b";
        //Map
        System.out.println(Splitter.on(";").withKeyValueSeparator("=").split(str2)); //{a1=a, b1=b}
    }

还可以支持正则切分


正则

Preconditions&Objects&assert断言介绍

Preconditions
    @Test
    public void testPreconditions(){
        List list = null;
        checkNotNullWithMsg(list); //java.lang.NullPointerException: this is null
    }

    private void checkNotNullWithMsg(List list){
        Preconditions.checkNotNull(list,"this is null");
    }
Objects
Objects.requireNonNull(null); //java.lang.NullPointerException
...
assert
List list = null;
assert list != null; //java.lang.AssertionError
assert list != null : "this is msg"; //java.lang.AssertionError: this is msg
...

ComparisonChain比较器

    @Test
    public void testObjects(){
        Guava g1 = new Guava("1","2",new Date());
        Guava g2 = new Guava("2","2",new Date());
        Guava g3 = new Guava("3","2",new Date());
        System.out.println(g1.compareTo(g2)); // -1
        System.out.println(g3.compareTo(g2)); // 1
    }
    static class Guava implements Comparable{
        private final String factory;
        private final String version;
        private final Date date;

        public Guava(String factory, String version, Date date) {
            this.factory = factory;
            this.version = version;
            this.date = date;
        }

        @Override
        public int compareTo(Guava o) {
            return ComparisonChain.start().compare(this.factory,o.factory)
                    .compare(this.version,o.version)
                    .compare(this.date,o.date).result();
        }
    }

Strings&Charsets&CharMatcher介绍

    @Test
    public void testStrings(){
        System.out.println(Strings.emptyToNull("")); //null
        System.out.println(Strings.nullToEmpty(null)); //""
        System.out.println(Strings.nullToEmpty("h")); //h
        System.out.println(Strings.commonPrefix("d1","d2")); //d
        System.out.println(Strings.repeat("d1",3)); //d1d1d1
    }
Strings方法
    @Test
    public void testCharsets(){
        Charset charset = Charset.forName("UTF-8");
        Charset charset2 = Charsets.UTF_8;
    }
    @Test
    public void testCharMatcher(){
        System.out.println(CharMatcher.is('A').countIn("Alex A a b")); //2
        System.out.println(CharMatcher.breakingWhitespace().collapseFrom("Alex     A a b", '*')); //Alex*A*a*b
        System.out.println(CharMatcher.javaDigit().or(CharMatcher.whitespace()).removeFrom("Alex     A a b 1 231"));//AlexAab
    }

函数式接口

Function

Function<传入类型,输出类型>

public class FunctionExample {
    public static void main(String[] args) {
        //传进去一个词,返回一个这个词的长度
        Function getLength = new Function() {
            @Override
            public Integer apply(String input) {
                Preconditions.checkNotNull(input, "check is null");
                return input.length();
            }
        };

        Integer testLength = getLength.apply("test");
        System.out.println(testLength);
//        Functions

    }
}

Supplier

提供结果的函数接口.只有返回值,没有输入参数

public class FunctionExample {
    public static void main(String[] args) {
        //这是一个提供结果的函数接口.
        //(1)只有返回值
        //(2)没有输入参数
        Supplier supplier = new Supplier() {
            @Overrider
            public String get() {
                System.out.println(111);
                return "test";
            }
        };
        String s = supplier.get();
        System.out.println(s);
        //Suppliers
    }
}
Predicate

提供test()方法,输出boolean

public class FunctionExample {
    public static void main(String[] args) {
        Predicate predicate = new Predicate() {
            @Override
            public boolean apply(String input) {
                return Objects.equals("test",input);
            }
        };
        boolean test1 = predicate.equals(predicate); // true
        boolean test2 = predicate.test("test2"); // false
        boolean test3 = predicate.equals("test"); //false
        boolean test4 = predicate.test("test");//true
        
        //Predicates...

    }
}

StopWatch

类似于 结束时间 - 开始时间

public class WatchExample {
    public static void main(String[] args) throws Exception {
        // 创建自动start的计时器
        Stopwatch watch = Stopwatch.createStarted();
        Thread.sleep(1000L);
        long time = watch.elapsed(TimeUnit.MILLISECONDS);
        // 结果1003
        System.out.println("代码执行时长:" + time);

        // 创建非自动start的计时器
        // 累计了start到stop的时间
        Stopwatch watch1 = Stopwatch.createUnstarted();
        Thread.sleep(1000L);
        watch1.start();
        Thread.sleep(1000L);
        watch1.stop();
        watch1.start();
        Thread.sleep(500L);
        time = watch1.elapsed(TimeUnit.MILLISECONDS);
        // 结果1500
        System.out.println("代码执行时长:" + time);

        Stopwatch watch2 = Stopwatch.createUnstarted();
        watch2.start();
        Thread.sleep(1000L);
        time = watch2.elapsed(TimeUnit.MILLISECONDS);
        // 结果1000
        System.out.println("代码执行时长:" + time);
    }
}

IO Files

对InputStream,OutputStream等的一些封装,提供了很多API,
官方文档:https://guava.dev/releases/27.0.1-jre/api/docs/com/google/common/io/Files.html

CharSource和CharSink

ByteSource和ByteSink

Closer使用

try...catch...finally的优化

Base*coding

EventBus

EventBus是Guava的事件处理机制,是设计模式中的观察者模式(生产/消费者编程模型)的优雅实现,在应用中可以处理一些异步任务。对于事件监听和发布订阅模式,EventBus是一个非常优雅和简单解决方案,我们不用创建复杂的类和接口层次结构。
EventBus实际上是一个消息队列,Event Source发送一个消息到EventBus,然后再由EventBus将消息推送到所监听的Listener。
https://blog.csdn.net/wangdong5678999/article/details/80561198

Monitor

Monitor是一个支持任意布尔条件的同步的抽象,Monitor类是作为ReentrantLock的一个替代,代码中使用Monitor比使用ReentrantLock更不易出错,可读性也更强,并且也没有显著的性能损失,使用Monitor甚至有潜在的性能得到优化
https://www.cnblogs.com/hupengcool/p/4250903.html

RateLimiter

常用的限流算法有漏桶算法和令牌桶算法
https://www.jianshu.com/p/8f548e469bbe
https://blog.csdn.net/fanrenxiang/article/details/80949079

简单Demo:
public class RateLimiterExample {
    // 一秒钟允许多少个操作
    private final static RateLimiter limiter = RateLimiter.create(0.5); // 一秒钟允许0.5个操作,2秒钟1次操作
    public static void main(String[] args) throws Exception {
        ExecutorService service = Executors.newFixedThreadPool(10);
        IntStream.range(0,10).forEach( i -> {
            service.submit(RateLimiterExample::testLimiter);
        });
    }
    private static void testLimiter(){
        System.out.println(Thread.currentThread() + "waiting " + limiter.acquire());
    }
}
---大约两秒打印一次
Thread[pool-1-thread-1,5,main]waiting 0.0
Thread[pool-1-thread-2,5,main]waiting 1.874738
Thread[pool-1-thread-3,5,main]waiting 3.872905
Thread[pool-1-thread-5,5,main]waiting 5.871703
Thread[pool-1-thread-4,5,main]waiting 7.871677
Thread[pool-1-thread-6,5,main]waiting 9.871123
Thread[pool-1-thread-7,5,main]waiting 11.870788
Thread[pool-1-thread-8,5,main]waiting 13.870773
Thread[pool-1-thread-9,5,main]waiting 15.870581
Thread[pool-1-thread-10,5,main]waiting 17.869938


限流桶实现

public class Bucket
{

    private final ConcurrentLinkedQueue container = new ConcurrentLinkedQueue<>();

    private final static int BUCKET_LIMIT = 1000;

    private final RateLimiter limiter = RateLimiter.create(10);

    private final Monitor offerMonitor = new Monitor();
    private final Monitor pollMonitor = new Monitor();

    public void submit(Integer data)
    {
        if (offerMonitor.enterIf(offerMonitor.newGuard(() -> container.size() < BUCKET_LIMIT)))
        {
            try
            {
                container.offer(data);
                System.out.println(currentThread() + " submit data " + data + ",current size:" + container.size());
            } finally
            {
                offerMonitor.leave();
            }
        } else
        {
            throw new IllegalStateException("The bucket is full.");
        }
    }


    public void takeThenConsume(Consumer consumer)
    {
        if (pollMonitor.enterIf(pollMonitor.newGuard(() -> !container.isEmpty())))
        {
            try
            {
                System.out.println(currentThread() + " waiting " + limiter.acquire());
                consumer.accept(container.poll());
            } finally
            {
                pollMonitor.leave();
            }
        }
    }
}

public class BucketTest
{

    public static void main(String[] args)
    {
        final Bucket bucket = new Bucket();
        final AtomicInteger DATA_CREATOR = new AtomicInteger(0);

        IntStream.range(0, 5).forEach(i ->
        {
            new Thread(() ->
            {
                for (; ; )
                {
                    int data = DATA_CREATOR.getAndIncrement();
                    bucket.submit(data);
                    try
                    {
                        TimeUnit.MILLISECONDS.sleep(200L);
                    } catch (Exception e)
                    {
                        if (e instanceof IllegalStateException)
                        {
                            System.out.println(e.getMessage());
                        }
                    }
                }       //25

                //10

                //5:2
            }).start();
        });


        IntStream.range(0, 5)
                .forEach(i -> new Thread(() ->
                        {
                            for (; ; )
                            {
                                bucket.takeThenConsume(x -> System.out.println(currentThread() + " W " + x));
                            }
                        }).start()
                );
    }
}

令牌桶实现

public class TokenBucket
{

    private AtomicInteger phoneNumbers = new AtomicInteger(0);

    private final static int LIMIT = 100;

    private RateLimiter rateLimiter = RateLimiter.create(10);

    private final int saleLimit;

    public TokenBucket()
    {
        this(LIMIT);
    }

    public TokenBucket(int limit)
    {
        this.saleLimit = limit;
    }

    public int buy()
    {
        Stopwatch started = Stopwatch.createStarted();
        boolean success = rateLimiter.tryAcquire(10, TimeUnit.SECONDS);
        if (success)
        {
            if (phoneNumbers.get() >= saleLimit)
            {
                throw new IllegalStateException("Not any phone can be sale, please wait to next time.");
            }
            int phoneNo = phoneNumbers.getAndIncrement();
            handleOrder();
            System.out.println(currentThread() + " user get the Mi phone: " + phoneNo + ",ELT:" + started.stop());
            return phoneNo;
        } else
        {
            started.stop();
            throw new RuntimeException("Sorry, occur exception when buy phone");
        }
    }

    private void handleOrder()
    {
        try
        {
            TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(10));
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}

public class TokenBucketExample
{

    public static void main(String[] args)
    {
        final TokenBucket tokenBucket = new TokenBucket();
        for (int i = 0; i < 200; i++)
        {
            new Thread(tokenBucket::buy).start();
        }
    }
}

ListenableFuture

FutureCallBack

JDK8:CompletableFuture

Cache

Google Guava 快速入门 —— Cache 缓存工具
自定义LRU算法的缓存实现
软引用SoftReference介绍以及简单用法cache
理解StrongReference,SoftReference, WeakReference的区别 SoftReference:当快OOM时才进行回收。 WeakReference:只要调用GC就会被回收。

Cache简单Demo
LoadingCache employeeCache = CacheBuilder.newBuilder()
        .maximumSize(100) // 最多可以缓存100条记录
        .expireAfterAccess(30, TimeUnit.MINUTES) // 缓存将在访问30分钟后过期
        .build(new CacheLoader() {
            @Override
            public Object load(String key) throws Exception {
                // 数据库加载
                return getFromDatabase(key);
            }
        });
第一次调用加载数据库中的数据,第二次调用走缓存
employeeCache.get("key");
employeeCache.getUnchecked("key");

Guava库学习:学习Guava Cache(四)CacheBuilderSpec

Collections

FluentIterable

主要用于过滤集合

Lists

Guava提供了能够推断范型的静态工厂方法
用工厂方法模式,我们可以方便地在初始化时就指定起始元素
通过为工厂方法命名,我们可以提高集合初始化大小的可读性
java代码之美(9)---guava之Lists、Maps

Sets
Maps,BiMap,MultiMap
Table,Range

当我们需要多个索引的数据结构的时候,通常情况下,我们只能用这种丑陋的Map>来实现。为此Guava提供了一个新的集合类型-Table集合类型,来支持这种数据结构的使用场景。Table支持“row”和“column”,而且提供多种视图。

Range,RangeMap

Guava学习笔记:Guava新集合-Table等

Immutable Collections,Sorted Collections

java代码之美(4)---guava之Immutable(不可变)集合


Google Guava 快速入门
Guava库学习
Java--代码之美

你可能感兴趣的:(Google Guava参考笔记)