Guava基础知识

Guava简介

Guava是google基于Java1.6非常强大的API扩展库,提供了如:集合、缓存、原生类型支持、并发库、通用注解、字符串处理 、I/O 等等。使用这些开源的类库,不仅能够节约你的宝贵时间,减少出错可能,还可以让coder将时间都集中在处理自己独特的业务逻辑上。同时多看看这些优秀的开源库代码,向大牛学习编码的原则和规范,提升自己设计API的能力,让代码更易读,更整洁,更简单,因为这些API自身就是很好的例子。

源码包:
  com.google.common.annotations:普通注解类型。
  com.google.common.base:基本工具类库和接口。
  com.google.common.cache:缓存工具包,支持多种缓存过期策略。
  com.google.common.collect:带泛型的集合接口扩展和实现,以及工具类,开源框架下随处可见。
  com.google.common.escape: 
  com.google.common.eventbus:发布订阅风格的事件总线。
  com.google.common.hash: 哈希工具包,更复杂的散列实现,并提供布鲁姆过滤器的实现。
  com.google.common.html: HTML工具包。
  com.google.common.io:I/O工具包。
  com.google.common.math:原始算术类型和超大数的运算工具包。
  com.google.common.net:网络工具包。
  com.google.common.primitives:八种原始类型和无符号类型的静态工具包。
  com.google.common.reflect:反射工具包。
  com.google.common.util.concurrent:多线程工具包。
  com.google.common.util.xml:xml工具包。

本篇介绍一些编码中经常使用的集合类:

Optional

  • 开发人员使用null表明的是某种缺失情形:可能是已经有一个默认值,或没有值,或找不到值。例如,Map.get返回null就表示找不到给定键对应的值。

  • Guava用Optional表示可能为null的T类型引用。一个Optional实例可能包含非null的引用(我们称之为引用存在),也可能什么也不包括(称之为引用缺失)。它从不说包含的是null值,而是用存在或缺失来表示。但Optional从不会包含null值引用。

  • 使用Optional除了赋予null语义,增加了可读性,最大的优点在于它是一种傻瓜式的防护。Optional迫使你积极思考引用缺失的情况,因为你必须显式地从Optional获取引用。

创建Optional实例(以下都是静态方法):
Optional.of(T) 创建指定引用的Optional实例,若引用为null则快速失败
Optional.absent() 创建引用缺失的Optional实例
Optional.fromNullable(T) 创建指定引用的Optional实例,若引用为null则表示缺失

用Optional实例查询引用(以下都是非静态方法):
boolean isPresent()如果Optional包含非null的引用(引用存在),返回true
T get() 返回Optional所包含的引用,若引用缺失,则抛出java.lang.IllegalStateException
T or(T) 返回Optional所包含的引用,若引用缺失,返回指定的值
T orNull() 返回Optional所包含的引用,若引用缺失,返回null

不可变集合Immutable
当对象被不可信的库调用时,不可变形式是安全的;
不可变对象被多个线程调用时,不存在竞态条件问题
不可变集合不需要考虑变化,因此可以节省时间和空间。所有不可变的集合都比它们的- 可变形式有更好的内存利用率(分析和测试细节);
不可变对象因为有固定不变,可以作为常量来安全使用。
创建不可变集合:
copyOf方法,如ImmutableSet.copyOf(set);
of方法,如ImmutableSet.of(“a”, “b”, “c”)ImmutableMap.of(“a”, 1, “b”, 2);
Builder工具

新集合类型

  • Guava引入了很多JDK没有的、但我们发现明显有用的新集合类型。这些新类型是为了和JDK集合框架共存。

  • Multiset 统计单词出现的次数

    String sentences = "this is a story, there is a good girl in the story."; 
    Map<String, Integer> counts = new HashMap<String, Integer>(); 
    for (String word : words) { 
    } else { 
    counts.put(word, count + 1); }
    }
        Multiset multiset = HashMultiset.create();
    
        for (String word : words) {
            multiset.add(word);
        }
    
        for (Object element : multiset.elementSet()) {
            System.out.println((String) element + ":" + multiset.count(element));
        }
  • Multimap
    Guava的 Multimap可以很容易地把一个键映射到多个值。换句话说,Multimap是把键映射到任意多个值的一般方式。

  • BiMap
    BiMap是一个有用的集合类型,很简单,它就是一个双向的映射。

Function 和Predicate

Function<String, Integer> lengthFunction = new Function<String, Integer>() {
    public Integer apply(String string) {
        return string.length();
    }
};
Predicate<String> allCaps = new Predicate<String>() {
    public boolean apply(String string) {
        return CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string);
    }
};
Multiset<Integer> lengths = HashMultiset.create(
     Iterables.transform(Iterables.filter(strings, allCaps), lengthFunction));
  • Functions提供简便的Function构造和操作方法

    • toStringFunction()
    • compose(Function, Function)
  • Predicates提供了处理Predicate的方法

    • compose(Predicate, Function)
    • and(Predicate…)
    • or(Predicate…)
    • not(Predicate)
  • ListenableFuture
    传统JDK中的Future通过异步的方式计算返回结果:在多线程运算中可能或者可能在没有结束返回结果,Future是运行中的多线程的一个引用句柄,确保在服务执行返回一个Result。

  • ListenableFuture可以允许你注册回调方法(callbacks),在运算(多线程执行)完成的时候进行调用, 或者在运算(多线程执行)完成后立即执行。这样简单的改进,使得可以明显的支持更多的操作,这样的功能在JDK concurrent中的Future是不支持的。

    private ListeningExecutorService singleExecutorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
    void sendEmail(final Map<String, String> params, final int typeCode, final String recipients, final String reMail, int operatorId) {
        ListenableFuture<Boolean> listenableFuture = singleExecutorService.submit(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                return mailService.send(typeCode, recipients, params, reMail);
            }
        });
        Futures.addCallback(listenableFuture, new FutureCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                if (result) {
                    LOGGER.info("sendEmail success ,to:" + recipients + " params: " + params.toString());
                } else {
                    LOGGER.warn("sendEmail failure ,to:" + recipients + " ,params: " + params.toString());
                }
            }
    
            @Override
            public void onFailure(Throwable t) {
                LOGGER.error("sendEmail throw error, to:" + recipients + " ,params: " + params.toString() + " ,throw Exception:" + t.getMessage(), t);
            }
        });
    }

字符串处理

  • 连接器[Joiner] 用分隔符把字符串序列连接起来也可能会遇上不必要的麻烦。如果字符串序列中含有null,那连接操作会更难。Fluent风格的Joiner让连接字符串更简单。
    Joiner.on(",").join(Arrays.asList(1, 5, 7)); // returns "1,5,7"
    拆分器[Splitter] splitter可以被设置为按照任何模式、字符、字符串或字符匹配器拆分。
  String s = ",a,,b,";
        System.out.println(Lists.newArrayList(s.split(",")));
        System.out.println(Splitter.on(',')
                .trimResults()
                .omitEmptyStrings()
                .split(s));

字符匹配器[CharMatcher]

  • 使用CharMatcher的好处更在于它提供了一系列方法,让你对字符作特定类型的操作:修剪[trim]、折叠[collapse]、移除[remove]、保留[retain]等等
 String string = "12323  eiurwer  HGWIehi";
        String theDigits = CharMatcher.DIGIT.retainFrom(string); //只保留数字字符
        String spaced = CharMatcher.WHITESPACE.trimAndCollapseFrom(string, ' ');
        String noDigits = CharMatcher.JAVA_DIGIT.replaceFrom(string, "*"); //用*号替换所有数字
        String lowerAndDigit = CharMatcher.JAVA_DIGIT.or(CharMatcher.JAVA_LOWER_CASE).retainFrom(string);
  • 大小写格式[CaseFormat] CaseFormat被用来方便地在各种ASCII大小写规范间转换字符串
  • 格式
    LOWER_CAMEL lowerCamel LOWER_HYPHEN lower-hyphen LOWER_UNDERSCORE lower_underscore UPPER_CAMEL UpperCamel UPPER_UNDERSCORE UPPER_UNDERSCORE
  • 范例
CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, "CONSTANT_NAME")

EventBus

  • EventBus,事件总线,guava基于观察者模式的优雅实现。对于事件监听和发布订阅模式,使用guava eventbus可以省去开发人员很多事情,不用在去定义那些复杂的类或接口来实现事件发布与订阅。在guava eventbus中,开发人员只需要在订阅方法上添加上@Subscribe注解就可以了,这样一来就省去了大量共用的编码工作。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值