guava学习--集合1

Lists:

其内部使用了静态工厂方法代替构造器,提供了许多用于List子类构造和操作的静态方法,我们简单的依次进行说明,如下:

newArrayList():构造一个可变的、空的ArrayList实例。

newArrayList(E... elements):构造一个可变的包含传入元素elements的ArrayList实例。

newArrayList(Iterable<? extends E> elements):构造一个可变的包含传入元素elements的ArrayList实例。

newArrayListWithCapacity( int initialArraySize):构造一个分配 指定空间大小的ArrayList实例。

newArrayListWithExpectedSize( int estimatedSize):构造一个期望长度为estimatedSize的ArrayList实例。

newLinkedList():构造一个空的LinkedList实例。

newLinkedList( Iterable<? extends E> elements):构造一个包含传入元素elements的LinkedList实例。

newCopyOnWriteArrayList():构造一个空的CopyOnWriteArrayList实例。

newCopyOnWriteArrayList( Iterable<? extends E> elements):构造一个包含传入元素elements的CopyOnWriteArrayList实例。

asList(@Nullable E first, E[] rest):返回一个不可变的List,其中包含指定的第一个元素和附加的元素数组组成,修改这个数组将反映到返回的List上。

asList( @Nullable E first, @Nullable E second, E[] rest): 返回一个不可变的List,其中包含指定的第一个元素、第二个元素和附加的元素数组组成,修改这个数组将反映到返回的List上。

transform( List fromList, Function<? super F, ? extends T> function):根据传进来的function对fromList进行相应的处理,并将处理得到的结果存入到新的list对象中返回。

partition(List list, int size):根据size传入的List进行切割,切割成符合要求的小的List,并将这些小的List存入一个新的List对象中返回。

charactersOf(String string)、charactersOf(CharSequence sequence):将传进来的String或者CharSequence分割为单个的字符,并存入到一个ImmutableList对象中返回。 (ImmutableList:一个高性能、不可变的、随机访问列表的实现 )

reverse(List list):返回一个传入List内元素倒序后的List。

接下来,我们通过下面的示例代码,来继续加深对Lists的理解,代码如下:

/**
 * Lists:处理List实例的实用类
 * User: Realfighter
 * Date: 2014/8/31
 * Time: 22:45
 */
public class ListsTest {

    @Test
    public void testLists() {
        /**
         * 一些构造List实例的方法很简单
         * 如:newArrayList(),newLinkedList()等
         * 这里不再赘述
         */
        String str = "i love u";//测试用
        String[] strs = {"i like u", "i miss u"};//测试用
        /**
         * asList:返回一个不可变的List
         * 其中包含指定的第一个元素和附加的元素数组组成
         * 修改这个数组将反映到返回的List上
         */
        List<String> list = Lists.asList(str, strs);
        System.out.println(list); //[i love u, i like u, i miss u]
        strs[1] = "i hate u";//对strs数组的修改会反映到List中
        System.out.println(list);//[i love u, i like u, i hate u]
        /**
         * transform:根据传进来的function对fromList进行相应的处理
         * 并将处理得到的结果存入到新的list对象中返回
         */
        List<String> newList = Lists.transform(list, new Function<String, String>() {
            @Override
            public String apply(String input) {
                //这里简单的对集合中的元素转换为大写
                return input.toUpperCase();
            }
        });
        System.out.println(newList);//[I LOVE U, I LIKE U, I HATE U]
        /**
         * partition:根据size传入的List进行切割,切割成符合要求的小的List
         * 并将这些小的List存入一个新的List对象中返回
         */
        List<List<String>> lists = Lists.partition(list, 2);
        System.out.println(lists);//[[i love u, i like u], [i hate u]]
        /**
         * charactersOf:将传进来的String或者CharSequence分割为单个的字符
         * 并存入到一个ImmutableList对象中返回
         * ImmutableList:一个高性能、不可变的、随机访问列表的实现
         */
        ImmutableList<Character> characters = Lists.charactersOf("realfighter");
        System.out.println(characters);//[r, e, a, l, f, i, g, h, t, e, r]
        /**
         * reverse:返回一个传入List内元素倒序后的List
         */
        List<String> reverse = Lists.reverse(list);
        System.out.println(reverse);//[i hate u, i like u, i love u]
    }

}

Sets:

Sets内部使用了静态工厂方法代替构造器,提供了许多用于Set子类构造和操作的静态方法,我们简单的依次进行说明,如下:

immutableEnumSet( E anElement, E... otherElements):返回一个包含给定枚举元素的不可变的Set实例。

immutableEnumSet( Iterable<E> elements):返回一个包含给定枚举元素的不可变的Set实例。

newEnumSet(Iterable<E> iterable,Class<E> elementType):返回一个包含给定元素的EnumSet实例,与EnumSet#copyOf(Collection)方法不同,当给定集合为 空的时候,不会产生异常,它可以转换任何实现了Iterable接口的类,不仅仅是Collection。它会先根据传入的元素类型创建一个空的 EnumSet,再把给定的元素添加到EnumSet返回。

newHashSet():返回一个可变的空的HashSet实例。

newHashSet(E... elements):返回一个可变买的HashSet包含给定的元素。

newHashSetWithExpectedSize(int expectedSize):构造一个期望长度为expectedSize的HashSet实例。

newHashSet(Iterable<? extends E> elements):返回一个可变的HashSet包含给定的元素,给定元素实现Iterable接口。

newHashSet(Iterator<? extends E> elements):返回一个可变的HashSet包含给定的元素,给定元素实现Iterator接口。

newConcurrentHashSet():创建一个线程安全的Set,由ConcurrentHashMap的实例支持,因此进行了相同的并发性担保,与HashSet不同的是,这个Set不允许null元素,该Set是可序列化的。

newConcurrentHashSet( Iterable<? extends E> elements):创建一个线程安全的Set,包含给定的元素,由ConcurrentHashMap的实例支持,因此进行了相同的并发性担保,与 HashSet不同的是,这个Set不允许null元素,该Set是可序列化的。

newLinkedHashSet():创建一个可变的、空的LinkedHashSet实例。

newLinkedHashSetWithExpectedSize( int expectedSize):构造一个期望长度为expectedSize的LinkedHashSet实例。

newLinkedHashSet( Iterable<? extends E> elements):构造一个包含给定元素的LinkedHashSet实例。

newTreeSet():返回一个可变的空的TreeSet实例。

newTreeSet( Iterable<? extends E> elements):返回一个可变的包含给定元素的TreeSet实例。

newTreeSet(Comparator<? super E> comparator):创建一个具有给定的比较器可变TreeSet的实例。

newIdentityHashSet():创建一个空的Set,使用特性来确定是否相等。

newCopyOnWriteArraySet():创建一个空的CopyOnWriteArraySet实例。

newCopyOnWriteArraySet( Iterable<? extends E> elements):创建一个包含给定元素的CopyOnWriteArraySet实例。

complementOf(Collection<E> collection):创建一个EnumSet包括不属于指定集合中的所有枚举值。

complementOf( Collection<E> collection, Class<E> type):创建一个EnumSet包括不属于指定集合中的所有枚举值。

newSetFromMap(Map<E, Boolean> map):返回一个由给定map支持的Set。

union( final Set<? extends E> set1, final Set<? extends E> set2):返回两个set集合的并集的不可修改SetView。(若A和B是集合,则A和B并集是有所有A的元素和所有B的元素,而没有其他元素的集 合)

intersection( final Set<E> set1, final Set<?> set2):返回两个set集合的交集的不可修改SetView。(两个集合A 和 集合B 的交集是指含有所有既属于 A 又属于 B 的元素,而没有其他元素的集合)

difference( final Set<E> set1, final Set<?> set2):返回两个set集合的差的不可修改SetView。(A,B是两个集合,则所有属于A且不属于B的元素构成的集合,叫做A与B的差集)

symmetricDifference( Set<? extends E> set1, Set<? extends E> set2):返回两个set集合的对称差的不可修改SetView。(对称差,即两个集合的对称差是只属于其中一个集合,而不属于另一个集合的元素组成的 集合)

filter(Set<E> unfiltered, Predicate<? super E> predicate):返回传入Set集合unfiltered中满足给定Predicate的元素集合Set。

filter( SortedSet<E> unfiltered, Predicate<? super E> predicate):返回传入SortedSet集合unfiltered中满足给定Predicate的元素集合SortedSet。

filter( NavigableSet<E> unfiltered, Predicate<? super E> predicate):返回传入NavigableSet集合unfiltered中满足给定Predicate的元素集合NavigableSet。

cartesianProduct( List<? extends Set<? extends B>> sets):返回通过从各给定集中选择一个元素所形成每一个可能的集合。

cartesianProduct( Set<? extends B>... sets):返回通过从各给定集中选择一个元素所形成每一个可能的集合。

powerSet(Set<E> set):返回一个set,包含给定set的所有可能父级集合。

unmodifiableNavigableSet( NavigableSet<E> set):返回指定NavigableSet的不可修改视图。

synchronizedNavigableSet( NavigableSet<E> navigableSet):返回一个同步的(线程安全的)NavigableSet,由指定的NavigableSet支持。

Sets类中提供的方法很多,我们这里对其中的一些重点和特别的方法做一些示例学习,其他的方法不再赘述,示例代码如下:

/**
 * Sets:处理Set实例的实用类
 * User: Realfighter
 * Date: 2014/9/3
 * Time: 20:00
 */
public class SetsTest {

    Set<Integer> set1;//测试用
    Set<Integer> set2;//测试用

    /**
     * 初始化测试集合
     */
    @Before
    public void setUp() {
        set1 = Sets.newHashSet(1, 2, 3, 4, 5);
        set2 = Sets.newHashSet(1, 3, 5, 7, 9);
    }

    /**
     * filter:返回传入Set集合unfiltered中满足给定Predicate的元素集合Set
     */
    @Test
    public void testFilter() {
        Set<String> set = Sets.newHashSet("i like u", "i miss u", "i love u");
        Predicate<String> predicate = new Predicate<String>() {
            @Override
            public boolean apply(String input) {
                //过滤包含字母l的元素
                return input.contains("l");
            }
        };
        //输出:[i like u, i love u]
        System.out.println(Sets.filter(set, predicate));
    }

    /**
     * difference:返回两个set集合的差的不可修改SetView
     * A,B是两个集合,则所有属于A且不属于B的元素构成的集合,叫做A与B的差集
     */
    @Test
    public void testDifference() {
        //输出:[2, 4]
        System.out.println(Sets.difference(set1, set2));
    }

    /**
     * symmetricDifference:返回两个set集合的对称差的不可修改SetView
     * 对称差,即两个集合的对称差是只属于其中一个集合,而不属于另一个集合的元素组成的集合
     */
    @Test
    public void testSymmetricDifference() {
        //输出:[2, 4, 9, 7]
        System.out.println(Sets.symmetricDifference(set1, set2));
    }

    /**
     * intersection:返回两个set集合的交集的不可修改SetView
     * 两个集合A和集合B的交集是指含有所有既属于A又属于B的元素,而没有其他元素的集合
     */
    @Test
    public void testIntersection() {
        //输出:[1, 3, 5]
        System.out.println(Sets.intersection(set1, set2));
    }

    /**
     * Union:返回两个set集合的并集的不可修改SetView
     * 若A和B是集合,则A和B并集是有所有A的元素和所有B的元素,而没有其他元素的集合
     */
    @Test
    public void testUnion() {
        //输出:[1, 2, 3, 4, 5, 9, 7]
        System.out.println(Sets.union(set1, set2));
    }

    /**
     * cartesianProduct:返回通过从各给定集中选择一个元素所形成每一个可能的集合
     */
    @Test
    public void testCartesianProduct() {
        Set<String> set1 = Sets.newHashSet("i love u", "i hate u");
        Set<String> set2 = Sets.newHashSet("tom", "jerry");
        Set<List<String>> sets = Sets.cartesianProduct(set1, set2);
        //输出:[[i hate u, tom], [i hate u, jerry], [i love u, tom], [i love u, jerry]]
        System.out.println(sets);
    }

    /**
     * powerSet:返回一个set,包含给定set的所有可能父级集合
     */
    @Test
    public void testPowerSet() {
        Set<String> set1 = Sets.newHashSet("i love u", "i hate u");
        Set<Set<String>> sets = Sets.powerSet(set1);
        for (Set<String> set : sets) {
            System.out.print(set);
        }
        //输出:[][i hate u][i love u][i hate u, i love u]
    }

}

Maps:

immutableEnumMap( Map<K, ? extends V> map):返回包含给定项的不可变映射实例。

newHashMap():构造一个可变的空的HashMap实例。

newHashMapWithExpectedSize(int expectedSize):构造一个期望长度为expectedSize的HashMap实例。

newHashMap( Map<? extends K, ? extends V> map):构造一个与给定map有相同映射关系的可变HashMap实例。

newLinkedHashMap():构造一个可变的、空的、插入排序的LinkedHashMap实例。

newLinkedHashMap( Map<? extends K, ? extends V> map):构造一个可变的、插入排序的、与给定map有相同映射关系的LinkedHashMap实例。

newConcurrentMap():返回一个通用的ConcurrentMap实例,支持ConcurrentMap接口的所有可选操作,它不允许null键或值,它是可序列化的。

newTreeMap():构造一个可变的、空的TreeMap实例。

newTreeMap(SortedMap<K, ? extends V> map):构造一个可变的、与给定SortedMap有相同映射关系的TreeMap实例。

newTreeMap( @Nullable Comparator<C> comparator):构造一个可变的、空的、使用给定比较器的TreeMap实例。

newEnumMap(Class<K> type):构造一个具有给定键类型的EnumMap实例。

newEnumMap( Map<K, ? extends V> map):构造一个与给定map有相同映射关系的EnumMap实例。

newIdentityHashMap():构造一个IdentityHashMap实例。

difference( Map<? extends K, ? extends V> left, Map<? extends K, ? extends V> right):返回两个给定map之间的差异。

difference( Map<? extends K, ? extends V> left, Map<? extends K, ? extends V> right, Equivalence<? super V> valueEquivalence):返回两个给定map之间的差异,通过所提供的valueEquivalence进行等值比较。

difference( SortedMap<K, ? extends V> left, Map<? extends K, ? extends V> right):返回两个已排序的Map之间的差异,通过给定left的比较器。

asMap( Set<K> set, Function<? super K, V> function):返回一个活动的map,键值为给定的set中的值,value为通过给定Function计算后的值。

asMap( SortedSet<K> set, Function<? super K, V> function):返回有序Set集合的map表示,根据给定的Function从给定的Set中映射键值。

asMap( NavigableSet<K> set, Function<? super K, V> function):返回NavigableSet集合的map表示,根据给定的Function从给定的Set中映射键值。

toMap(Iterable<K> keys,Function<? super K, V> valueFunction)、toMap(Iterator<K> keys,Function<? super K, V> valueFunction):返回一个不可变的ImmutableMap实例,其键值为给定keys中去除重复值后的值,其值为键被计算了 valueFunction后的值。

uniqueIndex(Iterable<V> values, Function<? super V, K> keyFunction)、uniqueIndex(Iterator<V> values, Function<? super V, K> keyFunction):返回一个不可变的ImmutableMap实例,其值为按照给定顺序的给定的values值,键值为相应的值经过给定 Function计算后的值。

fromProperties(Properties properties):通过给定的Properties实例,返回一个不可变的ImmutableMap实例。

immutableEntry(@Nullable K key, @Nullable V value):通过给定的key/value,返回一个不可变的map映射。

asConverter(final BiMap<A, B> bimap):返回一个Converter转换器,通过bimap.get()方法转换值,它的逆视图使用bimap.inverse().get()方法转换值。

synchronizedBiMap(BiMap<K, V> bimap):返回一个同步的(线程安全)的bimap,由给定的bimap支持。

unmodifiableBiMap( BiMap<? extends K, ? extends V> bimap):返回给定的bimap的不可修改的BiMap表示。

transformValues( Map<K, V1> fromMap, Function<? super V1, V2> function):返回一个map映射,其键值为给定fromMap的键值,其value为给定formMap中value通过Function转换后 的值。

transformValues( SortedMap<K, V1> fromMap, Function<? super V1, V2> function):返回一个SortedMap映射,其键值为给定fromMap的键值,其value为给定formMap中value通过 Function转换后的值。

transformValues( NavigableMap<K, V1> fromMap, Function<? super V1, V2> function):返回一个NavigableMap映射,其键值为给定fromMap的键值,其value为给定formMap中value通过 Function转换后的值。

transformEntries( Map<K, V1> fromMap, EntryTransformer<? super K, ? super V1, V2> transformer):返回一个map映射,其Entry为给定fromMap.Entry通过给定EntryTransformer转换后的值。

transformEntries(SortedMap<K, V1> fromMap, EntryTransformer<? super K, ? super V1, V2> transformer):返回一个SortedMap映射,其Entry为给定fromMap.Entry通过给定EntryTransformer转 换后的值。

transformEntries( final NavigableMap<K, V1> fromMap,EntryTransformer<? super K, ? super V1, V2> transformer):返回一个NavigableMap映射,其Entry为给定fromMap.Entry通过给定 EntryTransformer转换后的值。

filterKeys(Map<K, V> unfiltered, final Predicate<? super K> keyPredicate):返回给定unfilteredMap中的键值通过给定keyPredicate过滤后的map映射。

filterKeys(SortedMap<K, V> unfiltered, final Predicate<? super K> keyPredicate):返回给定unfilteredMap中的键值通过给定keyPredicate过滤后的SortedMap映射。

filterKeys(NavigableMap<K, V> unfiltered, final Predicate<? super K> keyPredicate):返回给定unfilteredMap中的键值通过给定keyPredicate过滤后的NavigableMap映射。

filterKeys(BiMap<K, V> unfiltered, final Predicate<? super K> keyPredicate):返回给定unfilteredMap中的键值通过给定keyPredicate过滤后的BiMap映射。

filterValues( Map<K, V> unfiltered, final Predicate<? super V> valuePredicate):返回给定unfilteredMap中的value值通过给定keyPredicate过滤后的map映射。

filterValues(SortedMap<K, V> unfiltered, final Predicate<? super V> valuePredicate):返回给定unfilteredMap中的value值通过给定keyPredicate过滤后的SortedMap映 射。

filterValues(NavigableMap<K, V> unfiltered, final Predicate<? super V> valuePredicate):返回给定unfilteredMap中的value值通过给定keyPredicate过滤后的 NavigableMap映射。

filterValues(BiMap<K, V> unfiltered, final Predicate<? super V> valuePredicate):返回给定unfilteredMap中的value值通过给定keyPredicate过滤后的BiMap映射。

filterEntries( Map<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate):返回给定unfilteredMap.Entry中的Entry值通过给定entryPredicate过滤后的map 映射。

filterEntries( SortedMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate):返回给定unfilteredMap.Entry中的Entry值通过给定entryPredicate过滤后的 SortedMap映射。

filterEntries( NavigableMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate):返回给定unfilteredMap.Entry中的Entry值通过给定entryPredicate过滤后的 NavigableMap映射。

filterEntries( BiMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate):返回给定unfilteredMap.Entry中的Entry值通过给定entryPredicate过滤后的 BiMap映射。

unmodifiableNavigableMap(NavigableMap<K, V> map):返回给定map的不可修改NavigableMap表示。

synchronizedNavigableMap( NavigableMap<K, V> navigableMap):返回一个同步的(线程安全)的NavigableMap,由给定的navigableMap支持。

Maps类中提供的方法很多,对其中的一些方法也是一知半解,需要慢慢摸索,这里对其中的一些重点和特别的方法做一些示例学习,其他的方法不再赘述,示例代码如下:

/**
 * Maps:处理Map实例的实用类
 * Maps里面方法很多,一知半解,慢慢摸索
 * User: Realfighter
 * Date: 2014/9/5
 * Time: 15:11
 */
public class MapsTest {

    @Test
    public void testMaps() {
        /**
         * difference:返回两个给定map之间的差异。
         */
        Map<String, String> map1 = new HashMap<String, String>() {
            {
                put("a", "1");
            }
        };
        Map<String, String> map2 = new HashMap<String, String>() {
            {
                put("b", "2");
            }
        };
        Map<String, String> map3 = new HashMap<String, String>() {
            {
                put("a", "3");
            }
        };
        //输出:not equal: only on left={a=1}: only on right={b=2}
        System.out.println(Maps.difference(map1, map2));
        //输出:not equal: value differences={a=(1, 3)}
        System.out.println(Maps.difference(map1, map3));
        /**
         * asMap:返回一个活动的map
         * 键值为给定的set中的值
         * value为通过给定Function计算后的值。
         */
        Set<String> set = Sets.newHashSet("a", "b", "c");
        //Function:简单的对元素做大写转换,下面示例多次使用
        Function<String, String> function = new Function<String, String>() {
            @Override
            public String apply(String input) {
                return input.toUpperCase();
            }
        };
        //输出:{b=B, c=C, a=A}
        System.out.println(Maps.asMap(set, function));
        /**
         * toMap:返回一个不可变的ImmutableMap实例
         * 其键值为给定keys中去除重复值后的值
         * 其值为键被计算了valueFunction后的值
         */
        List<String> keys = Lists.newArrayList("a", "b", "c", "a");
        //输出:{a=A, b=B, c=C}
        System.out.println(Maps.toMap(keys, function));
        /**
         * uniqueIndex:返回一个不可变的ImmutableMap实例,
         * 其value值为按照给定顺序的给定的values值
         * 键值为相应的值经过给定Function计算后的值
         */
        List<String> values = Lists.newArrayList("a", "b", "c", "d");
        /**
         * 注:这里的value值不可重复,重复的话在转换后会抛出异常:
         * IllegalArgumentException: Multiple entries with same key
         */
        //输出:{A=a, B=b, C=c, D=d}
        System.out.println(Maps.uniqueIndex(values, function));
        /**
         * transformValues:返回一个map映射
         * 其键值为给定fromMap的键值
         * 其value为给定formMap中value通过Function转换后的值
         */
        Map<String, Boolean> fromMap = Maps.newHashMap();
        fromMap.put("key", true);
        fromMap.put("value", false);
        //输出:{value=true, key=false}
        System.out.println(Maps.transformValues(fromMap, new Function<Boolean, Object>() {
            @Override
            public Object apply(Boolean input) {
                //对传入的元素取反
                return !input;
            }
        }));
        /**
         * transformEntries:返回一个map映射
         * 其Entry为给定fromMap.Entry通过给定EntryTransformer转换后的值
         */
        Maps.EntryTransformer<String, Boolean, String> entryTransformer = new Maps.EntryTransformer<String, Boolean, String>() {
            public String transformEntry(String key, Boolean value) {
                //value为假,则key变大写
                return value ? key : key.toUpperCase();
            }
        };
        //输出:{value=VALUE, key=key}
        System.out.println(Maps.transformEntries(fromMap, entryTransformer));
        /**
         * filterKeys:返回给定unfilteredMap中的键值通过给定keyPredicate过滤后的map映射
         */
        //输出:{key=true}
        System.out.println(Maps.filterKeys(fromMap, new Predicate<String>() {
            @Override
            public boolean apply(String input) {
                //过滤Map中键值包含字母y的元素
                return input.contains("y");
            }
        }));
        /**
         * filterValues:返回给定unfilteredMap中的value值通过给定keyPredicate过滤后的map映射
         */
        //输出:{value=false}
        System.out.println(Maps.filterValues(fromMap, new Predicate<Boolean>() {
            @Override
            public boolean apply(Boolean input) {
                //过滤Map中value值为假的元素
                return !input;
            }
        }));
        /**
         * filterEntries:返回给定unfilteredMap.Entry中的Entry值通过给定entryPredicate过滤后的map映射
         */
        //输出:{key=true}
        System.out.println(Maps.filterEntries(fromMap, new Predicate<Map.Entry<String, Boolean>>() {
            @Override
            public boolean apply(Map.Entry<String, Boolean> input) {
                //过滤Map.Entry中getValue()为真的元素
                return input.getValue();
            }
        }));
    }

}
Multimaps:想 Map<String, List<StudentScore>> StudentScoreMap = new HashMap<String, List<StudentScore>>()这样的数据结构,自己实现起来太麻烦,你需要检查key是否存在,不存在时则创建一个,存在时在List后面添加上一个。这个过程是比较痛苦的,如果你希望检查List中的对象是否存在,删除一个对象,或者遍历整个数据结构,那么则需要更多的代码来实现。
import java.util.Collection;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;

public class MutliMapTest {
    public static void main(String... args) {
        Multimap<String, String> myMultimap = ArrayListMultimap.create();

        // Adding some key/value
        myMultimap.put("Fruits", "Bannana");
        myMultimap.put("Fruits", "Apple");
        myMultimap.put("Fruits", "Pear");
        myMultimap.put("Fruits", "Pear");
        myMultimap.put("Vegetables", "Carrot");

        // Getting the size
        int size = myMultimap.size();
        System.out.println(size); // 5

        // Getting values
        Collection<String> fruits = myMultimap.get("Fruits");
        System.out.println(fruits); //  [Bannana, Apple, Pear, Pear]
        System.out.println(ImmutableSet.copyOf(fruits));// [Bannana, Apple, Pear]
        // Set<Foo> set = Sets.newHashSet(list);
        // Set<Foo> foo = new HashSet<Foo>(myList);

        Collection<String> vegetables = myMultimap.get("Vegetables");
        System.out.println(vegetables); // [Carrot]

        // Iterating over entire Mutlimap
        for (String value : myMultimap.values()) {
            System.out.println(value);
        }

        // Removing a single value
        myMultimap.remove("Fruits", "Pear");
        System.out.println(myMultimap.get("Fruits")); // [Bannana, Apple, Pear]

        // Remove all values for a key
        myMultimap.removeAll("Fruits");
        System.out.println(myMultimap.get("Fruits")); // [] (Empty Collection!)
    }
}

如果你需要基于multimap直接操作list或者set,那么可以使用在定义类型的时候使用子类名称:ListMultimap,SetMultimap和SortedSetMultimap。例如:

ListMutlimap<String,String> myMutlimap = ArrayListMultimap.create();

List<string> myValues = myMutlimap.get("myKey");  // Returns a List, not a Collection.

BiMap:BiMap提供了一种新的集合类型,它提供了key和value的双向关联的数据结构。通常情况下,我们在使用Java的Map时,往往是通过key来查找value的,但是如果出现下面一种场景的情况,我们就需要额外编写一些代码了:value查key。

     BiMap<Integer,String> logfileMap = HashBiMap.create();
        logfileMap.put(1,"a.log");
        logfileMap.put(2,"b.log");
        logfileMap.put(3,"c.log");
        System.out.println("logfileMap:"+logfileMap);
        BiMap<String,Integer> filelogMap = logfileMap.inverse();
        System.out.println("filelogMap:"+filelogMap);

在使用BiMap时,会要求Value的唯一性。如果value重复了则会抛出错误:java.lang.IllegalArgumentException。如果我们确实需要插入重复的value值,那可以选择forcePut方法。但是我们需要注意的是前面的key也会被覆盖了。inverse方法会返回一个反转的BiMap,但是注意这个反转的map不是新的map对象,它实现了一种视图关联,这样你对于反转后的map的所有操作都会影响原先的map对象。
 
Multiset:Multiset是什么?顾名思义,Multiset和Set的区别就是可以保存多个相同的对象。在JDK中,List和Set有一个基本的区别,就是List可以包含多个相同对象,且是有顺序的,而Set不能有重复,且不保证顺序(有些实现有顺序,例如LinkedHashSet和SortedSet等)所以Multiset占据了List和Set之间的一个灰色地带:允许重复,但是不保证顺序。 常见使用场景:Multiset有一个有用的功能,就是跟踪每种对象的数量,所以你可以用来进行数字统计。实现方式如下:

String strWorld="wer|dfd|dd|dfd|dda|de|dr";
        String[] words=strWorld.split("\\|");
        List<String> wordList=new ArrayList<String>();
        for (String word : words) {
            wordList.add(word);
        }
        Multiset<String> wordsMultiset = HashMultiset.create();
        wordsMultiset.addAll(wordList);
        for(String key:wordsMultiset.elementSet()){
            System.out.println(key+" count:"+wordsMultiset.count(key));
        }
上面的代码实现的功能非常简单,用于记录字符串在数组中出现的次数。这种场景在实际的开发过程还是容易经常出现的。

Multiset主要方法

  Multiset接口定义的接口主要有:
    add(E element) :向其中添加单个元素
    add(E element,int occurrences) : 向其中添加指定个数的元素
    count(Object element) : 返回给定参数元素的个数
    remove(E element) : 移除一个元素,其count值 会响应减少
    remove(E element,int occurrences): 移除相应个数的元素
    elementSet() : 将不同的元素放入一个Set中
    entrySet(): 类似与Map.entrySet 返回Set<Multiset.Entry>。包含的Entry支持使用getElement()和getCount()
    setCount(E element ,int count): 设定某一个元素的重复次数
    setCount(E element,int oldCount,int newCount): 将符合原有重复个数的元素修改为新的重复次数
    retainAll(Collection c) : 保留出现在给定集合参数的所有的元素 
    removeAll(Collectionc) : 去除出现给给定集合参数的所有的元素

public void testMultsetWordCount(){
        String strWorld="wer|dfd|dd|dfd|dda|de|dr";
        String[] words=strWorld.split("\\|");
        List<String> wordList=new ArrayList<String>();
        for (String word : words) {
            wordList.add(word);
        }
        Multiset<String> wordsMultiset = HashMultiset.create();
        wordsMultiset.addAll(wordList);

        //System.out.println("wordsMultiset:"+wordsMultiset);

        for(String key:wordsMultiset.elementSet()){
            System.out.println(key+" count:"+wordsMultiset.count(key));
        }

        if(!wordsMultiset.contains("peida")){
            wordsMultiset.add("peida", 2);
        }
        System.out.println("============================================");
        for(String key:wordsMultiset.elementSet()){
            System.out.println(key+" count:"+wordsMultiset.count(key));
        }

        if(wordsMultiset.contains("peida")){
            wordsMultiset.setCount("peida", 23);
        }

        System.out.println("============================================");
        for(String key:wordsMultiset.elementSet()){
            System.out.println(key+" count:"+wordsMultiset.count(key));
        }

        if(wordsMultiset.contains("peida")){
            wordsMultiset.setCount("peida", 23,45);
        }

        System.out.println("============================================");
        for(String key:wordsMultiset.elementSet()){
            System.out.println(key+" count:"+wordsMultiset.count(key));
        }

        if(wordsMultiset.contains("peida")){
            wordsMultiset.setCount("peida", 44,67);
        }

        System.out.println("============================================");
        for(String key:wordsMultiset.elementSet()){
            System.out.println(key+" count:"+wordsMultiset.count(key));
        }
    }

输出:
de count:1
dda count:1
dd count:1
dfd count:2
wer count:1
dr count:1
============================================
de count:1
dda count:1
dd count:1
dfd count:2
peida count:2
wer count:1
dr count:1
============================================
de count:1
dda count:1
dd count:1
dfd count:2
peida count:23
wer count:1
dr count:1
============================================
de count:1
dda count:1
dd count:1
dfd count:2
peida count:45
wer count:1
dr count:1
============================================
de count:1
dda count:1
dd count:1
dfd count:2
peida count:45
wer count:1
dr count:1

说明:setCount(E element,int oldCount,int newCount): 方法,如果传入的oldCount和element的不一致的时候,是不能讲element的count设置成newCount的。需要注意。

Multiset不是Map

  需要注意的是Multiset不是一个Map<E,Integer>,尽管Multiset提供一部分类似的功能实现。其它值得关注的差别有:
  Multiset中的元素的重复个数只会是正数,且最大不会超过Integer.MAX_VALUE。设定计数为0的元素将不会出现multiset中,也不会出现elementSet()和entrySet()的返回结果中。
  multiset.size() 方法返回的是所有的元素的总和,相当于是将所有重复的个数相加。如果需要知道每个元素的个数可以使用elementSet().size()得到.(因而调用add(E)方法会是multiset.size()增加1).
  multiset.iterator() 会循环迭代每一个出现的元素,迭代的次数与multiset.size()相同。 iterates over each occurrence of each element, so the length of the iteration is equal to multiset.size().
  Multiset 支持添加、移除多个元素以及重新设定元素的个数。执行setCount(element,0)相当于移除multiset中所有的相同元素。
  调用multiset.count(elem)方法时,如果该元素不在该集中,那么返回的结果只会是0。


 
时间: 2024-10-13 11:54:30

guava学习--集合1的相关文章

guava学习--集合2

Table: 当我们需要多个索引的数据结构的时候,通常情况下,我们只能用这种丑陋的Map<FirstName, Map<LastName, Person>>来实现.为此Guava提供了一个新的集合类型-Table集合类型,来支持这种数据结构的使用场景.Table支持"row"和"column",而且提供多种视图. Table<String, Integer, String> aTable = HashBasedTable.crea

Guava学习笔记: guava集合之Multiset

Guava学习笔记: guava集合之Multiset Multiset是什么? Multiset看似是一个Set,但是实质上它不是一个Set,它没有继承Set接口,它继承的是Collection<E>接口,你可以向Multiset中添加重复的元素,Multiset会对添加的元素做一个计数. 它本质上是一个Set加一个元素计数器. Multiset使用示例: package cn.outofmemory.guava.collection; import com.google.common.ba

Guava学习笔记:guava的不可变集合

Guava学习笔记:guava的不可变集合 不可变集合的意义 不可变对象有很多优点,包括: 当对象被不可信的库调用时,不可变形式是安全的: 不可变对象被多个线程调用时,不存在竞态条件问题 不可变集合不需要考虑变化,因此可以节省时间和空间.所有不可变的集合都比它们的可变形式有更好的内存利用率(分析和测试细节): 不可变对象因为有固定不变,可以作为常量来安全使用. 创建对象的不可变拷贝是一项很好的防御性编程技巧.Guava为所有JDK标准集合类型和Guava新集合类型都提供了简单易用的不可变版本. 

[Guava学习笔记]Collections: 不可变集合, 新集合类型

不可变集合 不接受null值. 创建:ImmutableSet.copyOf(set); ImmutableMap.of(“a”, 1, “b”, 2); public static final ImmutableSet<Color> GOOGLE_COLORS = ImmutableSet.<Color>builder() .addAll(WEBSAFE_COLORS) .add(new Color(0, 191, 255)) .build(); 可以有序(如ImmutableS

Guava学习笔记:Google Guava 类库简介

> Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, 等等. 这些高质量的 API 可以使你的JAVa代码更加优雅,更加简洁,让你工作更加轻松愉悦.下面我们就开启优雅Java编程学习之旅! 项目相关信息: 官方首页:http://code.googl

Guava学习笔记: BiMap

Guava学习笔记: BiMap 我们知道Map是一种键值对映射,这个映射是键到值的映射,而BiMap首先也是一种Map,他的特别之处在于,既提供键到值的映射,也提供值到键的映射,所以它是双向Map. 想象这么一个场景,我们需要做一个星期几的中英文表示的相互映射,例如Monday对应的中文表示是星期一,同样星期一对应的英文表示是Monday.这是一个绝好的使用BiMap的场景. package cn.outofmemory.guava.collection; import com.google.

Guava学习

Guava学习笔记目录 Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, 等等. 这些高质量的 API 可以使你的JAVa代码更加优雅,更加简洁,让你工作更加轻松愉悦.下面是学习过程中的一些笔记和知识点的记录. 1.Guava学习笔记:Google

[Guava学习笔记]Basic Utilities: Null, 前置条件, Object方法, 排序, 异常

我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3842433.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验. Null Guava用Optional表示可能为null的T类型引用. 创建:Optional.of(T)不接受null Optional.fromNullable(T)接受null Optional.absent() 查询:isPresent() get() or(T)如果为null则为T o

Guava学习笔记:Range

Guava学习笔记:Range 转载:http://www.cnblogs.com/peida/p/Guava_Range.html 在Guava中新增了一个新的类型Range,从名字就可以了解到,这个是和区间有关的数据结构.从Google官方文档可以得到定义:Range定义了连续跨度的范围边界,这个连续跨度是一个可以比较的类型(Comparable type).比如1到100之间的整型数据. 在数学里面的范围是有边界和无边界之分的:同样,在Guava中也有这个说法.如果这个范围是有边界的,那么