一、FluentIterable
1、作用:提供对集合的流式/函数式编程风格操作,在JDK1.8后提供了stream,FluentIterable已经无其优势了。但是GoogleGuava依然没有将其废弃,目的是提供习惯使用guava collections的研发人员。
代码示例:
package com.mzj.guava.collections;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
public class FluentIterableExampleTest {
public FluentIterable<String> build(){
ArrayList<String> list = Lists.newArrayList("A","BBBB","C","DDD");
return FluentIterable.from(list);
}
@Test
public void testFilter(){
FluentIterable<String> lists = build();
FluentIterable<String> listsResult = lists.filter(e->e!= null && e.length()>1);
System.out.println(listsResult);
assertThat(listsResult.size(),equalTo(2));
}
@Test
public void testCycle(){
FluentIterable<String> lists = build();
FluentIterable<String> cycle = lists.cycle().limit(20);//cycle是循环,相当于JAVA8的无限流generate
System.out.println(cycle);
}
@Test
public void testTransformAndConcat(){
FluentIterable<String> fit = build();
List<Integer> list = Lists.newArrayList(1,2);
FluentIterable<Integer> result = fit.transformAndConcat(e ->list);//等价于java8的flatMap效果
System.out.println(result);
}
}
运行结果:
二、Lists
方法汇总
No | 方法及说明 |
1 | List<E> asList(@Nullable E first, E[] rest) List<E> asList(@Nullable E first, @Nullable E second, E[] rest) 将array转化为List,并在list头部插入值,不支持基本类型array |
2 | List<List<B>> cartesianProduct(List… lists) List<List<B>> cartesianProduct(List<? extends List<? extends B>> lists) 计算多个list笛卡尔乘积 |
3 | ImmutableList<Character> charactersOf(String string) List<Character> charactersOf(CharSequence sequence) Stirng或CharSequence转List<Character>,CharSequence接口常见实现类StringBuilder |
4 | ArrayList<E> newArrayList() -> 底层依赖于JDK new ArrayList()实现,JDK默认容量是10,扩容方式为 ((旧容量 * 3) / 2) + 1 ArrayList<E> newArrayList(E… elements) -> guava首先进行容量初始化计算,计算方式为 5L + elements数目 + (elements数目 / 10), 然后通过JDK ArrayList(int initialCapacity)初始化 ArrayList<E> newArrayList(Iterable<? extends E> elements) ArrayList<E> newArrayList(Iterator<? extends E> elements) 初始化ArrayList |
5 | ArrayList<E> newArrayListWithCapacity(int initialArraySize) 初始化指定容量大小的ArrayList,其中容量指ArrayList底层依赖的数组的length属性值,常用于提前知道ArrayList大小的情况的初始化 |
6 | ArrayList<E> newArrayListWithExpectedSize(int estimatedSize) 初始化预定容量大小的ArrayList,返回的list的实际容量为5L + estimatedSize + (estimatedSize / 10),常用于不确定ArrayList大小的情况的初始化 |
7 | LinkedList<E> newLinkedList() LinkedList<E> newLinkedList(Iterable<? extends E> elements) 初始化LinkedList |
8 | CopyOnWriteArrayList<E> newCopyOnWriteArrayList() CopyOnWriteArrayList<E> newCopyOnWriteArrayList(Iterable<? extends E> elements) 初始化CopyOnWriteArrayList |
9 | List<List<T>> partition(List<T> list, int size) 分割list,分割后每个list的元素个数为size |
10 | List<T> reverse(List<T> list) 反转list |
11 | List<T> transform(List<F> fromList, Function<? super F, ? extends T> function) 转化list,不建议使用,建议使用java8 Stream的map操作,更方便 |
1、cartesianProduct
作用:笛卡尔积相关方法
@Test
public void test(){
List<List<String>> result = Lists.cartesianProduct(Lists.newArrayList("1","2"),
Lists.newArrayList("A","B"));
System.out.println(result);
}
输出:
2、transform
作用:转换方法
@Test
public void testTransform(){
ArrayList<String> sourceList = Lists.newArrayList("Scala","Guava","Lists");
Lists.transform(sourceList,e->e.toUpperCase()).forEach(System.out::println);
}
输出:
3、newArrayListWithCapacity
作用:new一个ArrayList使其具有初始化的大小
4、newArrayListWithExpectedSize
作用:new一个ArrayList,使其初始大小为:
其中arraySize是newArrayListWithExpectedSize方法的参数
5、reverse
作用:反转
@Test
public void testReverse(){
ArrayList<String> list = Lists.newArrayList("1","2","3");
List<String> result = Lists.reverse(list);
System.out.println(result);
}
结果:
6、partition
作用:分区
@Test
public void testPartition(){
ArrayList<String> list = Lists.newArrayList("1","2","3","4","5");
List< List<String>> result = Lists.partition(list,2);//每个分区大小
System.out.println(result);
}
输出:
其他测试代码:
public class ListsTest {
@Test
public void asListTest() {
/*asList可用来将array转化为List,并在list头部插入值,不支持基本类型array*/
int[] array = new int[]{1, 2, 3};
List<Integer> list = Lists.asList(4, ArrayUtils.toObject(array));
assertThat(list, contains(4, 1, 2, 3));
/*list转array, 必须使用toArray(T[] array), 传入的是类型完全一样的数组,大小为list.size()
* 如果使用无参toArray()方法,只能转成object[], 无法进行类型转换,强转会报ClassCastException*/
Integer[] array2 = list.toArray(new Integer[list.size()]);
list = Lists.asList(8, 9, array2);
assertThat(list, contains(8, 9, 4, 1, 2, 3));
}
@Test
public void cartesianProductTest() {
/*cartesianProduct用来计算若干个List的笛卡尔乘积*/
List<Integer> list1 = Lists.newArrayList(1, 2, 3);
List<Integer> list2 = Lists.newArrayList(5, 6, 7, 8);
List<Integer> list3 = Lists.newArrayList(0, 9);
List<List<Integer>> cartesianResult = Lists.cartesianProduct(list1, list2, list3);
System.out.println(cartesianResult);
assertThat(cartesianResult, hasSize(24));
/*嵌套的List也可以直接作为参数计算笛卡尔乘积*/
List<List<Integer>> list = Lists.newArrayList(Lists.newArrayList(1, 2), Lists.newArrayList(5, 6));
List<List<Integer>> cartesianResult1 = Lists.cartesianProduct(list);
System.out.println(cartesianResult1);
}
@Test
public void charactersOfTest() {
/*charactersOf(String string)*/
List<Character> characters = Lists.charactersOf("zhuoli");
assertThat(characters, contains('z', 'h', 'u', 'o', 'l', 'i'));
/*charactersOf(CharSequence sequence)*/
characters = Lists.charactersOf(new StringBuilder("Michael"));
assertThat(characters, contains('M', 'i', 'c', 'h', 'a', 'e', 'l'));
}
@Test
public void newArrayListTest() {
/*无参构造函数*/
List<Integer> list = Lists.newArrayList();
assertThat(list, empty());
list = Lists.newArrayList(1, 2, 3);
assertThat(list, contains(1, 2, 3));
/*newArrayList(Iterable elements)*/
list = Lists.newArrayList(Sets.newLinkedHashSet(1, 2, 4));
assertThat(list, contains(1, 2, 4));
}
@Test
public void newArrayListWithCapacityTest() throws NoSuchFieldException, IllegalAccessException {
/*newArrayListWithCapacity直接指定返回的arrayList容量*/
List<Integer> list0 = Lists.newArrayListWithCapacity(10);
int capacity0 = getCapacity(list0);
assertEquals(10, capacity0);
/*newArrayListWithExpectedSize返回的arrayList容量为 5L + arraySize + (arraySize / 10)*/
List<Integer> list1 = Lists.newArrayListWithExpectedSize(10);
int capacity1 = getCapacity(list1);
assertEquals(16, capacity1);
}
@Test
public void newLinkedListTest() {
List<Integer> list0 = Lists.newLinkedList();
assertThat(list0, empty());
/*newLinkedList(Iterable elements)*/
List<Integer> list1 = Lists.newLinkedList(Sets.newLinkedHashSet(3, 4, 5));
assertThat(list1, contains(3, 4, 5));
}
@Test
public void CopyOnWriteArrayListTest() {
List<Integer> list0 = Lists.newCopyOnWriteArrayList();
assertThat(list0, empty());
/*newCopyOnWriteArrayList(Iterable elements)*/
List<Integer> list1 = Lists.newCopyOnWriteArrayList(Sets.newLinkedHashSet(3, 4, 5));
assertThat(list1, contains(3, 4, 5));
}
@Test
public void partitionTest() {
List<Integer> list = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7);
List<List<Integer>> partitionList = Lists.partition(list, 2);
System.out.println(partitionList);
assertEquals(4, partitionList.size());
}
@Test
public void reverseTest() {
List<String> names = Lists.newArrayList("John", "Adam", "Jane");
List<String> reversed = Lists.reverse(names);
assertThat(reversed, contains("Jane", "Adam", "John"));
}
@Test
public void transformTest() {
/*transform用来转化list, 建议直接使用Java8的Stream*/
List<String> list = Lists.newArrayList("this", "is", "test");
List<String> upperList = Lists.transform(list, new Function<String, String>() {
@Override
public String apply(@Nullable String s) {
return s.toUpperCase();
}
});
System.out.println(list);
List<String> upperList1 = list.stream().map(String::toUpperCase).collect(Collectors.toList());
assertEquals(upperList, upperList1);
}
@Test
public void removeDuplicatesFromList() {
/*去除list重复元素*/
List<Character> chars = Lists.newArrayList('h', 'e', 'l', 'l', 'o');
assertEquals(5, chars.size());
List<Character> result = ImmutableSet.copyOf(chars).asList();
assertThat(result, contains('h', 'e', 'l', 'o'));
/*通过Java8 Stream去除重复元素, 建议使用*/
chars = chars.stream().distinct().collect(Collectors.toList());
assertEquals(result, chars);
}
/*通过反射获取list内部实现elementData的length属性*/
private int getCapacity(List<Integer> list) throws NoSuchFieldException, IllegalAccessException {
Field f = ArrayList.class.getDeclaredField("elementData");
f.setAccessible(true);
Object[] elementData = (Object[]) f.get(list);
return elementData.length;
}
}
三、Sets
说明:提供了交集、并集、差集等功能
方法汇总
No | 方法及说明 |
1 | Set<List<B>> cartesianProduct(List<? extends Set<? extends B>> sets) Set<List<B>> cartesianProduct(Set… sets) 求多个Set的笛卡尔乘积 |
2 | Set<Set<E>> combinations(Set<E> set, final int size) 求Set的size组合,数学上的公式为 n! / r! * (n – r)! |
3 | Sets.SetView<E> difference(final Set<E> set1, final Set<?> set2) 求set1与set2的差集,返回的是一个Set视图,不支持插入和删除操作 |
4 | Sets.SetView<E> intersection(final Set<E> set1, final Set<?> set2) 求set1与set2的交集,返回的是一个Set视图,不支持插入和删除操作 |
5 | Set<E> newConcurrentHashSet() Set<E> newConcurrentHashSet(Iterable<? extends E> elements) ConcurrentHashSet初始化 |
6 | CopyOnWriteArraySet<E> newCopyOnWriteArraySet() CopyOnWriteArraySet<E> newCopyOnWriteArraySet(Iterable<? extends E> elements) CopyOnWriteArraySet初始化 |
7 | HashSet<E> newHashSet() HashSet<E> newHashSet(E… elements) HashSet<E> newHashSet(Iterable<? extends E> elements) HashSet<E> newHashSet(Iterator<? extends E> elements) HashSet初始化 |
8 | LinkedHashSet<E> newLinkedHashSet() LinkedHashSet<E> newLinkedHashSet(Iterable<? extends E> elements) LinkedHashSet初始化 |
9 | HashSet<E> newHashSetWithExpectedSize(int expectedSize) 初始化一个存在初始容量的HashSet,HashSet底层依赖于HashMap,expectedSize用于确定HashMap底层bucket数组的初始化容量(bucket数组容量总为2的指数幂),比如expectedSize为14,其实底层bucket数组初始化容量为16(大于14的最小2的指数幂) |
10 | LinkedHashSet<E> newLinkedHashSetWithExpectedSize(int expectedSize) 初始化一个存在初始容量的LinkedHashSet,原理同上 |
11 | TreeSet<E> newTreeSet() TreeSet<E> newTreeSet(Comparator<? super E> comparator) TreeSet<E> newTreeSet(Iterable<? extends E> elements) 初始化TreeSet |
12 | Sets.SetView<E> union(final Set<? extends E> set1, final Set<? extends E> set2) |
13 | Set<E> filter(Set<E> unfiltered, com.google.common.base.Predicate<? super E> predicate) Set过滤 SortedSet<E> filter(SortedSet<E> unfiltered, com.google.common.base.Predicate<? super E> predicate) SortedSet(如LinkedHashSet)过滤 NavigableSet<E> filter(NavigableSet<E> unfiltered, com.google.common.base.Predicate<? super E> predicate) NavigableSet(如TreeSet)过滤 也可以使用java8的Stream fielter操作,也非常方便 java8 Stream的map操作 |
14 | powerSet 返回给定集合的所有子集 |
1、create相关接口
@Test
public void testCreate(){
HashSet<Integer> set = Sets.newHashSet(1,2,3,4);
System.out.println(set.size());
ArrayList<Integer> integers = Lists.newArrayList(1, 1, 2, 3);
System.out.println(integers.size());
HashSet<Integer> integers1 = Sets.newHashSet(integers);
System.out.println(integers1.size());
}
2、cartesianProduct
作用:笛卡尔积
@Test
public void testCartesianProduct(){
Set<List<Integer>> set = Sets.cartesianProduct(Sets.newHashSet(1, 2), Sets.newHashSet(3, 4));
System.out.println(set);
}
3、combinations
作用:求Set的size组合,数学上的公式为 n! / r! * (n – r)!
@Test
public void testCombinations(){
Set<Integer> set = Sets.newHashSet(1, 2, 3, 4, 5);
Set<Set<Integer>> result = Sets.combinations(set, 3);
result.forEach(System.out::println);
}
4、powerSet
作用:返回给定集合的所有子集
@Test
public void testPowerSet(){
Set<Integer> set = Sets.newHashSet(1, 2);
Set<Set<Integer>> powerSet = Sets.powerSet(set);
powerSet.forEach(System.out::println);
}
其他测试代码:
public class SetsTest {
@Test
public void cartesianProductTest() {
List<Set<Integer>> setList = Lists.newArrayList();
setList.add(Sets.newHashSet(1, 2));
setList.add(Sets.newHashSet(3, 6, 7));
Set<List<Integer>> result = Sets.cartesianProduct(setList);
System.out.println(result);
assertEquals(6, result.size());
}
@Test
public void cartesianProductTest1() {
Set<Integer> set1 = Sets.newHashSet(1, 2);
Set<Integer> set2 = Sets.newHashSet(3, 6, 7);
Set<List<Integer>> result = Sets.cartesianProduct(set1, set2);
System.out.println(result);
assertEquals(6, result.size());
}
@Test
public void combinationsTest() {
/*求组合结果 n! / r! * (n - r)!*/
Set<Integer> set = Sets.newHashSet(1, 2, 3, 4, 5);
Set<Set<Integer>> result = Sets.combinations(set, 2);
result.forEach(System.out::println);
assertEquals(10, result.size());
}
@Test
public void differenceTest() {
/*求差集,返回结果Set是一个视图,不支持插入、删除操作*/
Set<Character> first = Sets.newHashSet('a', 'b', 'c');
Set<Character> second = Sets.newHashSet('b', 'c', 'd');
Set<Character> result = Sets.difference(first, second);
System.out.println(result);
result = Sets.difference(second, first);
System.out.println(result);
}
@Test
public void filterTest() {
Set<Integer> set0 = Sets.newHashSet(1, 2, 3, 4, 5, 6);
Set<Integer> filterResult0 = Sets.filter(set0, ele -> ele % 2 == 0);
assertThat(filterResult0, containsInAnyOrder(2, 4, 6));
Set<Integer> set1 = Sets.newLinkedHashSet(Lists.newArrayList(1, 2, 3, 4, 5, 6));
Set<Integer> filterResult1 = Sets.filter(set1, ele -> ele % 2 == 1);
assertThat(filterResult1, contains(1, 3, 5));
Set<Integer> set2 = Sets.newTreeSet(Lists.newArrayList(1, 2, 3, 4, 5, 6));
Set<Integer> filterResult2 = Sets.filter(set2, ele -> ele % 2 == 1);
assertThat(filterResult2, contains(1, 3, 5));
}
@Test
public void intersectionTest() {
/*求交集,返回结果Set是一个视图,不支持插入、删除操作*/
Set<Character> first = ImmutableSet.of('a', 'b', 'c');
Set<Character> second = ImmutableSet.of('b', 'c', 'd');
Set<Character> intersection = Sets.intersection(first, second);
assertThat(intersection, containsInAnyOrder('b', 'c'));
}
@Test
public void newConcurrentHashSetTest() {
Set<Integer> set = Sets.newConcurrentHashSet();
assertTrue(set.isEmpty());
set = Sets.newConcurrentHashSet(Lists.newArrayList(1, 2, 3));
assertThat(set, containsInAnyOrder(1, 2, 3));
}
@Test
public void newCopyOnWriteArraySetTest() {
Set<Integer> set = Sets.newCopyOnWriteArraySet();
assertTrue(set.isEmpty());
set = Sets.newCopyOnWriteArraySet(Lists.newArrayList(1, 2, 3));
assertThat(set, containsInAnyOrder(1, 2, 3));
}
@Test
public void newHashSetTest() {
/*HashSet构造方法*/
Set<Integer> set = Sets.newHashSet();
assertTrue(set.isEmpty());
set = Sets.newHashSet(1, 2, 3);
assertThat(set, containsInAnyOrder(1, 2, 3));
set = Sets.newHashSet(Lists.newArrayList(4, 5, 6));
assertThat(set, containsInAnyOrder(4, 5, 6));
set = Sets.newHashSet(Lists.newArrayList(0, 9, 8).iterator());
assertThat(set, containsInAnyOrder(0, 9, 8));
}
@Test
public void newHashSetWithExpectedSizeTest() {
/*Set底层依赖于Map实现,newHashSetWithExpectedSize传入的数值为Map底层bucket数组大小,JDK实现为2的指数幂,所以下面代码底层Map的bucket数组实际大小为16*/
Set<Integer> set = Sets.newHashSetWithExpectedSize(14);
assertTrue(set.isEmpty());
}
@Test
public void newLinkedHashSetTest() {
/*HashSet构造方法*/
Set<Integer> set = Sets.newLinkedHashSet();
assertTrue(set.isEmpty());
set = Sets.newLinkedHashSet(Lists.newArrayList(1, 2, 3));
assertThat(set, containsInAnyOrder(1, 2, 3));
}
@Test
public void newLinkedHashSetWithExpectedSizeTest() {
/*Set底层依赖于Map实现,newLinkedHashSetWithExpectedSize传入的数值为Map底层bucket数组大小,JDK实现为2的指数幂,所以下面代码底层Map的bucket数组实际大小为16*/
Set<Integer> set = Sets.newLinkedHashSetWithExpectedSize(14);
assertTrue(set.isEmpty());
}
@Test
public void newTreeSetTest() {
Set<Integer> set = Sets.newTreeSet();
assertTrue(set.isEmpty());
set = Sets.newTreeSet(Lists.newArrayList(1, 2, 3));
assertThat(set, containsInAnyOrder(1, 2, 3));
}
@Test
public void unionTest() {
/*求并集*/
Set<Character> first = ImmutableSet.of('a', 'b', 'c');
Set<Character> second = ImmutableSet.of('b', 'c', 'd');
Set<Character> intersection = Sets.union(first, second);
assertThat(intersection, containsInAnyOrder('a', 'b', 'c', 'd'));
}
}
四、Maps
方法汇总:
No | 方法及说明 |
1 | Map<K, V> asMap(Set<K> set, Function<? super K, V> function) SortedMap<K, V> asMap(SortedSet<K> set, Function<? super K, V> function) NavigableMap<K, V> asMap(NavigableSet<K> set, Function<? super K, V> function) Set转Map,函数式接口用于通过Set的元素值获取Map的value值 |
2 | MapDifference<K, V> difference(Map<? extends K, ? extends V> left, Map<? extends K, ? extends V> right) SortedMapDifference<K, V> difference(SortedMap<K, ? extends V> left, Map<? extends K, ? extends V> right) 通过Map的key计算left和right的差值,MapDifference包含 left – right、right – left及left与right相交这三部分信息 |
3 | BiMap<K, V> filterEntries(BiMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) Map<K, V> filterEntries(Map<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) SortedMap<K, V> filterEntries(SortedMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) NavigableMap<K, V> filterEntries(NavigableMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) 通过Map的Entry(key和value)过滤Map,函数式接口为通过Entry产生的过滤条件 |
4 | BiMap<K, V> filterKeys(BiMap<K, V> unfiltered, Predicate<? super K> keyPredicate) Map<K, V> filterKeys(Map<K, V> unfiltered, Predicate<? super K> keyPredicate) SortedMap<K, V> filterKeys(SortedMap<K, V> unfiltered, Predicate<? super K> keyPredicate) NavigableMap<K, V> filterKeys(NavigableMap<K, V> unfiltered, Predicate<? super K> keyPredicate) 通过Map的key过滤Map,函数式接口为通过key产生的过滤条件 |
5 | BiMap<K, V> filterValues(BiMap<K, V> unfiltered, Predicate<? super V> valuePredicate) Map<K, V> filterValues(Map<K, V> unfiltered, Predicate<? super V> valuePredicate) SortedMap<K, V> filterValues(SortedMap<K, V> unfiltered, Predicate<? super V> valuePredicate) NavigableMap<K, V> filterValues(NavigableMap<K, V> unfiltered, Predicate<? super V> valuePredicate) 通过Map的value过滤Map,函数式接口为通过value产生的过滤条件 |
6 | ImmutableMap<String, String> fromProperties(Properties properties) 通过Properties构造ImmutableMap |
7 | ConcurrentMap<K, V> newConcurrentMap() 构造ConCurrentHashMap |
8 | HashMap<K, V> newHashMap() HashMap<K, V> newHashMap(Map<? extends K, ? extends V> map) 构造HashMap |
9 | LinkedHashMap<K, V> newLinkedHashMap() LinkedHashMap<K, V> newLinkedHashMap(Map<? extends K, ? extends V> map) 构造LinkedHashMap |
10 | HashMap<K, V> newHashMapWithExpectedSize(int expectedSize) LinkedHashMap<K, V> newLinkedHashMapWithExpectedSize(int expectedSize) 初始化一定大小的HashMap/LinkedHashMap,expectedSize用于确定HashMap底层bucket数组长度,bucket数组长度为2的指数幂,如果expectedSize上送14,其实底层bucket数组长度为16 |
11 | TreeMap<K, V> newTreeMap() newTreeMap(SortedMap<K, ? extends V> map) TreeMap<K, V> newTreeMap(@Nullable Comparator<C> comparator) 构造TreeMap |
12 | NavigableMap<K, V> subMap(NavigableMap<K, V> map, Range<K> range) 通过Range确定的key的范围分割Map,即求子Map |
13 | ImmutableMap<K, V> toMap(Iterable<K> keys, Function<? super K, V> valueFunction) ImmutableMap<K, V> toMap(Iterator<K> keys, Function<? super K, V> valueFunction) list转Map,函数式接口用于通过list元素确定Map的value,如果list中存在重复元素,会丢弃重复元素,不会抛异常,通过Java8 Stream操作会抛IllegalStateException异常 |
14 | Map<K, V2> transformEntries(Map<K, V1> fromMap, Maps.EntryTransformer<? super K, ? super V1, V2> transformer) SortedMap<K, V2> transformEntries(SortedMap<K, V1> fromMap, Maps.EntryTransformer<? super K, ? super V1, V2> transformer) NavigableMap<K, V2> transformEntries(NavigableMap<K, V1> fromMap, Maps.EntryTransformer<? super K, ? super V1, V2> transformer) 通过Map的Entry(key和value)转化Map,函数式表达式用于通过Entry确定转化后的value值 |
15 | Map<K, V2> transformValues(Map<K, V1> fromMap, Function<? super V1, V2> function) SortedMap<K, V2> transformValues(SortedMap<K, V1> fromMap, Function<? super V1, V2> function) NavigableMap<K, V2> transformValues(NavigableMap<K, V1> fromMap, Function<? super V1, V2> function) 通过Map的value转化Map,函数式接口用于通过value确定转化后的value值 |
16 | ImmutableMap<K, V> uniqueIndex(Iterable<V> values, Function<? super V, K> keyFunction) ImmutableMap<K, V> uniqueIndex(Iterator<V> values, Function<? super V, K> keyFunction) List元素作为Map的value,函数式接口用于通过List元素确定Map的key,如果生成的key存在重复的情况,会抛IllegalArgumentException异常,通过Java8 Stream操作会抛IllegalStateException异常 |
public class MapsTest {
@Test
public void asMapTest() {
/*asSet可用来将Set、SortedSet、NavigableSet转Map*/
Map<String, Integer> compareMap = Maps.newHashMap();
compareMap.put("This", 4);
compareMap.put("is", 2);
compareMap.put("test", 4);
Set<String> hashSet = Sets.newHashSet(Lists.newArrayList("This", "is", "test"));
Map<String, Integer> map0 = Maps.asMap(hashSet, String::length);
assertThat(map0, is(compareMap));
Set<String> treeSet = Sets.newTreeSet("This", "is", "test");
Map<String, Integer> map1 = Maps.asMap(treeSet, String::length);
assertThat(map1, equalTo(map0));
Set<String> sortedSet = Sets.newLinkedHashSet("This", "is", "test");
Map<String, Integer> map2 = Maps.asMap(sortedSet, String::length);
assertThat(map2, is(map1));
/*通过java8 Stream 也可以实现*/
Map<String, Integer> map3 = sortedSet.stream().collect(Collectors.toMap(ele -> ele, String::length));
assertThat(map3, is(map2));
}
@Test
public void differenceTest() {
Map<String, Integer> left = Maps.newHashMap();
Map<String, Integer> right = Maps.newHashMap();
left.put("Michael", 18);
left.put("Jane", 20);
left.put("Mary", 22);
left.put("haha", 22);
right.put("Michael", 19);
right.put("Jane", 18);
right.put("Mary", 22);
right.put("zhuoli", 23);
/*left与right的差*/
MapDifference<String, Integer> difference = Maps.difference(left, right);
/*left - right {haha=22}*/
Map<String, Integer> entriesOnlyOnLeft = difference.entriesOnlyOnLeft();
System.out.println(entriesOnlyOnLeft);
/*right - left {zhuoli=23}*/
Map<String, Integer> entriesOnlyOnRight = difference.entriesOnlyOnRight();
System.out.println(entriesOnlyOnRight);
/*left与right相同的Entry {Mary=22}*/
Map<String, Integer> entriesInCommon = difference.entriesInCommon();
System.out.println(entriesInCommon);
}
@Test
public void filterEntriesTest() {
/*根据Entry过滤Map*/
Map<String, Integer> compareMap = Maps.newHashMap();
compareMap.put("Jane", 20);
compareMap.put("Mary", 22);
Map<String, Integer> left = Maps.newHashMap();
left.put("Michael", 18);
left.put("Jane", 20);
left.put("Mary", 22);
Map<String, Integer> resultMap = Maps.filterEntries(left, ele -> ele.getValue() > 18);
assertThat(resultMap, is(compareMap));
/*Java8 Stream filter也可以,比较起来好像Guava的Maps更方便一些*/
Map<String, Integer> streamResult = left.entrySet().stream().filter(ele -> ele.getValue() > 18).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
assertThat(streamResult, is(resultMap));
}
@Test
public void filterKeysTest() {
/*根据key过滤Map*/
Map<String, Integer> compareMap = Maps.newHashMap();
compareMap.put("Michael", 18);
Map<String, Integer> left = Maps.newHashMap();
left.put("Michael", 18);
left.put("Jane", 20);
left.put("Mary", 22);
Map<String, Integer> resultMap = Maps.filterKeys(left, ele -> ele.length() > 4);
assertThat(resultMap, is(compareMap));
/*Java8 Stream filter也可以,比较起来好像Guava的Maps更方便一些*/
Map<String, Integer> streamResult = left.entrySet().stream().filter(ele -> ele.getKey().length() > 4).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
assertThat(streamResult, is(resultMap));
}
@Test
public void filterValuesTest() {
/*根据value过滤Map*/
Map<String, Integer> compareMap = Maps.newHashMap();
compareMap.put("Michael", 18);
Map<String, Integer> left = Maps.newHashMap();
left.put("Michael", 18);
left.put("Jane", 20);
left.put("Mary", 22);
Map<String, Integer> resultMap = Maps.filterValues(left, ele -> ele < 20);
assertThat(resultMap, is(compareMap));
/*Java8 Stream filter也可以,比较起来好像Guava的Maps更方便一些*/
Map<String, Integer> streamResult = left.entrySet().stream().filter(ele -> ele.getValue() < 20).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
assertThat(streamResult, is(resultMap));
}
@Test
public void fromPropertiesTest() {
/*通过Properties构造ImmutableMap*/
Map<String, String> compareMap = Maps.newHashMap();
compareMap.put("this", "1");
compareMap.put("is", "2");
compareMap.put("test", "3");
Properties properties = new Properties();
/*注意Properties的value必须也为String, 否则会报NPE,详见Properties的getProperty方法(getProperty获取value为null,
ImmutableMap.Builder put操作中ImmutableMap.entryOf操作会checkEntryNotNull,报NPE)*/
properties.put("this", "1");
properties.put("is", "2");
properties.put("test", "3");
/*fromProperties生成的是ImmutableMap<String, String>*/
Map<String, String> map = Maps.fromProperties(properties);
assertThat(map, is(compareMap));
}
@Test
public void newConcurrentMapTest() {
Map<String, Integer> map = Maps.newConcurrentMap();
assertTrue(map.isEmpty());
}
@Test
public void newHashMapTest() {
Map<String, Integer> map = Maps.newHashMap();
assertTrue(map.isEmpty());
Map<String, Integer> sortedMap = Maps.newLinkedHashMap();
sortedMap.put("zhuoli", 11);
/*HashMap<K, V> newHashMap(Map<? extends K, ? extends V> map)*/
Map<String, Integer> map1 = Maps.newHashMap(sortedMap);
assertThat(map1, hasEntry("zhuoli", 11));
}
@Test
public void newHashMapWithExpectedSizeTest() {
/*传入的数值为Map底层bucket数组大小,JDK实现为2的指数幂,所以下面代码底层Map的bucket数组实际大小为16*/
Map<String, Integer> map = Maps.newHashMapWithExpectedSize(14);
assertTrue(map.isEmpty());
}
@Test
public void newLinkedHashMapTest() {
Map<String, Integer> map = Maps.newLinkedHashMap();
assertTrue(map.isEmpty());
Map<String, Integer> sortedMap = Maps.newLinkedHashMap();
sortedMap.put("zhuoli", 11);
/*LinkedHashMap<K, V> newLinkedHashMap(Map<? extends K, ? extends V> map)*/
Map<String, Integer> map1 = Maps.newLinkedHashMap(sortedMap);
assertThat(map1, hasEntry("zhuoli", 11));
}
@Test
public void newLinkedHashMapWithExpectedSizeTest() {
/*传入的数值为Map底层bucket数组大小,JDK实现为2的指数幂,所以下面代码底层Map的bucket数组实际大小为16*/
Map<String, Integer> map = Maps.newLinkedHashMapWithExpectedSize(14);
assertTrue(map.isEmpty());
}
@Test
public void newTreeMapTest() {
Map<String, Integer> map = Maps.newTreeMap();
assertTrue(map.isEmpty());
TreeMap<String, Integer> sortedMap = Maps.newTreeMap();
sortedMap.put("zhuoli", 11);
Map<String, Integer> map1 = Maps.newTreeMap(sortedMap);
assertThat(map1, hasEntry("zhuoli", 11));
}
@Test
public void subMapTest() {
Map<Integer, String> compareMap = Maps.newHashMap();
compareMap.put(1, "chenhao");
compareMap.put(2, "zhuoli");
TreeMap<Integer, String> idNameMap = Maps.newTreeMap();
idNameMap.put(1, "chenhao");
idNameMap.put(2, "zhuoli");
idNameMap.put(3, "xiaoxian");
idNameMap.put(4, "haha");
/*定义子Map的key的范围为(0, 3)*/
Range<Integer> range = Range.open(0, 3);
Map<Integer, String> result = Maps.subMap(idNameMap, range);
assertThat(result, is(compareMap));
}
@Test
public void toMapTest() {
Map<String, String> compareMap = Maps.newHashMap();
compareMap.put("this", "THIS");
compareMap.put("is", "IS");
compareMap.put("test", "TEST");
List<String> list = Lists.newArrayList("this", "is", "test", "is");
/*ImmutableMap<K, V> toMap(Iterable<K> keys, Function<? super K, V> valueFunction)
* 第二个参数为用于获取map value的函数表达式*/
/*Guava toMap如果Iterable集合存在重复的情况,不会抛异常,会丢弃重复值*/
Map<String, String> map = Maps.toMap(list, String::toUpperCase);
System.out.println(map);
assertThat(map, equalTo(compareMap));
/*Java 8 stream toMap操作*/
/*使用Java8 stream toMap操作时,如果key存在重复的情况,会抛异常IllegalStateException*/
assertThatThrownBy(() -> list.stream().collect(Collectors.toMap(ele -> ele, String::toUpperCase)))
.isInstanceOf(IllegalStateException.class)
.hasNoCause();
}
@Test
public void transformEntriesTest() {
/*根据Entry转化Map(根据key和value修改Map的value值)*/
Map<String, String> compareMap = Maps.newHashMap();
compareMap.put("this", "this4");
compareMap.put("is", "is2");
compareMap.put("test", "test4");
Map<String, Integer> map = Maps.newHashMap();
map.put("this", 4);
map.put("is", 2);
map.put("test", 4);
Map<String, String> resultMap = Maps.transformEntries(map, (k, v) -> k + v.toString());
assertThat(resultMap, equalTo(compareMap));
Map<String, Integer> resultMap1 = Maps.transformEntries(map, (k, v) -> v + 1);
assertThat(resultMap1, hasEntry("this", 5));
/*Java 8 Stream Collectors.toMap转化Map, Guava使用简单一些,但是Java8适用性更强,可以同时转化key和value*/
Map<String, String> resultMap2 = map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, ele -> ele.getKey() + ele.getValue()));
assertThat(resultMap2, equalTo(compareMap));
Map<String, String> resultMap3 = map.entrySet().stream().collect(Collectors.toMap(ele -> ele.getKey().toUpperCase(), ele -> ele.getKey() + ele.getValue()));
assertThat(resultMap3, hasEntry("THIS", "this4"));
}
@Test
public void transformValuesTest(){
/*通过Map的value转化Map(根据value修改value值)*/
Map<String, Integer> compareMap = Maps.newHashMap();
compareMap.put("this", 5);
compareMap.put("is", 3);
compareMap.put("test", 5);
Map<String, Integer> map = Maps.newHashMap();
map.put("this", 4);
map.put("is", 2);
map.put("test", 4);
Map<String, Integer> resultMap = Maps.transformValues(map, value -> value + 1);
assertThat(resultMap, is(compareMap));
/*Java8 Stream 操作*/
Map<String, Integer> resultMap1 = map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, ele -> ele.getValue() + 1));
assertThat(resultMap1, is(compareMap));
}
@Test
public void uniqueIndexTest(){
Map<Integer, String> compareMap = Maps.newHashMap();
compareMap.put(4, "this");
compareMap.put(2, "is");
/*Iterable作为Map的value,通过函数表达式生成key组成map*/
List<String> list = Lists.newArrayList("this", "is");
Map<Integer, String> map = Maps.uniqueIndex(list, String::length);
assertThat(map, is(compareMap));
/*如果函数式表达式生成的key存在重复的情况,会抛IllegalArgumentException异常*/
List<String> list1 = Lists.newArrayList("this", "is", "test");
assertThatThrownBy(()->Maps.uniqueIndex(list1, String::length))
.isInstanceOf(IllegalArgumentException.class)
.hasNoCause();
/*uniqueIndex Java8 Stream等价操作*/
Map<Integer, String> map1 = list.stream().collect(Collectors.toMap(String::length, ele -> ele));
assertThat(map1, is(compareMap));
/*Java8 key重复会抛IllegalStateException异常*/
assertThatThrownBy(()->list1.stream().collect(Collectors.toMap(String::length, ele -> ele)))
.isInstanceOf(IllegalStateException.class)
.hasNoCause();
}
}
uniqueIndex:
五、Multimaps
作用:Map<K,List<V>>的结构实现起来特别麻烦,需要检查key是否存在,不存在时则创建一个,存在时在List后面添加上一个。这个过程是比较痛苦的,如果希望检查List中的对象是否存在,删除一个对象,或者遍历整个数据结构,那么则需要更多的代码来实现。
Multimap 提供了一个方便地把一个键对应到多个值的数据结构。
可以这样理解Multimap:”键-值映射”的集合(例如:a -> 1 a -> 2 a ->4 b -> 3 c -> 5)
特点:不会有任何键映射到空集合:一个键要么至少到一个值,要么根本就不在Multimap中
package com.mzj.guava.collections;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import org.junit.Test;
import java.util.HashMap;
public class MultimapsExample {
@Test
public void test(){
LinkedHashMultimap<String,String> multimap = LinkedHashMultimap.create();
multimap.put("1","1");
multimap.put("1","2");
System.out.println(multimap.get("1").getClass());
System.out.println(multimap.get("1"));
}
}
六、BiMap
特点:根据value的值确定唯一性的map结构
package com.mzj.guava.collections;
import com.google.common.collect.HashBiMap;
import org.junit.Test;
public class BiMapExample {
@Test
public void test(){
HashBiMap<String, String> biMap = HashBiMap.create();
biMap.put("1","2");
biMap.put("2","2");
}
}
可以通过forcePut接口替换相同value的key:
@Test
public void test2(){
HashBiMap<String, String> biMap = HashBiMap.create();
biMap.put("1","2");
biMap.forcePut("2","2");
System.out.println(biMap);
}
输出:
七、Table
作用:类似于数据库的表,有行,有列的数据结构。
Guava中提供了四种类型的Table:ArrayTable、TreeBaseTable、HashBaseTable、ImmutableTable
Table结构类似于:Map<R:rowKey,Map<C:columnKey,V:value>>
package com.mzj.guava.collections;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import org.junit.Test;
import java.util.Map;
import java.util.Set;
public class TableExampleTest {
@Test
public void testHashBasedTable(){
Table<String,String,String> table = HashBasedTable.create();
//1、put方法参数:row行key、column列key、值
table.put("Language","Java","1.8");
table.put("Language","Python","3.7");
table.put("DataBase","oracle","12C");
table.put("DataBase","mysql","8.0");
table.put("MyLanguage","Java","144");
System.out.println(table);
//2、拿到某一行
Map<String,String> language = table.row("Language");
System.out.println(language);
//3、table结构类似于:Map<rowKey,Map<columnKey,value>>
//4、可以直接拿到某列
Map<String, String> column = table.column("Java");
System.out.println(column);
//5、cellSet
Set<Table.Cell<String, String, String>> cells = table.cellSet();
System.out.println(cells);
}
}
输出:
八、Range
1、作用:范围+基于集合的Range(范围)
package com.mzj.guava.collections;
import com.google.common.collect.BoundType;
import com.google.common.collect.Maps;
import com.google.common.collect.Range;
import org.junit.Test;
import java.util.NavigableMap;
import java.util.TreeMap;
public class RangeExampleTest {
/**
* 逻辑表达式:a<=X<=b
*/
@Test
public void testClosedRange(){
//closed:都包含
Range<Integer> closeRange = Range.closed(0,9);//参数1为lower的点,参数2为upper的点
System.out.println(closeRange);
System.out.println(closeRange.contains(0));
System.out.println(closeRange.contains(9));
//lower的点
System.out.println(closeRange.lowerEndpoint());
//upper的点
System.out.println(closeRange.upperEndpoint());
}
/**
* 逻辑表达式:a<X<b
*/
@Test
public void testOpenRange(){
//open:都不包含
Range<Integer> openRange = Range.open(0,9);//参数1为lower的点,参数2为upper的点
System.out.println(openRange);
System.out.println(openRange.contains(0));
System.out.println(openRange.contains(9));
//lower的点
System.out.println(openRange.lowerEndpoint());
//upper的点
System.out.println(openRange.upperEndpoint());
}
/**
* 逻辑表达式:a<X<=b
*/
@Test
public void testOpenClosedRange(){
//openClosed:lower不包含,upper包含
Range<Integer> openRange = Range.openClosed(0,9);//参数1为lower的点,参数2为upper的点
System.out.println(openRange);
System.out.println(openRange.contains(0));
System.out.println(openRange.contains(9));
//lower的点
System.out.println(openRange.lowerEndpoint());
//upper的点
System.out.println(openRange.upperEndpoint());
}
/**
* 逻辑表达式:a<=X<b
*/
@Test
public void testClosedOpenRange(){
//openClosed:lower包含,upper不包含
Range<Integer> openRange = Range.closedOpen(0,9);//参数1为lower的点,参数2为upper的点
System.out.println(openRange);
System.out.println(openRange.contains(0));
System.out.println(openRange.contains(9));
//lower的点
System.out.println(openRange.lowerEndpoint());
//upper的点
System.out.println(openRange.upperEndpoint());
}
/**
* 逻辑表达式:x>a
*/
@Test
public void testGreaterThan(){
Range<Integer> range = Range.greaterThan(10);
System.out.println(range.contains(10));
System.out.println(range.contains(Integer.MAX_VALUE));
}
/**
* 基于Map内容的range
*/
@Test
public void testMapRange(){
TreeMap<String,Integer> treeMap = Maps.newTreeMap();
treeMap.put("Java",1);
treeMap.put("Guava",2);
treeMap.put("Netty",3);
treeMap.put("kafka",4);
System.out.println(treeMap);//下面的范围获取,是基于放进去后排序的结果进行获取的
NavigableMap<String, Integer> result = Maps.subMap(treeMap, Range.closed("Java", "Netty"));
System.out.println(result);
}
@Test
public void testOtherMethod(){
System.out.println(Range.atLeast(5));
System.out.println(Range.lessThan(10));
System.out.println(Range.atMost(10));
System.out.println(Range.all());
System.out.println(Range.downTo(10, BoundType.CLOSED));
System.out.println(Range.upTo(10, BoundType.CLOSED));
}
}
九、RangeMap
1、作用:类似对学生成绩进行分类,91-100的A,81-90的B....
package com.mzj.guava.collections;
import com.google.common.collect.Range;
import com.google.common.collect.TreeRangeMap;
import org.junit.Test;
public class RangeMapExample {
@Test
public void testRangeMap(){
TreeRangeMap<Integer,String> gradeScale = TreeRangeMap.create();
gradeScale.put(Range.closed(0,60),"E");
gradeScale.put(Range.closed(61,70),"D");
gradeScale.put(Range.closed(71,80),"C");
gradeScale.put(Range.closed(81,90),"B");
gradeScale.put(Range.closed(91,100),"A");
System.out.println(gradeScale.get(77));
System.out.println(gradeScale.get(97));
}
}
输出:
十、ImmutableCollections
1、作用:不可变集合,在多线程编程中使用,不能对其进行add、update,只能read,具有线程安全性
package com.mzj.guava.collections;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.junit.Test;
import java.util.Arrays;
public class ImmutableCollections {
@Test
public void testOf(){
ImmutableList<Integer> list = ImmutableList.of(1, 2, 3);
System.out.println(list);
}
@Test
public void testCopy(){
Integer[] array = {1,2,3,4,5};
System.out.println(ImmutableList.copyOf(array));
}
@Test
public void testBuilder(){
ImmutableList<Integer> list = ImmutableList.<Integer>builder().add(1)
.add(2, 3, 4)
.addAll(Arrays.asList(5, 6))
.build();
System.out.println(list);
}
@Test
public void testImmutableMap(){
ImmutableMap<String, String> map = ImmutableMap.of("Java", "1.8").of("Oracle", "12c");
System.out.println(map);
ImmutableMap<String, String> map1 = ImmutableMap.<String,String>builder().put("ORACLE","1212").put("ORACLE1","121212").build();
System.out.println(map1);
}
}
十一、Ordering
1、作用:排序
package com.mzj.guava.collections;
import com.google.common.collect.Ordering;
import org.junit.Test;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class OrderingExample {
@Test
public void testJDKSort(){
List<Integer> list = Arrays.asList(1,4,5,2,3);
Collections.sort(list);
System.out.println(list);
}
@Test(expected = NullPointerException.class)
public void testJDKSortIssue(){
List<Integer> list = Arrays.asList(1,4,5,null,2,3);
Collections.sort(list);
System.out.println(list);//jdk的sort如果遇到null会抛出异常
}
/**
* 如果遇到null,则放在第一个元素
*/
@Test
public void testOrderNaturalByNullFirst(){
List<Integer> list = Arrays.asList(1,4,5,null,2,3);
Collections.sort(list, Ordering.natural().nullsFirst());
System.out.println(list);
}
/**
* 如果遇到null,则放在最后一个元素
*/
@Test
public void testOrderNaturalByNullLast(){
List<Integer> list = Arrays.asList(1,4,5,null,2,3);
Collections.sort(list, Ordering.natural().nullsLast());
System.out.println(list);
}
/**
* 如果遇到null,则放在最后一个元素
*/
@Test
public void testOrderNatural(){
List<Integer> list = Arrays.asList(1,5,3,8,2);
Collections.sort(list);
System.out.println(Ordering.natural().isOrdered(list));//判断当前集合是否是按照自然顺序排序的
}
}