初学guava,记到小本本上

Guava入门

Guava简介

Java类库中有不少难用的典型,Collection一定是其中之一。Google最早提出Guava库,是对Java Collection进行扩展以提高开发效率。随着时间推移,它已经覆盖到了Java开发的方方面面,在Java 8中,已经可以看到不少API就是从Guava中原封不动的借鉴而来。接下来的几个例子比较了使用Guava和原生JDK的开发。

初始化集合

//JDK
List<String> list = new ArrayList<String>(); 
list.add("a");
list.add("b");
list.add("c");
list.add("d");

//Guava
List<String> list = Lists.newArrayList("a", "b", "c", "d");

这也是我初见Guava,就对这个没见过的语法产生了兴趣。(这是不是设计模式中的工厂模式?)

读取文件内容

//Guava
List<String> lines = Files.readLines(file, Charsets.UTF_8);

入参只需要一个文件和编码格式那是相当的简洁了。

集合新类型

Guava针对开发中的常见场景,提供了一些新的集合类型简化代码。

Multiset

这个可以帮我们统计一个集合中某个元素出现了多少次

//这是java的写法
Map<String, Integer> counts = new HashMap<String, Integer>();
for (String word : words) {
    Integer count = counts.get(word);
    if (count == null) {
        counts.put(word, 1);
    } else {
        counts.put(word, count + 1);
    }
}

这段代码看起来有一点丑陋,并且容易出错。Guava提供了一种新的集合类型——Multiset。顾名思义,也就是Set中能够同时存在相同的元素:

@Test
    public void test1(){
        HashMultiset<String> multiset = HashMultiset.create();
        multiset.add("111");
        multiset.add("2222");
        //添加五次
        multiset.add("444",5); 
		//从这可以看出是无序
        System.out.println(multiset);   // [111, 444 x 5, 2222]
        System.out.println(multiset.elementSet());  // [111, 444, 2222]
        System.out.println(multiset.count("111")); // 1
        System.out.println(multiset.count("444")); // 5
        System.out.println(multiset.count("000")); // 0
		//完成包含(子集)就返回true,反之则false        
        System.out.println(multiset.containsAll(Arrays.asList("111","2222"))); //true
        System.out.println(multiset.containsAll(Arrays.asList("111","2222","3"))); //false
    }

Multiset很像一个ArrayList,因为它允许重复元素,只不过它的元素之间没有顺序;同时它又具备Map<String, Integer>的某一些特性。但本质上它还是一个真正的集合类型——用来表达数学上“多重集合”的概念,这个例子只是恰好和Map对应上罢了。

MultiMap

看名字就可以看出来是一个Map的增强的,想必在开发的过程中你一定遇到过实现一个这样的集合:Map<K, List> Map<K, Set>用来表达某一个Key对应的元素是一个集合,可以用两种视角来看待这类集合:

a -> 1 a -> 2 a -> 4 b -> 3 c -> 5

另一种是:

a -> [1, 2, 4] b -> 3 c -> 5

如果使用JDK提供的Collection来实现类似功能,那么一定会有类似上一节中统计数量的代码:添加一个元素时,先在Map中查找该元素对应的List,如果不存在则新建一个List对象。

Multimap<String, Integer> multimap = ArrayListMultimap.create();
multimap.put("a", 1);
multimap.put("a", 2);
multimap.put("a", 4);
multimap.put("b", 3);
multimap.put("c", 5);

System.out.println(multimap.keys());//[a x 3, b, c]
System.out.println(multimap.get("a"));//[1 ,2, 4]
System.out.println(multimap.get("b"));//[3]
System.out.println(multimap.get("c"));//[5]
System.out.println(multimap.get("d"));//[]

/*
  public String toString() {
        return this.asMap().toString();
    }
*/
//查看源码发现toString就是调用了asMap,下面两个的结果相等
System.out.println(multimap);
System.out.println(multimap.asMap());//{a=[1, 2, 4], b=[3], c=[5]}

Sets

我们经常需要操作集合(Set),并对集合进行交并补差等运算,Sets类提供了这些方法:

  • union(Set, Set)
  • intersection(Set, Set)
  • difference(Set, Set)
  • symmetricDifference(Set, Set)
Set<String> wordsWithPrimeLength = ImmutableSet.of("one", "two", "three", "six", "seven", "eight");
Set<String> primes = ImmutableSet.of("two", "three", "five", "seven");

SetView<String> intersection = Sets.intersection(primes, wordsWithPrimeLength); // contains "two", "three", "seven"
// I can use intersection as a Set directly, but copying it can be more efficient if I use it a lot.
return intersection.immutableCopy();

Primitives

这个也是相当方便的。
Java中的基本类型(Primitive)包括:byte, short, int, long, float, double, char, boolean。

在Guava中与之对应的一些工具类包括Bytes, Shorts, Ints, Longs, Floats, Doubles, Chars, Booleans。现在以Ints为例示范一些常用方法:

//变成集合
System.out.println(Ints.asList(1,2,3,4));
//前一个小于后一个返回-1,大于则返回1
System.out.println(Ints.compare(1, 2));
//以什么分割
System.out.println(Ints.join(" ", 1, 2, 3, 4));
//取最大值
System.out.println(Ints.max(1, 3, 5 ,4, 6));
//字符串转数字
/*
public static Integer tryParse(String string) {
    return tryParse(string, 10);
  }

public static Integer tryParse(
      String string, int radix) {
    Long result = Longs.tryParse(string, radix);
    if (result == null || result.longValue() != result.intValue()) {
      return null;
    } else {
      return result.intValue();
    }
  }
  */
System.out.println(Ints.tryParse("1234"));

输出结果:

[1, 2, 3, 4]
-1   
1 2 3 4
6
1234

出于兴趣,尝试了一下Booleans:

 
/*
[true, true, false]
-1
true,true,false
*/
 System.out.println(Booleans.asList(true,true,false));
 System.out.println(Booleans.compare(false, true));
 System.out.println(Booleans.join(",",true, true, false));
/*
public static int compare(boolean a, boolean b) {
    return (a == b) ? 0 : (a ? 1 : -1);
  }
*/

想不出这个能用在哪,但是应该是有用的。

Hashing

编写一个Hash散列算法在Java中比较繁复,但是在Guava里却非常简单:

public static String md5(String str) {
    return Hashing.md5().newHasher()
            .putString(str, Charsets.UTF_8)
            .hash()
            .toString();
}

总结

Guava是一个非常有用的现代程序库,在Java项目中强烈推荐使用它来取代Apache Commons的一些子项目(例如Lang, Collection, IO等等),除了这里介绍的一些最常用的特性,它还包括缓存、网络、IO、函数式编程等等内容(其中函数式编程在Java 8中可以使用Stream和Lambda表达式等特性来实现)。它的参考文档应该是Java程序员手头必备之物。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值