guava学习--集合1

时间:2021-07-18 20:46:35

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。