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。