AndroidAndroid知识Android开发经验谈

Guava for Android 概述

2017-07-11  本文已影响1024人  我叫陆大旭
Guava

Hi~我是Guava

简介

Guava (潘石榴)是一个 Google 的基于java的类库集合的扩展项目,集合、缓存、原始类型、并发库、注解、字符串处理、I / O 等等。

文档地址

https://github.com/google/guava/wiki

项目地址

https://github.com/google/guava

源代码说明

基础工具

1.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
Set<T> asSet() 返回Optional所包含引用的单例不可变集,如果引用存在,返回一个只有单一元素的集合,如果引用缺失,返回一个空集合。

2.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

3.Ordering

创建排序器

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

链式调用方法:通过链式调用,可以由给定的排序器衍生出其它排序器

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

运用排序器:Guava的排序器实现有若干操纵集合或元素值的方法

|方法|描述|另请参见|
|---|---|
|greatestOf(Iterable iterable, int k) |获取可迭代对象中最大的k个元素。 |leastOf|
|isOrdered(Iterable)| 判断可迭代对象是否已按排序器排序:允许有排序值相等的元素。| isStrictlyOrdered|
|sortedCopy(Iterable) |判断可迭代对象是否已严格按排序器排序:不允许排序值相等的元素。| immutableSortedCopy|
|min(E, E)| 返回两个参数中最小的那个。如果相等,则返回第一个参数。 |max(E, E)|
|min(E, E, E, E...) |返回多个参数中最小的那个。如果有超过一个参数都最小,则返回第一个最小的参数。| max(E, E, E, E...)|
|min(Iterable) |返回迭代器中最小的元素。如果可迭代对象中没有元素,则抛出NoSuchElementException。| max(Iterable), min(Iterator), max(Iterator)|

集合

1.不可变集合

关联可变集合和不可变集合

|可变集合接口 |属于JDK还是Guava |不可变版本|
|---|---|
|Collection|JDK |ImmutableCollection|
|List |JDK |ImmutableList|
|Set |JDK |ImmutableSet|
|SortedSet/NavigableSet |JDK |ImmutableSortedSet|
|Map |JDK |ImmutableMap|
|SortedMap |JDK |ImmutableSortedMap|
|Multiset |Guava |ImmutableMultiset|
|SortedMultiset |Guava |ImmutableSortedMultiset|
|Multimap |Guava |ImmutableMultimap|
|ListMultimap |Guava |ImmutableListMultimap|
|SetMultimap |Guava |ImmutableSetMultimap|
|BiMap |Guava |ImmutableBiMap|
|ClassToInstanceMap |Guava |ImmutableClassToInstanceMap|
|Table |Guava |ImmutableTable|

创建方式

1.ImmutableSet.copyOf()

Set<String> sets = new HashSet<>();
sets.add("set obj1");
sets.add("set obj2");
ImmutableSet<String> immutableSet = ImmutableSet.copyOf(sets);
System.out.println(immutableSet.size());

2.ImmutableSet.of()

ImmutableSet<String> immutableSet2 = ImmutableSet.of("a", "b", "c", "a", "d", "a");
System.out.println(immutableSet2.size());

3.ImmutableSet.Builder()

ImmutableSet immutableSet1 = ImmutableSet.builder().add("ImmutableSet obj1").add("ImmutableSet obj2").build();
System.out.println(immutableSet1.size());

2.新集合类型

Multiset

相同于Set可以重复加入数据,但是不像Set有顺序

/**
 * 相同于set可以重复加入,但是不像set有顺序
  */
Multiset multiset = HashMultiset.create();
multiset.add("a");
multiset.add("b");
multiset.add("c");
multiset.add("b");
multiset.add("a");
System.out.println("multiset size:"+multiset.size());
//multiset size:5
Multimap

把一个键映射到多个值。

Multimap<String,String> multimap = HashMultimap.create();
multimap.put("key1","key1 obj1");
multimap.put("key1","key1 obj2");
multimap.put("key1","key1 obj3");

Iterator<String> stringIterator = multimap.get("key1").iterator();
System.out.println("key values:");
while (stringIterator.hasNext()){
    System.out.println(stringIterator.next());
}
/*
key values:
key1 obj3
key1 obj2
key1 obj1
 */

/**
 * 转换视图
 */
Map<String,Collection<String>> map = multimap.asMap();
Iterator<String > stringIterator1 = map.get("key1").iterator();
System.out.println("map key values:");
while (stringIterator1.hasNext()){
    System.out.println(stringIterator1.next());
}
/*
map key values:
key1 obj3
key1 obj2
key1 obj1
 */
BiMap

双向映射

BiMap<String, Integer> userIds = HashBiMap.create();
userIds.put("User1",1);
userIds.put("User2",2);
userIds.put("User3",3);
userIds.put("User4",4);
String userForId = userIds.inverse().get(2);
System.out.println(userForId);
Table

有两个支持所有类型的键:”行”和”列。

HashBasedTable hashBasedTable = HashBasedTable.create();
hashBasedTable.put("row1","column1","row1+column1:value");
hashBasedTable.put("row1","column2","row1+column2:value");
hashBasedTable.put("row2","column1","row2+column1:value");
hashBasedTable.put("row3","column2","row2+column2:value");
Map<String,String> hashBasedTableRowMap = hashBasedTable.row("row1");
Iterator<String> iterator = hashBasedTableRowMap.keySet().iterator();
while (iterator.hasNext()){
    String column = iterator.next();
    String value = hashBasedTableRowMap.get(column);
    System.out.println("column:"+column + "  value:"+ value);
}
/*
column:column1  value:row1+column1:value
column:column2  value:row1+column2:value
*/
ClassToInstanceMap

特殊的Map:它的键是类型,而值是符合键所指类型的对象。

ClassToInstanceMap<Number> numberDefaults= MutableClassToInstanceMap.create();
numberDefaults.putInstance(Integer.class, Integer.valueOf(0));
RangeSet

描述了一组不相连的、非空的区间。
关于区间的概念后面会解释。

RangeSet<Integer> rangeSet = TreeRangeSet.create();
rangeSet.add(Range.closed(1, 10)); // {[1,10]}
System.out.println(rangeSet.asRanges().toString());
rangeSet.add(Range.closedOpen(11, 15));//不相连区间:{[1,10], [11,15)}
System.out.println(rangeSet.asRanges().toString());
rangeSet.add(Range.closedOpen(15, 20)); //相连区间; {[1,10], [11,20)}
System.out.println(rangeSet.asRanges().toString());
rangeSet.add(Range.openClosed(0, 0)); //空区间; {[1,10], [11,20)}
System.out.println(rangeSet.asRanges().toString());
rangeSet.remove(Range.open(5, 10)); //分割[1, 10]; {[1,5], [10,10], [11,20)}
System.out.println(rangeSet.asRanges().toString());

/**
 * RangeSet最基本的操作,判断RangeSet中是否有任何区间包含给定元素。
 */
boolean isContains = rangeSet.contains(1);
System.out.println("isContains:"+isContains);

/**
 * 返回包含给定元素的区间;若没有这样的区间,则返回null。
 */
Range<Integer> range = rangeSet.rangeContaining(1);
System.out.println("range:"+range);

3.集合工具类

Iterables

|方法|描述|备注|
|---|---|
|concat(Iterable<Iterable>) |串联多个iterables的懒视图* |concat(Iterable...)|
|frequency(Iterable, Object) |返回对象在iterable中出现的次数 |与Collections.frequency (Collection, Object)比较;Multiset|
|partition(Iterable, int) |把iterable按指定大小分割,得到的子集都不能进行修改操作 |Lists.partition(List, int);paddedPartition(Iterable, int)|
|getFirst(Iterable, T default) |返回iterable的第一个元素,若iterable为空则返回默认值 |与Iterable.iterator(). next()比较;FluentIterable.first()|
|getLast(Iterable) |返回iterable的最后一个元素,若iterable为空则抛出NoSuchElementException |getLast(Iterable, T default);FluentIterable.last()|
|elementsEqual(Iterable, Iterable) |如果两个iterable中的所有元素相等且顺序一致,返回true |与List.equals(Object)比较|
|unmodifiableIterable(Iterable) |返回iterable的不可变视图 |与Collections. unmodifiableCollection(Collection)比较|
|limit(Iterable, int) |限制iterable的元素个数限制给定值 |FluentIterable.limit(int)|
|getOnlyElement(Iterable) |获取iterable中唯一的元素,如果iterable为空或有多个元素,则快速失败 |getOnlyElement(Iterable, T default)|

FluentIterable

把自己拷贝到不可变集合

转换的类型 方法
ImmutableSet toImmutableSet()
ImmutableSortedSet toImmutableSortedSet(Comparator)
Lists、Sets、Maps、Multisets、Multimaps、Tables

都有各自的静态类方法

缓存

基本使用
LoadingCache<String, String> stringStringLoadingCache = CacheBuilder.newBuilder().build(new CacheLoader<String, String>() {
    @Override
    public String load(String key) throws Exception {
        if(key.equals("key2")){
            System.out.println("load key2");
            return "values2";
        }
        System.out.println("load else");
        return "values0";
    }
    public Map<String, String> loadAll(Iterable<? extends String> keys) throws Exception {
        System.out.println("loadAll:"+keys.toString());
        Map<String,String> loadAll = new HashMap<String, String>();
        Iterator keysIt = keys.iterator();
        while (keysIt.hasNext()){
            String key = (String) keysIt.next();
            loadAll.put(key,key+":::values");
        }
        return loadAll;
    }


});
stringStringLoadingCache.put("key1","value1");
String values1 = stringStringLoadingCache.getUnchecked("key1");
System.out.println(values1);
String values2 = stringStringLoadingCache.getUnchecked("key2");
System.out.println(values2);
String values3 = stringStringLoadingCache.getUnchecked("key3");
System.out.println(values3);
String values11 = stringStringLoadingCache.getUnchecked("key1");
System.out.println(values11);
Set<String> keySet = Sets.newSet("key4");
try {
    ImmutableMap<String, String> immutableMap = stringStringLoadingCache.getAll(keySet);
    System.out.println(immutableMap.toString());
} catch (ExecutionException e) {
    e.printStackTrace();
}
/*
value1
load key2
values2
load else
values0
value1
loadAll:[key4]
{key4=key4:::values}
 */

1.创建的CacheLoader并简单的实现 V load(K key)。
2.获取元素用get()或getUnchecked()。
3.getAll()会调用loadAll()方法,从而增加效率。
4.put()显示插入数据。

缓存回收
统计

CacheBuilder.recordStats():开启统计。
Cache.stats():返回CacheStats统计内容。
CacheStats.hitRate():缓存命中率;
CacheStats.averageLoadPenalty():加载新值的平均时间,单位为纳秒;
CacheStats.evictionCount():缓存项被回收的总数,不包括显式清除

字符串处理

连接器
Joiner joiner = Joiner.on(":").skipNulls();
String string = joiner.join("AAA", null, "BBB", "CCC");
String string0 = joiner.join(Arrays.asList("DDD", "EEEE"));
System.out.println(string);
System.out.println(string0);
拆分器
Iterable<String> stringSet= Splitter.on(',')
        //.limit(3)
        .omitEmptyStrings()
        .trimResults()
        .split("a,b,,c,d,e,f");
Iterator<String> iterator = stringSet.iterator();
while (iterator.hasNext()){
    System.out.println(iterator.next());
}
方法 描述 范例
Splitter.on(char) 按单个字符拆分 Splitter.on(‘;’)
Splitter.on(CharMatcher) 按字符匹配器拆分 Splitter.on(CharMatcher.BREAKING_WHITESPACE)
Splitter.on(String) 按字符串拆分 Splitter.on(“, “)
Splitter.on(Pattern)
Splitter.onPattern(String)
按正则表达式拆分 Splitter.onPattern(“\r?\n”)
Splitter.fixedLength(int) 按固定长度拆分;最后一段可能比给定长度短,但不会为空。 Splitter.fixedLength(3)
方法 描述
omitEmptyStrings() 从结果中自动忽略空字符串
trimResults() 移除结果字符串的前导空白和尾部空白
trimResults(CharMatcher) 给定匹配器,移除结果字符串的前导匹配字符和尾部匹配字符
limit(int) 限制拆分出的字符串数量

原生类型处理

原生类型 Guava工具类
byte Bytes, SignedBytes, UnsignedBytes
short Shorts
int Ints, UnsignedInteger, UnsignedInts
long Longs, UnsignedLong, UnsignedLongs
float Floats
double Doubles
char Chars
boolean Booleans
方法签名 描述 类似方法 可用性
List<Wrapper> asList(prim… backingArray) 把数组转为相应包装类的List Arrays.asList 符号无关*
prim[] toArray(Collection<Wrapper> collection) 把集合拷贝为数组,和collection.toArray()一样线程安全 Collection.toArray() 符号无关
prim[] concat(prim[]… arrays) 串联多个原生类型数组 Iterables.concat 符号无关
boolean contains(prim[] array, prim target) 判断原生类型数组是否包含给定值 Collection.contains 符号无关
int indexOf(prim[] array, prim target) 给定值在数组中首次出现处的索引,若不包含此值返回-1 List.indexOf 符号无关
int lastIndexOf(prim[] array, prim target) 给定值在数组最后出现的索引,若不包含此值返回-1 List.lastIndexOf 符号无关
prim min(prim… array) 数组中最小的值 Collections.min 符号相关*
prim max(prim… array) 数组中最大的值 Collections.max 符号相关
String join(String separator, prim… array) 把数组用给定分隔符连接为字符串 Joiner.on(separator).join 符号相关
Comparator<prim[]> lexicographicalComparator() 按字典序比较原生类型数组的Comparator Ordering.natural().lexicographical() 符号相关
int[] ints= {1,2,3};
int[] ints0= {8,9,0};

List<Integer> integerList = Ints.asList(ints);
for (Integer integerListItem:integerList){
    System.out.println(integerListItem);
}
//123
System.out.println("================");

int[] ints1 = Ints.toArray(integerList);
for (int i :ints1){
    System.out.println(i);
}
//123
System.out.println("================");

int[] ints2 = Ints.concat(ints,ints0);
for (int i :ints2){
    System.out.println(i);
}
//123890
System.out.println("================");

boolean isContains = Ints.contains(ints,2);
System.out.println(isContains);
//true
System.out.println("================");

int index = Ints.indexOf(ints,0);
System.out.println(index);
//-1
System.out.println("================");

int index1 = Ints.indexOf(ints,1);
System.out.println(index1);
//0
System.out.println("================");

int max = Ints.max(ints2);
System.out.println(max);
//9
System.out.println("================");

int min = Ints.min(ints2);
System.out.println(min);
//1
System.out.println("================");

String string = Ints.join(";",ints);
System.out.println(string);
//1;2;3
System.out.println("================");

int c = Ints.constrainToRange(-3,0,9);
System.out.println(c);
//0
System.out.println("================");

区间

区间的构建
区间描述 方法
(a..b) open(C, C)
[a..b] closed(C, C)
[a..b) closedOpen(C, C)
(a..b] openClosed(C, C)
(a..+∞) greaterThan(C)
[a..+∞) atLeast(C)
(-∞..b) lessThan(C)
(-∞..b] atMost(C)
(-∞..+∞) all()
区间描述 方法
有界区间 range(C, BoundType, C, BoundType)
无上界区间:((a..+∞) 或[a..+∞)) downTo(C, BoundType)
无下界区间:((-∞..b) 或(-∞..b]) upTo(C, BoundType)

BoundType类型:BoundType.CLOSED或BoundType.OPEN

特别描述
区间运算
Range range0 = Range.closedOpen(0,4);//[0,4)
Range range1 = Range.openClosed(3,5);//(3,5]
System.out.println(range0.toString());
//[0..4)
System.out.println(range1.toString());
//(3..5]

/**
 * 判断是否是空区间
 */
boolean isEmpty = range0.isEmpty();
System.out.println("isEmpty:"+isEmpty);
//isEmpty:false

/**
 * 判断是否有上限
 */
boolean hasLowerBound = range0.hasLowerBound();
boolean hasUpperBound = range0.hasUpperBound();
System.out.println("hasLowerBound:"+hasLowerBound +"   hasUpperBound:"+hasUpperBound);
//hasLowerBound:true   hasUpperBound:true

/**
 * 返回区间边界类型,CLOSED或OPEN;如果区间没有对应的边界,抛出IllegalStateException;
 */
BoundType lowerBoundType = range0.lowerBoundType();
BoundType upperBoundType = range0.upperBoundType();
System.out.println("hasLowerBound:"+hasLowerBound +"   hasUpperBound:"+hasUpperBound);
//hasLowerBound:true   hasUpperBound:true

/**
 * 返回区间的端点值
 */
Comparable<Integer> lowerEndpoint = range0.lowerEndpoint();
Comparable<Integer> upperEndpoint = range0.upperEndpoint();
System.out.println("lowerEndpoint:"+lowerEndpoint +"   upperEndpoint:"+upperEndpoint);
//lowerEndpoint:0   upperEndpoint:4

/**
 * 区间之间的包含关系
 */
boolean encloses = range0.encloses(range1);
System.out.println("encloses:"+encloses);
//encloses:false

/**
 * 判断区间是否是相连
 */
boolean isConnected = range0.isConnected(range1);
System.out.println("isConnected:"+isConnected);
//isConnected:true

/**
 * 交集:既包含于第一个区间,又包含于另一个区间的最大区间
 */
Range range2 = range0.intersection(range1);
System.out.println("intersection:"+range2.toString());
//intersection:(3..4)


/**
 * 跨区间:同时包括两个区间的最小区间
 */
Range rang3 = range0.span(range1);
System.out.println("span:"+rang3.toString());
//span:[0..5]

离散域
ImmutableSortedSet set = ContiguousSet.create(range0, DiscreteDomain.integers());
        Iterator iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
//0 1 2 3

散列

事件总线

EventBus 事件发布/订阅轻量级框架

数学运算

溢出检查运算

主要针对三种整数运算,int,long和BigInteger。

try {
    /**
     * 这里相加不会报错
     */
    int i0 = Integer.MAX_VALUE + 2;
    System.out.println(i0);
    /**
     * 这里会抛出异常,java.lang.ArithmeticException: overflow
     */
    int i1 = IntMath.checkedAdd(Integer.MAX_VALUE, 2);

} catch (Exception e) {
    e.printStackTrace();
}

IntMath和LongMath有相应的方法

实数运算

IntMath、LongMath和BigIntegerMath提供相应的运算方法
RoundingMode模式:

方法(以IntMath为例)

浮点数运算

并发

暂略

反射

暂略

I/O

暂略

散列

暂略

图形

暂略

项目地址

https://github.com/iamludaxu/ae/tree/master/app/src/test/java/gift/witch/android/ae/guava

参考

Google Guava官方教程(中文版)
Guava User Guide

上一篇 下一篇

猜你喜欢

热点阅读