资料
正源:
google/guava: Google core libraries for Java (github.com)
中文教程(翻译的很好)
wizardforcel.gitbooks.io/guava-tutor…
八臂神剑的视频教程
其它资料汇集
《Getting Started with Google Guava Write better, more efficient Java, and have fun doing so by Bejeck B. (z-lib.org).epub》
Utilities
We learned how Guava makes life easier when working with delimited strings using Joiner, Splitter, and the very useful MapJoiner and MapSplitter classes. We also learned about Guava's ability to work with strings using the Charsets, CharMatcher, and Strings classes.
We saw how to make our code more robust and improve debugging with the use of the Preconditions class. In the Objects class, we learned about some useful methods to help with setting default values and creating toString and hashCodemethods. We also saw how to use the ComparisonChain class to make implementing the compareTo method easier.
Optional
Build Optional Instance
- Optional.of(T): T为null会抛出异常
- Optional.absent()
- Optional.fromNullable(T): T允许null
Optional<String> x = Optional.absent();
assertThat(x.or("hello"), is("hello"));
Optional<String> y = Optional.of("hello");
assertThat(y.or("world"), is("hello"));
Common methods
isPresent、get、or(T)、orNull()、asSet
// 两种为可能null值设置默认值的方式
assertThat(Optional.fromNullable(null).or("hello"), is("hello"));
assertThat(MoreObjects.firstNonNull(null, "hello"), is("hello"));
Joiner
basic usage
Joiner.on("#").skipNulls().join(StringList)
Joiner.on("#").useForNulls("default").join(StringList)
- One could pass in an array, iterable, or varargs of any object. The result is built by calling
Object.toString() - Once created, a
Joinerclass is immutable - from package
com.google.common.base
Appendable
The Joiner class can be used with classes that implement the Appendable interface.
- StringBuilder
StringBuilder stringBuilder = new StringBuilder();
Joiner.on("#").useForNulls("default").appendTo(stringBuilder, stringList);
- FileWriter
Joiner.on("#").appendTo(new FileWriter(new File(path)), list);
MapJoiner
Map<String,String> map = Maps.newLinkedHashMap();
// map.put(...)
Joiner.on("#").withKeyValueSeparator("=").join(map);
Spliter
A Splitter class can split on a single character, a fixed string, a java.util.regex.Pattern package, a string representing a regular expression, or a CharMatcher class
Splitter.on('|').omitEmptyStrings().trimResults().split("foo|bar|baz")
Splitteris immutable on creation too- omitEmptyStrings can ignore empty result, trimResults() will trim each element
Split by fixed Length
Splitter.fixedLength(3).splitToList("aaabbbccc")
split by regex
List<String> list = Splitter.on(Pattern.compile("\d+")).omitEmptyStrings().splitToList("1a2b3c");
// result is [a,b,c]
limit
List<String> result = Splitter.on("#").limit(3).splitToList("hello#world#java#google#guava");
// result[2] = "java#googel#guava"
MapSpliter
Splitter.MapSplitter splitter = Splitter.on("#").withKeyValueSeparator("#");
Map map = splitter.trimResults().omitEmptyStrings().split("a=1#b=2")
String Utilities
Guava provides us with some very useful classes that can make working with strings much easier. These classes are:
CharMatcherCharsetsStrings
Charsets
By not specifying the character set that you want the bytes returned in, you will get the default of the system running the code, which could lead to problems if the default character set on the system is not the one you are expecting to deal with.
// wrong demo1: did not specify charset
byte[] bytes = "foobarbaz".getBytes();
// wrong demo2: ince we are using a string to specify the character set definition, we could make a spelling mistake
try{
byte[] bytes = "foobarbaz".getBytes("UTF-8");
}catch (UnsupportedEncodingException e){
// UTF-8 must be supported on the Java platform, so in reality the UnsupportedEncodingException error will never be thrown
}
correct usage:
byte[] bytes2 = "foobarbaz".getBytes(Charsets.UTF_8);
However, In Java 7, there is a
StandardCharsetsclass that also provides static final definitions to the six standard character sets supported on the Java platform.
Strings
// null or empty
Strings.emptyToNull("");
Strings.nullToEmpty(null);
Strings.commonPrefix("Hello", "Hit") //H
Strings.commonSuffix("Hello", "Who") //o
Strings.repeat("Alex", 3); // result is "AlexAlexAlex"
Strings.isNullOrEmpty(null)
Strings.padStart("Alex", 5, 'H'); //HAlex
Strings.padEnd("foo", 6, 'x') // fooxxx, 6 means min length
- It would probably be a good idea to always use the
nullToEmptymethod on any string objects passed as arguments. 6, specifies the minimum length of the returned string and not how many times to append thexcharacter to the original string
CharMatcher
CharMatcher class provides functionality for working with characters based on the presence or absence of a type of character or a range of characters
match line breaks and replace
CharMatcher.breakingWhitespace().replaceFrom(stringWithLineBreaks, " ")
// spans multiple lines and format it to be on one line
match consecutive tabs/spaces and collapse
CharMatcher.whitespace().collapseFrom(tabsAndSpaces, ' ')
CharMatcher.whitespace().trimAndCollapseFrom...
kinds of CharMatcher
- any()
- none()
- digit()
- javaDigit()
- letter()
CharMatcher定义了非常多的子类,用于进行各式各样的匹配。匹配后执行的操作则主要有:remove/retain, collapse, match, count
CharMatcher.JAVA_DIGIT.retainFrom("foo989yxbar234");
// result is 989234
combine matchers
CharMatcher cm = CharMatcher.digit().or(CharMatcher.whitespace())
Preconditions
// bad code
if(someObj == null){
throw new IllegalArgumentException(" someObj must not be null");
}else{
// do something
}
By using preconditions (with static imports)
// This method returns the object if it is not null
Preconditions.checkNotNull(someObj,"someObj must not be null");
Preconditions.checkArgument
Preconditions.checkElementIndex
Preconditions.checkState
MoreObjects
Object utilities methods assist in creating toString and hashCode methods.
note: we use Objects in history version and now most functions are migrated to MoreObjects
toString
@Override
public String toString() {
return MoreObjects.toStringHelper(this).omitNullValues()
.add("version", this.version)
.add("releaseDate", this.releaseDate).toString();
}
firstNonNull
String a = MoreObjects.firstNonNull(null, "defaultValue");
// 等同于下面代码,如果第二个值也是空则抛出空指针异常
return first != null ? first : checkNotNull(second);
generating hash code
@Override
public int hashCode() {
return Objects.hashCode(version, releaseDate);
}
compareTo
the ComparisonChain class will stop making comparisons with the first non-zero result, the only way a zero will be returned is if all comparisons result in a zero.
public int compareTo(Guava o) {
return ComparisonChain.start().compare(this.version, o.version)
.compare(this.releaseDate, o.releaseDate).result();
}
FPS
Guava can add some functional aspects to Java with the Function and Predicate interfaces. The Function interface provides us with the ability to transform objects and the Predicate interface gives us a powerful mechanism for filtering. The Functions and Predicatesclasses also help us write code that is easier to maintain and much easier to change. Suppliers help by providing essential collaborating objects while completely hiding the details of how those objects are created
Function interface
The Function interface contains only two methods:
public interface Function<F, T> extends java.util.function.Function<F, T> {
T apply(@Nullable F input);
boolean equals(@Nullable Object object);
}
A good Function implementation should have no side effects, meaning the object passed as an argument should remain unchanged after the apply method has been called.
Functions
The Functions class contains a handful of useful methods for working with Function instances
forMap
// 通过Map构建Function
Function<String,Object> function = Funcations.forMap(xxMap);
compose
复合函数,通过函数 F(B)=C,F(A)=B构建F(A)=C的函数
public static <A, B, C> Function<A, C> compose(Function<B, C> g, Function<A, ? extends B> f) {
return new FunctionComposition<A, B, C>(g, f);
}
Predicate
The Predicate interface is a functional cousin to the Function interface. note the result type is boolean and there's test() method besides.
public interface Predicate<T> extends java.util.function.Predicate<T> {
boolean apply(@Nullable T input);
default boolean test(@Nullable T input) {
return apply(input);
}
boolean equals(@Nullable Object object);
}
Predicates
and/or/not
The Predicates.and method takes multiple Predicateinstances and returns a single Predicate instance that will return true if all the component Predicateinstances evaluate to true
compose
compose(Predicate predicate, Function<A, ? extends B> function), takes one predicate and one function as parameters.
Supplier
The Supplier interface helps us implement several of the typical creational patterns. When get is called, we could always return the same instance (singleton) or a new instance with each invocation. A Supplier interface also gives you the flexibility to use lazy instantiation by not constructing an instance until the getmethod is called.
public interface Supplier<T> extends java.util.function.Supplier<T> {
T get();
}
Suppliers
memoize
有缓存的Supplier
memoizeWithExpiration
Collections
google-collections --> abandoned and merged into Guava
amazing number of classes from com.google.common.collect which proved Collection Library is really important!
- Classes with useful static methods for lists, maps, and sets
- Range
- Immutable Collections
- Bimaps -> can navigate from values to keys
- Table -> helpful when using a map of maps
- Multimaps -> allow mutiple values with a unique key
- FluentIterable
- Ordering -> enhanced Coparators
FluentIterable
The fluent programming style allows us to chain method calls together, making for a more readable code.
FluentIterable.from
public static <E> FluentIterable<E> from(final Iterable<E> iterable)
得到FluentIterable对象,进而进行流式编程,类同于java8的stream()方法
FluentIterable.filter
The FluentIterable.filter method takes a Predicateas an argument. Then every element is examined and retained if the given Predicate holds true for it. If no objects satisfy the Predicate, an empty Iterable will be returned
Note: Iterable differs from java.util.Iterators which is easy to make mistakes: when you call a Iterator method may affect result of another method as the position point is changed! such as toString, size, contains...
Iterable<Integer> iterable = FluentIterable.from(numbers).filter(new Predicate<Integer>() {
@Override
public boolean apply(@Nullable Integer input) {
return input % 2 == 0;
}
});
assertThat(Iterables.contains(iterable, 2), Is.is(true));
FluentIterable.transform
The FluentIterable.transform method is a mapping operation where Function is applied to each element. This yields a new iterable having the same size as the original one,composed of the transformed objects.
FluentIterable<Integer> transform = FluentIterable.from(numbers).transform(new Function<Integer, Integer>() {
@Nullable
@Override
public Integer apply(@Nullable Integer input) {
return input * 10;
}
});
ImmutableList<Integer> integers = transform.toList();
toList, which returns the final result as List<String>. There are also the toSet, toMap, toSortedList, and toSortedSet methods available. The toMap method considers the elements of the FluentIterable instance to be the keys. Both the toSortedList and toSortedSet methods take a Comparator parameter to specify the order.
Lists
Lists is a utility class for working with the List instances.
new
// init a empty list
ArrayList<Object> objects = Lists.newArrayList();
// init a list with initial values
ArrayList<Integer> integers = Lists.newArrayList(1, 2, 3, 4);
partition
The partitionmethod returns consecutive sublists of the same size, with the case that the last sublist may be smaller sometimes.
Sets
Sets is a utility class for working with Set instances. There are static factory methods for creating HashSets, LinkedHashSets (Set instances that guarantee items stay in the same order as they are added), and TreeSets (items are sorted by their natural order or by a provided Comparator)
note:
SetViewis important to Sets
difference
The Sets.difference method takes two set instance parameters and returns SetView of the elements found in the first set, but not in the second. SetView is a static, abstract inner class of the Sets class and represents an unmodifiable view of a given Set instance. Any elements that exist in the second set but not in the first set are not included.
找出集合1有,而集合2中没有的元素
symmetricDifference
The Sets.symmetricDifference method returns elements that are contained in one set or the other set, but not contained in both
找出集合1和集合2不同元素的合集
intersection
求交集
union
求并集
Maps
While the Maps.uniqueIndex method uses Function to generate keys from the given values, the Maps.asMapmethod does the inverse operation. The Maps.asMapmethod takes a set of objects to be used as keys, and Function is applied to each key object to generate the value for entry into a map instance. There is another method, Maps.toMap, that takes the same arguments with the difference being ImmutableMap is returned instead of a view of the map. The significance of this is that the map returned from the Maps.asMap method would reflect any changes made to the original map, and the map returned from the Maps.toMap method would remain unchanged from changes to the original map.
create
usually we can create empty Map directly by method like:
**Maps.newHashMap()**
we can also create Map from other structures such as Sets,Lists,we can use methods likes uniqueIndex, asMap ...
ImmutableMap<String, Book> map = Maps.uniqueIndex(books, new BookIsbnFunction());
Map<String, Book> stringBookMap = Maps.asMap(isbnSets, new IsbnBookFunction());
Maps.asMap, takes a Set and a Function to build map, and returned a view of the map.
Maps.toMap, takes the same arguments but returned ImmutableMap instead.
transformEntries
uses a Maps.EntryTransformer interface that derives a new value for the same key, based on the key and value from the original map.
transformValues
uses Function that takes the map's original value and transforms it into a new value for the same key in the original map.
Multimaps
it helps when you need associate more than one value with a given key.
by default, the values are stored in private class WrappedSet which extends WrappedCollection implements Set
ArrayListMultimap
ArrayListMulitmap is a map that uses ArrayList (RandomAccessWrappedList exactly) to store the values for the given key.
multimap is not a true map. But if we need typical map behavior, we would use asMap method
HashMultimap
HashMultimap is based on hash tables. Unlike ArrayListMultimap, inserting the same key-value pair multiple times is not supported, thus only distinct key-value pairs are kept.
other implementations
there are three immutable implementations: ImmutableListMultimap, ImmutableMultimap, and ImmutableSetMultimap. There is LinkedHashMultimap, which returns collections for a given key that have the values in the same order as they were inserted. Finally, we have TreeMultimap that keeps the keys and values sorted by their natural order or the order specified by a comparator.
BiMap
he bimap keeps the values unique in the map as well as the keys. inserting a key with a value that already exists in the map will causes IllegalArgumentException to be thrown
BiMap<String,String> biMap = HashBiMap.create();
Although we only take the HashBiMap for example here, there are also implementations of EnumBiMap, EnumHashBiMap, and ImmutableBiMap.
forcePut
The BiMap.forcePutcall will quietly remove the map entry with the same value . if the key is different also, the previous key will be discarded.
inverse
biMap.inverse().get("Jerry")
Table
there are times when a single map is not enough; we need to have a map of maps, thus table collection. A table is a collection that takes two keys, a row, and a column, and maps those keys to a single value.
HashBasedTable
HashBasedTable, which stores data in Map<R, Map<C, V>>
Table views
Range
The Range class allows us to create a specific interval or span of values with defined endpoints, and works with Comparable types.We can create Range objects with a variety of boundary conditions such as openClosed, closedOpen, greaterThan, atLeast, lessThan, and atMost