Guava集合(二)工具类篇

Immutablexxx 不可变集合

JDK 提供了Collections.unmodifiableXXX方法,为什么guava还有提供不可变方法。根据官网的描述我认为最大的原因有两个:

  • jdk提供的不可变集合方法是不安全的,如果原有集合的引用在其它地方被持有,那么就不是真的不可变,可以通过原有集合的引用改变该“不可变集合”。
  • 低效:数据结构仍然具有可变集合的所有开销,包括并发修改检查,哈希表中的额外空间等。
//  Collections.unmodifiableXXX方法不安全示例
    @Test
    public void ImmutableTest () {
        ArrayList<String> fruits = Lists.newArrayList("Apple", "Pear", "Banana");
        ImmutableList<String> immutableList = ImmutableList.copyOf(fruits);
        List<String> list = Collections.unmodifiableList(fruits);

        fruits.add("Orange");

        System.out.println(immutableList);//[Apple, Pear, Banana]
        
        System.out.println(list);//[Apple, Pear, Banana, Orange]
    }

怎样使用

  • 使用 copyOf 方法,例如 ImmutableSet.copyOf(set)
  • 使用 of method,例如, ImmutableSet.of(“a”, “b”, “c”) or ImmutableMap.of(“a”, 1, “b”, 2)
  • 使用 Builder
    @Test
    public void ImmutableBuilderTest () {
        List<Object> list = ImmutableList.builder()
                .add("I", "am", "java", "programer")
                .build();
        System.out.println(list);
    }

ImmutableXXX.copyOf

ImmutableXXX.copyOf方法会尽可能的避免复制数据,例如如下代码:

// “聪明”的copyof方法只返回视图
// 看源码 ImmutableSet 和Jdk hashSet数据结构不一样,ImmutableSet采用线性探测法,利用数组存储数据
ImmutableSet<String> foobar = ImmutableSet.of("foo", "bar", "baz");
thingamajig(foobar);

void thingamajig(Collection<String> collection) {
   ImmutableList<String> defensiveCopy = ImmutableList.copyOf(collection);
   ...
}

源码分析:

  public static <E> ImmutableList<E> copyOf(Collection<? extends E> elements) {
  // 如果是不可变集合类型,就尽可能的不去复制数据
    if (elements instanceof ImmutableCollection) {
      @SuppressWarnings("unchecked") // all supported methods are covariant
      ImmutableList<E> list = ((ImmutableCollection<E>) elements).asList();
      // isPartialView是否是局部视图,决定copyof的实现是否应进行显式复制以避免内存泄漏。例如:
      //你有ImmutableList <String> hugeList,并且执行了ImmutableList.copyOf(hugeList.subList(0,10)),则将执行显式复制,以避免意外按住引用不需要的hugeList中的引用。
      return list.isPartialView() ? ImmutableList.<E>asImmutableList(list.toArray()) : list;
    }
    return construct(elements.toArray());
  }

Lists

Lists主要提供了一系列的静态工厂方法创建List集合。

Lists.newArrayList()
Lists.newArrayList(E... elements)
Lists.newArrayListWithCapacity(int initialArraySize)
Lists.newLinkedList()
Lists.newLinkedList(Iterable<? extends E> elements)
Lists.newCopyOnWriteArrayList()
Lists.newCopyOnWriteArrayList(Iterable<? extends E> elements)
Lists.asList(@Nullable E first, E[] rest)
Lists.asList(@Nullable E first, @Nullable E second, E[] rest)
Lists.cartesianProduct(List<? extends List<? extends B>> lists) //求笛卡尔积
Lists.cartesianProduct(List... lists) //求笛卡尔积
Lists.transform(List<F> fromList, Function<? super F, ? extends T> function) //转换
Lists.partition(List<T> list, int size) //按size分区
Lists.reverse(List<T> list) //倒序

示例

   @Test
    public void testAsList (){
        List<String> list = Lists.asList("China", new String[]{"Hello"});
    }


    @Test
    public void testOfList (){
        List<String> lsit = Lists.newArrayList("China","Guava","Good");
        ArrayList<Object> lust = Lists.newArrayListWithExpectedSize(10);
        List<String> transform = Lists.transform(lsit, (element) -> element.toUpperCase());
        System.out.println(transform);
    }

    @Test
    public void testCartesianProduct () {
        List<String> lsit = Lists.newArrayList("China","Guava","Good");
        List<String> lsit2 = Lists.newArrayList("Hello","Nice");
        //[[China, Hello], [China, Nice], [Guava, Hello], [Guava, Nice], [Good, Hello], [Good, Nice]]
        List<List<String>> lists = Lists.cartesianProduct(lsit, lsit2);
    }

Sets

Sets工具类提供了创建各式各样Set集合的工厂方法

  • Sets.newHashSet();
  • Sets.newHashSet(E… elements) ;
  • Sets.newConcurrentHashSet();
  • Sets.newCopyOnWriteArraySet();
  • Sets.newLinkedHashSet();
  • Sets.newEnumSet();
  • Sets.newTreeSet();

示例:

/**
 * 测试EnumSet
 */
@Test
    public void testEnumSet () {
        List<Fruit> fruits = Lists.newArrayList(Apple, Orange, Pear,Apple);
        EnumSet<Fruit> enumSet = Sets.newEnumSet(fruits, Fruit.class);
        Assert.assertEquals(3,enumSet.size());
    }
  • Sets.intersection()// 求交集
  • Sets.difference(final Set set1, final Set<?> set2)//set1 有set2 没有的元素
  • Sets.union()// 全集
  • Sets.symmetricDifference( final Set<? extends E> set1, final Set<? extends E> set2)// 差集
Sets.SetView<String> intersection = Sets.intersection(primes, wordsWithPrimeLength); // contains "two", "three", "seven"
Sets.SetView<String> difference = Sets.difference(wordsWithPrimeLength, primes);// A有B没有的 [one, six, eight]
Sets.SetView<String> union = Sets.union(wordsWithPrimeLength, primes); // [one, two, three, six, seven, eight, five]

Maps

提供Map的创建的工厂方法,诸如

  • HashMap
  • LinkedHashMap
  • newConcurrentMap
  • newTreeMap
  • EnumMap

其它API :求差集

        Map<String, Integer> left = ImmutableMap.of("a", 1, "b", 2, "c", 3);
        Map<String, Integer> right = ImmutableMap.of("b", 2, "c", 4, "d", 5);
        MapDifference<String, Integer> diff = Maps.difference(left, right);

//        map1和map2的交集,key,value都相同
        diff.entriesInCommon(); // {"b" => 2}
//        key值相同,但是value值不相同
        diff.entriesDiffering(); // {"c" => (3, 4)}
//       key存在于left但是不在right中的
        diff.entriesOnlyOnLeft(); // {"a" => 1}
//        key存在于right但是不在中的left
        diff.entriesOnlyOnRight(); // {"d" => 5}

官方API

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值