• 第六周 十倍效率开发神器-Guava


    Guava

    什么是Guava?

    Guava是谷歌开源的工具库,里面包含了一些新的集合类型、并发工具类、I/O、缓存、字符串操作等等。

    引入依赖:

    <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>30.1.1-jre</version>
    </dependency>
    

    3.1 集合操作

    1. 不可变集合:用不可变的集合进行防御性编程
    2. 新集合类型:Multimap、SortedMultiset等
    3. 强大的集合工具类
    4. 扩展工具类:让实现和扩展集合类变得更容易,比如创建Collection的装饰器

    使用示例:

      public static void testCollection(){
            //不能进行新增,会抛出UnsupportedOperationException
            ImmutableSet<String> immutableSet = ImmutableSet.of("red", "orange", "yellow", "blue", "blue", "green");
            System.out.println(immutableSet);
    
            //同个key的值放入不会覆盖
            ArrayListMultimap arrayListMultimap = ArrayListMultimap.create();
            arrayListMultimap.put("a",1);
            arrayListMultimap.put("a",2);
            System.out.println(arrayListMultimap.get("a"));
    
            //集合工具类
            ArrayList<String> list = Lists.newArrayList("aa", "bb", "cc");
            String aa = Iterables.find(list, x -> x.equals("aa"));
            System.out.println(aa);
    
            List<Integer> integers = Ints.asList(1, 2, 3, 4, 5, 6, 7, 8);
            List<Integer> reverse = Lists.reverse(integers);
            //分成3个一组
            List<List<Integer>> partition = Lists.partition(integers, 3);
    
            Set<String> wordsWithPrimeLength = ImmutableSet.of("one", "two", "three", "six", "seven", "eight");
            Set<String> primes = ImmutableSet.of("two", "three", "five", "seven");
    
            //获取两个set里共有的
            Sets.SetView<String> intersection = Sets.intersection(primes, wordsWithPrimeLength); // contains "two", "three", "seven"
            System.out.println(intersection);
    
            //转list为map
            User user = new User();
            user.setName("liu");
            user.setId(1);
            User user2 = new User();
            user2.setName("wang");
            user2.setId(2);
            ArrayList<User> users = Lists.newArrayList(user, user2);
            ImmutableMap<Integer, User> integerUserImmutableMap = Maps.uniqueIndex(users, u -> u.getId());
            System.out.println(integerUserImmutableMap);
    
            //快速创建map
            ImmutableMap.<String,Object>of("type","aa");
    
    
        }
    

    3.2 本地缓存

    实现了JVM缓存,支持多种缓存过期策略

    3.2.1 创建方式:

    创建方式1:使用CacheLoader

    public static void testCache() throws InterruptedException, ExecutionException {
            CacheLoader<Integer,User> cacheLoader=new CacheLoader<Integer, User>() {
                @Override
                public User load(Integer key) throws Exception {
                    return new User(key,"王二");
                }
            };
            LoadingCache<Integer, User> cache = CacheBuilder.newBuilder().maximumSize(1000)
                    .expireAfterWrite(30, TimeUnit.SECONDS)
                    .build(cacheLoader);
        }
    

    创建方式2:使用Callable

     Cache<Integer,User> objectCache = CacheBuilder.newBuilder().maximumSize(1000)
                    .expireAfterWrite(30, TimeUnit.SECONDS)
                    .build();
            User user = objectCache.get(1, ()  -> new User(1, "王二"));
    
    3.2.2 缓存回收
    1. 指定大小回收
     CacheLoader<Integer,User> cacheLoader=new CacheLoader<Integer, User>() {
                @Override
                public User load(Integer key) throws Exception {
                    return new User(key,"王二");
                }
            };
            LoadingCache<Integer, User> cache = CacheBuilder.newBuilder().
            //指定大小是3个
            maximumSize(3)
                    .expireAfterWrite(30, TimeUnit.SECONDS)
                    .build(cacheLoader);
    
            cache.put(1,new User(1,"a"));
            cache.put(2,new User(2,"a"));
            cache.put(3,new User(3,"a"));
            cache.put(4,new User(4,"a"));
            //getIfPresent方法不会重新加载创建cache
            System.out.println(cache.getIfPresent(  1));
            System.out.println(cache.getIfPresent(2));
            System.out.println(cache.getIfPresent(3));
            System.out.println(cache.getIfPresent(4));
    

    打印结果:

    null
    User(id=2, name=a)
    User(id=3, name=a)
    User(id=4, name=a)
    

    最早插入的会被回收

    1. 缓存时间回收
       CacheLoader<Integer,User> cacheLoader=new CacheLoader<Integer, User>() {
                @Override
                public User load(Integer key) throws Exception {
                    return new User(key,"王二");
                }
            };
            LoadingCache<Integer, User> cache = CacheBuilder.newBuilder().maximumSize(3)
                    .expireAfterWrite(3, TimeUnit.SECONDS)
                    .build(cacheLoader);
            cache.put(1,new User(1,"a"));
            Thread.sleep(2000);
            System.out.println(cache.getIfPresent(  1));
            Thread.sleep(2000);
            System.out.println(cache.getIfPresent(1));
    

    打印结果为空

    • expireAfterWrite(time),上次写入多长时间后过期
    • expireAfterAccess(time),上次写或读操作多长时间后过期

    上面的示例中,用expireAfterWrite的话,第二次打印结果为null,用expireAfterAccess的话第二次的打印结果有值

    3.2.3 显示的清除缓存
    • Cache.invalidate(key) :清除指定单个key
    • Cache.invalidateAll(keys):清除指定多个key
    • Cache.invalidateAll() :清除所有
    3.2.4 移除缓存监听器
     CacheLoader<Integer,User> cacheLoader=new CacheLoader<Integer, User>() {
                @Override
                public User load(Integer key) throws Exception {
                    return new User(key,"王二");
                }
            };
    
            RemovalListener<Integer, User> removalListener = new RemovalListener<Integer, User>() {
                public void onRemoval(RemovalNotification<Integer, User> removal) {
                    System.out.println("移除值:"+removal);
                }
            };
    
            LoadingCache<Integer, User> cache = CacheBuilder.newBuilder().maximumSize(3)
                    .expireAfterWrite(3, TimeUnit.SECONDS)
                    .removalListener(removalListener)
                    .build(cacheLoader);
            cache.put(1,new User(1,"a"));
            cache.invalidate(1);
    
    3.2.5 刷新值

    刷新值和清除值是不一样的,刷新可能是异步的,在刷新的时候,旧值还能返回给前端。而且还能覆写reload方法来自定义刷新值的逻辑

     CacheLoader<Integer,User> cacheLoader=new CacheLoader<Integer, User>() {
                @Override
                public User load(Integer key) throws Exception {
                    return new User(key,"王二");
                }
            };
    
    
            LoadingCache<Integer, User> cache = CacheBuilder.newBuilder().maximumSize(3)
                    .build(cacheLoader);
            cache.put(1,new User(1,"a"));
            Thread.sleep(4000);
            @Nullable User u1 = cache.getIfPresent(1);
            Thread.sleep(4000);
            @Nullable User u2 = cache.getIfPresent(1);
            Thread.sleep(4000);
            @Nullable User u3 = cache.getIfPresent(1);
            System.out.println(u1==u2);
            System.out.println(u2==u3);
    

    打印结果都为false,说明值被刷新了

    覆写reload的例子:

    static final ExecutorService executor = Executors.newFixedThreadPool(4);
        public static void testRefresh() throws InterruptedException {
    
            CacheLoader<Integer, User> cacheLoader=new CacheLoader<Integer, User>() {
                @Override
                public User load(Integer key) throws Exception {
                    return new User(key,"王二");
                }
    
                @Override
                public ListenableFuture<User> reload(Integer key, User oldValue) throws Exception {
                    if(key<0){
                       return Futures.immediateFuture(oldValue);
                    }else {
                        ListenableFutureTask<User> task = ListenableFutureTask.create(()-> new User(key,"name"));
                        executor.execute(task);
                        return task;
                    }
                }
            };
    
    
            LoadingCache<Integer, User> cache = CacheBuilder.newBuilder().maximumSize(3)
                    //3秒钟刷新一次
                     .refreshAfterWrite(3, TimeUnit.SECONDS)
                    .build(cacheLoader);
            cache.put(1,new User(1,"a"));
            cache.put(-1,new User(1,"a"));
            @Nullable User u1 = cache.getIfPresent(1);
            Thread.sleep(4000);
            @Nullable User u2 = cache.getIfPresent(1);
            System.out.println(u1==u2);
            Thread.sleep(4000);
            @Nullable User u3 = cache.getIfPresent(-1);
            Thread.sleep(4000);
            @Nullable User u4 = cache.getIfPresent(-1);
            System.out.println(u3==u4);
        }
    
    3.2.6 其他特性

    统计方法
    cache.stats(),需要构建的时候加上recordStats()

      CacheLoader<Integer,User> cacheLoader=new CacheLoader<Integer, User>() {
                @Override
                public User load(Integer key) throws Exception {
                    return new User(key,"王二");
                }
            };
    
    
            LoadingCache<Integer, User> cache = CacheBuilder.newBuilder().recordStats().maximumSize(3)
                    .build(cacheLoader);
            cache.put(1,new User(1,"aa"));
            cache.getIfPresent(1);
            cache.getIfPresent(1);
            cache.getIfPresent(2);
            //加载新值所用的平均时间,以纳秒为单位
            System.out.println(cache.stats().averageLoadPenalty());
            //命中次数
            System.out.println(cache.stats().hitCount());
            //load次数
            System.out.println(cache.stats().loadCount());
    

    3.3 Strings工具类

    public static void testString(){
            Joiner joiner = Joiner.on(";").skipNulls();;
            String join = joiner.join("a", "b", null, "c");
            System.out.println(join); //a;b;c
    
            Iterable<String> split = Splitter.on(',')
                    .trimResults()
                    .omitEmptyStrings()
                    .split("foo,bar,,   qux");
            System.out.println(split);  //[foo, bar, qux]
    
            //是否能匹配
            boolean b = CharMatcher.is('a').matchesAnyOf("abc");
            System.out.println(b);  //true
            //出现的次数
            int countIn = CharMatcher.is('a').countIn("abca");
            System.out.println(countIn);  //2
            //匹配指定的值
            String s = CharMatcher.is('a').retainFrom("bdaswa");  
            System.out.println(s);  //aa
        }
    

    3.4 I/O处理类

    CharSource charSource = Files.asCharSource(new File("d://1.txt"), Charset.forName("UTF-8"));
            ImmutableList<String> strings = charSource.readLines();
    

    3.5 并发工具类

    public static void testFuture() throws ExecutionException, InterruptedException {
            ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
            ListenableFuture<User> explosion = service.submit(
                    new Callable<User>() {
                        public User call() throws InterruptedException {
                            Thread.sleep(2000);
                           return new User(1,"xxxx");
                        }
                    });
            System.out.println("不阻塞,继续执行");
            Futures.addCallback(
                    explosion,
                    new FutureCallback<User>() {
                        // we want this handler to run immediately after we push the big red button!
                        public void onSuccess(User explosion) {
                            System.out.println("success:"+explosion);
                        }
                        public void onFailure(Throwable thrown) {
                            System.out.println("failure:"+thrown);
                        }
                    },
                    service);
        }
    

    3.6 反射

    public class LogHandler implements InvocationHandler {
            Object target;  // 被代理的对象,实际的方法执行者
    
            public LogHandler(Object target) {
                this.target = target;
            }
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                before();
                Object result = method.invoke(target, args);  // 调用 target 的 method 方法
                after();
                return result;  // 返回方法的执行结果
            }
            // 调用invoke方法之前执行
            private void before() {
                System.out.println(String.format("log start time [%s] ", new Date()));
            }
            // 调用invoke方法之后执行
            private void after() {
                System.out.println(String.format("log end time [%s] ", new Date()));
            }
    }
        
        public  void testReflection(){
            GoodsService goodsService = Reflection.newProxy(GoodsService.class,new LogHandler(new GoodsServiceImpl()));
            goodsService.updatePrice(1,2.0);
        }
    

    3.7 事件总线 EventBus

    发布-订阅模式的组件通信,进程内模块间解耦

    @Data
    @AllArgsConstructor
    public class UserEvent {
    
        private User user;
    
        private String remark;
    
    
    }
    
    public class UserHandler {
    
        @Subscribe
        public void handle(UserEvent userEvent){
            System.out.println("取到user:"+userEvent.getUser());
        }
    }
    
    static EventBus eventBus=new EventBus();
    //异步的
    //static EventBus eventBus=new AsyncEventBus(Executors.newSingleThreadExecutor());
        static {
            //eventBus会去找注册进去的类 @Subscribe标记的方法
            eventBus.register(new UserHandler());
        }
    
        public static void testEvent(){
            eventBus.post(new UserEvent(new User(1,"ab"),"测试"));
        }
    
    书山有路勤为径,学海无涯苦作舟
  • 相关阅读:
    java + jni + mingw实例开发(基于命令行窗口模式)
    OpenCv for Android
    Android图像处理实例教程
    eclipse使用技巧
    Android NDK开发实例教程
    Android开发的教程和资源
    JAVA安装,环境变量配置
    一些比较好的博客
    uwsgi启动Django项目时:unable to load app 0 (mountpoint='') (callable not found or import error) *** no app loaded. going in full dynamic mode ***
    robot中使用evaluate转化数据格式
  • 原文地址:https://www.cnblogs.com/javammc/p/14916066.html
Copyright © 2020-2023  润新知