zoukankan      html  css  js  c++  java
  • Guava集合工具

    JDK提供了一系列集合类,如下所示,极大的方便了开发工作,并针对这些类提供了一个工具类java.util.Collections,Guava在此基础上添加了一些常用工具类方法,相比于java.util.Collections集合类,Guava使用起来更方便快捷。本文主要介绍Guava集合工具类中Lists、Sets、Maps的常规使用。

     

    Lists
    S.N. 方法及说明
    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操作,更方便
    示例代码:

    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
    S.N. 方法及说明
    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)
    求set1和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操作
    示例代码:

    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
    S.N. 方法及说明
    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();
    }
    }
    以上可以发现,Guava Maps中的复杂操作如asMap(set转map)、filterEntries/filterKeys/filterValues(fiter过滤)、toMap(list转map)、transformEntries/transformValues(转化map)、uniqueIndex(list元素作为value转map)等都可以通过Java8的Stream操作实现。Java8的Stream操作适用性比较广,但是有时候需要书写较长的链式操作,Guava针对各个场景提供了具体的方法。其实本质上没什么区别,就看大家在开发中怎么选择了。

    测试代码:码云 – 卓立 – Guava测试代码

    Google Guava Docs
    Google Guava User Guide
    Guava源码
    ---------------------
    版权声明:本文为CSDN博主「卓立0」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/weixin_41835612/article/details/83646257

  • 相关阅读:
    使用jedis连接redis
    布隆过滤器redis缓存
    SQL与NOSQL
    Charles 移动端抓包工具,使用方法以及注意事项
    安装npm包的时候报错rollbackFailedOptional: verb npm-session
    You may need an appropriate loader to handle this file type.
    数组去重
    判断两个数组是否相等(包括数组里边的键值对是否相等)
    数组里的字符串转为数字
    背景色铺满整个屏幕
  • 原文地址:https://www.cnblogs.com/GarfieldEr007/p/11357278.html
Copyright © 2011-2022 走看看