Guava包学习---Lists

  Guava包是我最近项目中同事推荐使用的,是google推出的库。里面的功能非常多,包括了集合、缓存、原生类型支持、并发库、通用注解、字符串处理、IO等。我们项目中使用到了guava依赖,但是实际上只是用了其中很小一部分功能,比如集合的声明和处理以及函数式风格等。

  废话少说,上图先:

  我们会发现里面太多的东西,基本上全部加起来得有数百个上千的类了,但是所经常使用的其实就几十个类。其实可以在项目中建立common-utils包专门抄一部分guava的类过去,而不必全部将guava依赖进来。

  工作中使用最多的莫过于List、set、map、string,I/O了,先看Lists吧。

@GwtCompatible(emulated = true)
public final class Lists {}

这个是guava中Lists工具的声明,这个GwtCompatible的注解有两个参数,一个是serializable 一个是imulated,都是boolean的值,表示是否需要支持序列化、是否仿真(其实就是是否和JVM的默认实现不一致)。guava中的注释写的非常详细,方法也非常多,但实际上我经常用到的只不过是某些list的声明和一些将list拆分的功能,所以我就只关心那几个方法了。上图看下guava lists类的方法:

其实里面很多方法就是使用泛型简化平时手工去敲的操作。有些方法在jdk1.7及以后已经应该变成deprecated。

 @GwtCompatible(serializable = true)
  public static <E> ArrayList<E> newArrayList(Iterable<? extends E> elements) {
    checkNotNull(elements); // for GWT
    // Let ArrayList‘s sizing logic work, if possible
    return (elements instanceof Collection)
        ? new ArrayList<E>(Collections2.cast(elements))
        : newArrayList(elements.iterator());
  }

Lists中newArrayList和newLinkedList等有好几个重载方法,其实就是使用泛型去简化一些工作。可能有人疑问我用Lists.newArrayList(xxx)和直接new ArrayList<?>()有什么区别,其实就是省点打字的功夫。比如你创建一个List<Map<String,Map<String,Object>> 这样子的list,如果你要用new的话得还得费很大劲去敲键盘,其实用guava去声明只需要使用重载方法就行了:

List<Map<String,Map<String,Object>>> list = Lists.newArrayList();

其实后面的创建的LinkedList、copyonwriteArrayList等等如出一辙,就不再多看。

还有一个比较有用的方法是拆分list:

public static <T> List<List<T>> partition(List<T> list, int size) {
    checkNotNull(list);
    checkArgument(size > 0);
    return (list instanceof RandomAccess)
        ? new RandomAccessPartition<T>(list, size)
        : new Partition<T>(list, size);
  }

比如当你需要请求别人的API传入参数时对方的入参数量有限制,可以先拆分然后顺序请求获得结果。

RandomAccess意思是加快访问速度,不保证顺序但是可以让所有元素都常量时间拿到。下面列出Partition的详细代码:

private static class Partition<T> extends AbstractList<List<T>> {
    final List<T> list;
    final int size;

    Partition(List<T> list, int size) {
      this.list = list;
      this.size = size;
    }

    @Override
    public List<T> get(int index) {
      checkElementIndex(index, size());
      int start = index * size;
      int end = Math.min(start + size, list.size());
      return list.subList(start, end);
    }

    @Override
    public int size() {
      return IntMath.divide(list.size(), size, RoundingMode.CEILING);
    }

    @Override
    public boolean isEmpty() {
      return list.isEmpty();
    }
  }

也就是当你get的时候,它去进行subList操作。

接下来是一些很小众的功能了:

  @Beta
  public static ImmutableList<Character> charactersOf(String string) {
    return new StringAsImmutableList(checkNotNull(string));
  }

获得一个String的不可变Char。

  @Beta
  public static List<Character> charactersOf(CharSequence sequence) {
    return new CharSequenceAsList(checkNotNull(sequence));
  }

获得一个charsquence的list

 @CheckReturnValue
  public static <T> List<T> reverse(List<T> list) {
    if (list instanceof ImmutableList) {
      return ((ImmutableList<T>) list).reverse();
    } else if (list instanceof ReverseList) {
      return ((ReverseList<T>) list).getForwardList();
    } else if (list instanceof RandomAccess) {
      return new RandomAccessReverseList<T>(list);
    } else {
      return new ReverseList<T>(list);
    }
  }

反转一个list。

剩下还有很多重写方法和static的protected的方法,但是都很常见。接下来去看一下Sets类吧。

时间: 2024-10-22 12:17:58

Guava包学习---Lists的相关文章

Guava包学习-Multimap

它和上一章的MultiSet的继承结果很相似,只不过在上层的接口是Multimap不是Multiset. Multimap的特点其实就是可以包含有几个重复Key的value,你可以put进入多个不同value但是相同的key,但是又不是让后面覆盖前面的内容. Guava中有很多multimap的变种,其实就是普通的map变种一样,这里不做详细解释,用的是拿出来就成了.先测试一下multimap的特性: public void testMultimap(){ HashMultimap<Intege

Guava包学习---Maps

Maps包方法列表: 还是泛型创建Map: public static <K, V> HashMap<K, V> newHashMap() { return new HashMap<K, V>(); } public static <K, V> HashMap<K, V> newHashMapWithExpectedSize(int expectedSize) { return new HashMap<K, V>(capacity(e

Guava包学习---Bimap

Bimap也是Guava中提供的新集合类,别名叫做双向map,就是key->value,value->key,也就是你可以通过key定位value,也可以用value定位key. 这个场景在日常开发中还是经常碰到的. 其实,Bimap相对比较简单,它是一个接口,扩展了Map接口,里面也是<K,V>格式,只不过它不允许有重复的V,这一点很重要,当你尝试往里面put一个重复的V的是会有报错信息提示.没有重复的V也就保证了你把这个map倒置的时候从V定位K也是可以唯一定位到的,我们可以看

Guava包学习--Table

Table,顾名思义,就好像HTML中的Table元素一样,其实就是行+列去确定的值,更准确的比喻其实就是一个二维矩阵. 其实它就是通过行+列两个key去找到一个value,然后它又containsvalue.containsrow.containscolumn等方法来判断是否包含. 同事put方法也是3个参数:另外你可以通过row()或者column方法得到一列或者一行的一个map<k,v>值. 我感觉这个集合非常有想法,你在处理类似Dom中的二维数组中的值都可以在程序中用这个进行模拟. 具

Guava库学习:学习Guava EventBus(二)EventBus 事件订阅示例

原文地址:Guava库学习:学习Guava EventBus(二)EventBus 事件订阅示例 上一篇Guava库学习:学习Guava EventBus(一)EventBus,我们简单的对Guava基于事件的编程进行了介绍,学习和了解了EventBus类的使用,本篇起,我们通过一系列的示例代码深入的学习EventBus类,本篇学习Guava EventBus(二)EventBus 事件订阅示例.     订阅Subscribe 首先,我们假定定义了如下所示的TradeAccountEvent类

Guava库学习:学习Guava Files系列(二)

原文地址:Guava库学习:学习Guava Files系列(二) 上一篇,Guava库学习:学习Guava Files系列(一)中,我们简单的学习了使用Files进行文件的读写等常用操作,本篇我们继续进行Guava Files系列的学习.     InputSupplier 和 OutputSupplier Guava提供了 InputSupplier 和 OutputSupplier接口,用于提供InputStreams/Readers 或OutputStreams/Writers的处理.我们

Guava库学习:学习Guava Files系列(一)

原文地址:Guava库学习:学习Guava Files系列(一) 对程序开发人员来说,文件的读写是很重要的一项技能.但是令人惊讶的是,尽管Java提供了一个丰富而健壮的I/O库,进行一些基本的文件操作却显得很繁 琐.不过在Java 7中已经发生了一些改变,但那些使用Java 6的就不那么好运了.幸运的是,Guava做了一些我们期望I/O库做的事情,提供了一系列的工具,让我们能够更方便的进行I/O操作.本篇,我们就开始来学习如何使用Guava Files进行一些I/O操作. 尽管Java 7做了一

Guava库学习:Guava 零碎知识

这将是Guava库学习系列的最后一篇,但是仍然包含许多零零碎碎的知识.虽然不可能覆盖所有Guava涉及的知识,但我们会竭尽所能.本篇将会介绍一些Guava中有用的工具,并不需要再开一个系列.本篇学习的一些工具可能并不会经常使用,但当你需要时,它是必不可少的.接下来,开始本篇的学习. 本篇,我们将主要学习以下内容:Hashing.BloomFilter.Optional.Throwable. Hashing散列类包含静态实用方法获取HashFunction实例 BloomFilter数据结构,用于

Guava库学习:学习Guava Cache知识汇总

原文地址:Guava库学习:学习Guava Cache知识汇总 至此,我们结束了对Guava Cache 缓存机制的学习,在学习过程中,我们学习了如何简单的通过MapMaker创建最简单的ConcurrentMap缓存,我们也了解了缓存的高级特性,以及强大的LoadingCache,我们也探索和学习了CacheBuilder.CacheLoader这些核心的API,以及CacheStats.RemovalLitener等,下面对这些文章做一些汇总,方便以后的查阅和复习.     Guava库学习