Guava工具包使用

10 篇文章 1 订阅
8 篇文章 1 订阅

Guava工具包含了若干被Google的 Java项目广泛依赖 的核心库,例如:

  1. 集合 [collections]
  2. 缓存 [caching]
  3. 原生类型支持 [primitives support]
  4. 并发库 [concurrency libraries]
  5. 通用注解 [common annotations]
  6. 字符串处理 [string processing]
  7. I/O 等等

引用

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>26.0</version>
</dependency>

集合:

不可变集合

不可变对象有很多优点,包括:

  • 当对象被不可信的库调用时,不可变形式是安全的;
  • 不可变对象被多个线程调用时,不存在竞态条件问题
  • 不可变集合不需要考虑变化,因此可以节省时间和空间。所有不可变的集合都比它们的可变形式有更好的内存利用率(分析和测试细节);
  • 不可变对象因为有固定不变,可以作为常量来安全使用。


JDK也提供了Collections.unmodifiableXXX方法把集合包装为不可变形式,但我们认为不够好:

  • 笨重而且累赘:不能舒适地用在所有想做防御性拷贝的场景;
  • 不安全:要保证没人通过原集合的引用进行修改,返回的集合才是事实上不可变的;
  • 低效:包装过的集合仍然保有可变集合的开销,比如并发修改的检查、散列表的额外空间,等等。

不可变集合的创建:copyof、of、builder方法、asList 视图

新集合类型:

  • Multiset:既有ArrayList语义,也有map语义
  • SortedMultiset:支持高效获取指定范围的子集
  • Multimap:将一个键映射到多个值
  • BiMap:实现键值的双向映射
  • Table:实现表结构,使用多个值做索引
  • ClassToInstanceMap:键是类型,值是符合键所指类型的对象
ClassToInstanceMap<Number> numberDefaults=MutableClassToInstanceMap.create();
numberDefaults.putInstance(Integer.class, Integer.valueOf(0));
  • RangeSet:描述一组不相连的、非空的区间。当添加新的区间时,所有相连的区间会被合并,空区间会被忽略
  • RangeMap:描述了不相交、非空的区间到特定值的映射。不会合并相邻的映射

 

Collections中未包含的集合工具:

  • Iterables
  • FluentIterable

Lists方法:partition、reverse

集合方法:union、intersection、difference、symmetricDifference、cartesianProduct(返回所有笛卡尔积)、powerSet(所有子集)

Maps方法:

  • uniqueIndex(有一组对象,在某个属性上分别有独一无二的值,而希望能够按照这个属性值查找对象)
  • index(有一组对象,他们有共同的特定属性,希望按照这个属性的值查询对象,但属性值不一定是独一无二的)
  • difference、entriesInCommon、entriesDiffering、entriesOnlyOnLeft、entriesOnlyOnRight
  • invertFrom(Miltimap 多个键可以映射到同一个值,invertFrom后也可以将值映射到多个键)
  • forMap  把Map包装成SetMultimap

Table
    transpose  将table表进行转置

 

集合创建:

// 普通Collection的创建
List<String> list = Lists.newArrayList();
Set<String> set = Sets.newHashSet();
Map<String, String> map = Maps.newHashMap();

// 不变Collection的创建
ImmutableList<String> iList = ImmutableList.of("a", "b", "c");
ImmutableSet<String> iSet = ImmutableSet.of("e1", "e2");
ImmutableMap<String, String> iMap = ImmutableMap.of("k1", "v1", "k2", "v2");
Multiset<String> set1 = HashMultiset.create();
set1.add("a");
set1.add("2");
set1.add("a");

System.out.println("set1 = " + set1.toString());
//计算出现次数
System.out.println("count= " + set1.count("a"));
//key可以重复
Multimap<String, Integer> multimap = ArrayListMultimap.create();
multimap.put("a", 1);
multimap.put("a", 1);
System.out.println("multimap = " + multimap);

//双向map 键和值都不能重复
BiMap<String, String> biMap = HashBiMap.create();
biMap.put("a", "1");
biMap.put("b", "2");
System.out.println("bimap key " + biMap.get("a"));
System.out.println("bimap value " + biMap.inverse().get("1"));

//Table 比较常用 <row, column ,value>
Table<String, String, Integer> tables = HashBasedTable.create();
tables.put("row1", "column1",1);
tables.put("row2","column2", 2);
System.out.println("the row1 is " + tables.row("row1"));
System.out.println("the row1 cloumn is " + tables.column("column1"));
System.out.println("the value is " + tables.get("row1", "column1"));

扩展工具类

在元素添加到列表时增加特定行为

  • Forwarding装饰器:delegate,覆盖这个方法返回被装饰的对象,实现特定行为
  • PeekingIterator:事先获取下次next返回的元素
  • AbstractIterator:实现自己的Iterator
  • AbstractSequentialIerator:表示迭代的另一种方式
     

集合的过滤

(1)按照条件过滤

ImmutableList<String> names = ImmutableList.of("begin", "code", "Guava", "Java");
Iterable<String> fitered = Iterables.filter(names, Predicates.or(Predicates.equalTo("Guava"), Predicates.equalTo("Java")));
System.out.println(fitered); // [Guava, Java]

(2)自定义过滤条件

//自定义过滤条件   使用自定义回调方法对Map的每个Value进行操作
ImmutableMap<String, Integer> m = ImmutableMap.of("begin", 12, "code", 15);
        // Function<F, T> F表示apply()方法input的类型,T表示apply()方法返回类型
        Map<String, Integer> m2 = Maps.transformValues(m, new Function<Integer, Integer>() {
            public Integer apply(Integer input) {
                if(input>12){
                    return input;
                }else{
                    return input+1;
                }
            }
        });
System.out.println(m2);   //{begin=13, code=15}

(3)set的交集、并集、差集

HashSet<Integer> setA = Sets.newHashSet(1, 2, 3, 4, 5);
HashSet<Integer> setB = Sets.newHashSet(4, 5, 6, 7, 8);

Sets.SetView<Integer> union = Sets.union(setA, setB);
System.out.println("union:");
for (Integer integer : union){
    System.out.println(integer);//union:12345867
}


Sets.SetView<Integer> difference = Sets.difference(setA, setB);
System.out.println("difference:");
for (Integer integer : difference){
    System.out.println(integer); //difference:123
}


Sets.SetView<Integer> intersection = Sets.intersection(setA, setB);
System.out.println("intersection:");
for (Integer integer : intersection){
    System.out.println(integer);
}

(4)map的交集、并集、差集

Map<String, Integer> mapA = Maps.newHashMap();
Map<String, Integer> mapB = Maps.newHashMap();
mapA.put("a", 1);
mapA.put("b", 2);
mapA.put("c", 6);

mapB.put("d", 4);
mapB.put("c", 3);

MapDifference<String, Integer> difference1 = Maps.difference(mapA, mapB);
System.out.println("are qual " + difference1.areEqual());
System.out.println("diff  " + difference1.entriesDiffering());
System.out.println("left " + difference1.entriesOnlyOnLeft());
System.out.println("right" + difference1.entriesOnlyOnRight());
System.out.println("common" + difference1.entriesInCommon());

字符串操作

(1) 连接器Joiner

将集合转换为特定规则的字符串,核心是Joiner类

list->string


List<String> list = Lists.newArrayList();
list.add("a");
list.add("b");
list.add("c");
String result = Joiner.on(",").join(list);
System.out.println("the string is " + result);

map->String

Map<String, String> map1 = Maps.newHashMap();
map1.put("zhangruizhi", "hehe");
map1.put("zhang", "haha");
String resultMap = Joiner.on(",").withKeyValueSeparator("=").join(map1);
System.out.println("the result map is " + resultMap);

连接器Joiner

Joiner joiner = Joiner.on("; ").skipNulls();
return joiner.join("Harry", null, "Ron", "Hermione");


(2) 拆分器Splitter

将字符串转换为特定规则的集合,核心是Splitter类

string->list,可以忽略空格,空行

String s = "192.168.0.1,  192.168.0.2,    192.168.0.3, 192.168.0.4";
List<String> sList = Splitter.on(",").omitEmptyStrings().trimResults().splitToList(s);
System.out.println("the sList is " + sList);

string->map

String mapS = "zhangruizhi=a, zhang=b";
Map<String, String> sMap = Splitter.on(",").withKeyValueSeparator("=").split(mapS);
System.out.println("the s map is " + sMap);

拆分器Splitter

Splitter.on(',')
 
        .trimResults()
 
        .omitEmptyStrings()
 
        .split("foo,bar,,   qux");


字符匹配器CharMatcher

String noControl = CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); //移除control字符
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);
// 只保留数字和小写字母

字符集Charsets

大小写格式CaseFormat

CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, "CONSTANT_NAME")); // returns "constantName"

计时工具

Stopwatch stopwatch = Stopwatch.createStarted();
int sum = 0;
for( int i =0; i< 100; i++){
    sum+=i;
}
long time = stopwatch.elapsed(TimeUnit.MICROSECONDS);

文件操作

主要是Files类

File file = new File("/test.txt");
List<String> listTest = null;
try {
    list = Files.readLines(file, Charsets.UTF_8);
} catch (Exception e) {
}

File from = new File("./test.log");
File to = new File("./newFile.log");
File directory = new File("./.");
try{
    Files.copy(from,to);  //复制文件
    Files.move(from, to); //移动文件
    URL url = Resources.getResource("abc.xml"); //获取classpath根下的abc.xml文件url
}catch (IOException ioe){

}

缓存

Guava Cache适用于:

  • 愿意消耗一些内存空间来提升速度。
  • 你预料到某些键会被查询一次以上。
  • 缓存中存放的数据总量不会超出内存容量。
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
 
        .maximumSize(1000)
 
        .expireAfterWrite(10, TimeUnit.MINUTES)
 
        .removalListener(MY_LISTENER)
 
        .build(
 
            new CacheLoader<Key, Graph>() {
 
                public Graph load(Key key) throws AnyException {
 
                    return createExpensiveGraph(key);
 
                }
 
        });

缓存回收:基于容量的回收、定时回收、基于引用的回收、显式清除


Guava 数学运算

  • Guava Math针对各种不常见的溢出情况都有充分的测试;对溢出语义,Guava文档也有相应的说明;如果运算的溢出检查不能通过,将导致快速失败;
  • Guava Math的性能经过了精心的设计和调优;虽然性能不可避免地依据具体硬件细节而有所差异,但Guava Math的速度通常可以与Apache Commons的MathUtils相比,在某些场景下甚至还有显著提升;
  • Guava Math在设计上考虑了可读性和正确的编程习惯;IntMath.log2(x, CEILING) 所表达的含义,即使在快速阅读时也是清晰明确的。而32-Integer.numberOfLeadingZeros(x – 1)对于阅读者来说则不够清晰。

基本使用

Optional

对null值进行快速失败
Optional<T> 表示可能的null的T类型的引用

Optional.of(T)创建指定引用的Optional实例,若引用为null则快速失败
Optional.absent()创建引用缺失的Optional实例
Optional.fromNullable(T)创建指定引用的Optional实例,若引用为null则表示缺失


 

Preconditions

若干前置条件判断的方法

checkArgument(boolean)检查boolean是否为true,用来检查传递给方法的参数。IllegalArgumentException
checkNotNull(T)检查value是否为null,该方法直接返回value,因此可以内嵌使用checkNotNull。NullPointerException
checkState(boolean)用来检查对象的某些状态。IllegalStateException
checkElementIndex(int index, int size)检查index作为索引值对某个列表、字符串或数组是否有效。index>=0 && index<size *IndexOutOfBoundsException
checkPositionIndex(int index, int size)检查index作为位置值对某个列表、字符串或数组是否有效。index>=0 && index<=size *IndexOutOfBoundsException
checkPositionIndexes(int start, int end, int size)检查[start, end]表示的位置范围对某个列表、字符串或数组是否有效*IndexOutOfBoundsException

参数检查 主要是Preconditions类

String testString = null;
Preconditions.checkArgument(!Strings.isNullOrEmpty(testString), "the testString is null or empty");


String testString1 = null;
Preconditions.checkNotNull(testString1);

 

Ordering
用来构建复杂的比较器,完成集合排序的功能

创建排序器:

 

natural()对可排序类型做自然排序,如数字按大小,日期按先后排序
usingToString()按对象的字符串形式做字典排序[lexicographical ordering]
from(Comparator)把给定的Comparator转化为排序器



链式调用方法:  后面的方法包装了前面的排序器
 

reverse()获取语义相反的排序器
nullsFirst()使用当前排序器,但额外把null值排到最前面。
nullsLast()使用当前排序器,但额外把null值排到最后面。
compound(Comparator)合成另一个比较器,以处理当前排序器中的相等情况。
lexicographical()基于处理类型T的排序器,返回该类型的可迭代对象Iterable<T>的排序器。
onResultOf(Function)对集合中元素调用Function,再按返回值用当前排序器排序。


运用排序器:


 

Throwables:简化异常和错误的传播与检查

Throwables.propagate  



参考:

https://www.cnblogs.com/peida/archive/2013/06/08/3120820.html
https://wizardforcel.gitbooks.io/guava-tutorial/content/1.html

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值