1. Classes with useful static methods for working with lists, maps and sets
2. The Range class used to represent the boundaries around a continuous set of values
3. Immutable Collections
4. Bimaps
5. The Table collection type, which is a very powerful collection that is a replacement for using a map of maps.
6. Multimaps, which allow us to have more than one value associated with unique key.
7. The FluentIterable class, which represents a set of powerful interfaces for working with Iterable instances.
8. The Ordering class that gives us enhanced abilities when working with Comparators
1. FluentIterable
The FluentIterable class represents a powerful interface for working with Iterable instances in fluent style of programming.
The fluent programming style allows us to chain method calls together, making for a more readable code.
1> FluentIterable.filter(Predicate<T>)
@Test public void filterTest() { List<String> list = Lists.newArrayList("A", "B", "C", "D"); List<String> filteredList = FluentIterable.from(list) .filter(Predicates.and(new Predicate<String>() { public boolean apply(String input) { return "A".compareTo(input) < 0; } }, new Predicate<String>() { public boolean apply(String input) { return "D".compareTo(input) > 0; } })).toList(); assertEquals(2, filteredList.size()); assertEquals("B", filteredList.get(0)); assertEquals("C", filteredList.get(1)); }
source code:
public static <E> FluentIterable<E> from(final Iterable<E> iterable) { return (iterable instanceof FluentIterable) ? (FluentIterable<E>) iterable : new FluentIterable<E>(iterable) { @Override public Iterator<E> iterator() { return iterable.iterator(); } }; } FluentIterable(Iterable<E> iterable) { this.iterable = checkNotNull(iterable); // set passed in iterable as property } public final FluentIterable<E> filter(Predicate<? super E> predicate) { return from(Iterables.filter(iterable, predicate)); } public static <T> UnmodifiableIterator<T> filter( final Iterator<T> unfiltered, final Predicate<? super T> predicate) { return new AbstractIterator<T>() { @Override protected T computeNext() { while (unfiltered.hasNext()) { T element = unfiltered.next(); if (predicate.apply(element)) { return element; } } return endOfData(); } }; }
2> FluentIterable.transform(Function<F, T>)
@Test public void transformTest() { List<String> list = Lists.newArrayList("A", "B", "C", "D", "E"); Map<String, String> map = Maps.newHashMap(); map.put("A", "A for Alcohol"); map.put("B", "B for Boycott"); map.put("C", "C for Combine"); List<String> transformedList = FluentIterable.from(list) .transform(Functions.forMap(map, "Not Defined")).toList(); List<String> expectedList = Lists.newArrayList("A for Alcohol", "B for Boycott", "C for Combine", "Not Defined", "Not Defined"); assertEquals(expectedList, transformedList); }
source code:
public final <T> FluentIterable<T> transform(Function<? super E, T> function) { return from(Iterables.transform(iterable, function)); } public static <F, T> Iterable<T> transform(final Iterable<F> fromIterable, final Function<? super F, ? extends T> function) { return new FluentIterable<T>() { @Override public Iterator<T> iterator() { return Iterators.transform(fromIterable.iterator(), function); } }; } public static <F, T> Iterator<T> transform(final Iterator<F> fromIterator, final Function<? super F, ? extends T> function) { return new TransformedIterator<F, T>(fromIterator) { @Override T transform(F from) { return function.apply(from); } }; }
2. Lists
1> Lists.newXXXList(): Factory method to simplify the creation of Generic Collection
public static <E> ArrayList<E> newArrayList(E... elements) { int capacity = computeArrayListCapacity(elements.length); ArrayList<E> list = new ArrayList<E>(capacity); Collections.addAll(list, elements); return list; }
2> Lists.partition()
@Test public void partitionTest() { List<String> strList = Lists.newArrayList("A", "B", "C", "D"); List<List<String>> partedStrList = Lists.partition(strList, 2); assertEquals(2, partedStrList.size()); assertEquals(2, partedStrList.get(0).size()); assertEquals(2, partedStrList.get(1).size()); partedStrList = Lists.partition(strList, 3); assertEquals(2, partedStrList.size()); assertEquals(3, partedStrList.get(0).size()); assertEquals(1, partedStrList.get(1).size()); }
source code:
public static <T> List<List<T>> partition(List<T> list, int size) { return (list instanceof RandomAccess) ? new RandomAccessPartition<T>(list, size) : new Partition<T>(list, size); } 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) { 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(); } }
3. Sets
1> Sets.newXXXSet(): Factory method to simplify the creation of Generic Collection
public static <E> HashSet<E> newHashSet(E... elements) { HashSet<E> set = newHashSetWithExpectedSize(elements.length); Collections.addAll(set, elements); return set; }
2> Sets.difference and Sets.intersection and Sets.union
@Test public void partitionTest() { Set<String> strSet1 = Sets.newHashSet("A", "B", "C", "D"); Set<String> strSet2 = Sets.newHashSet("D", "M", "O", "G"); Set<String> diffSet = Sets.difference(strSet1, strSet2); assertEquals(3, diffSet.size()); Set<String> interSet = Sets.intersection(strSet1, strSet2); assertEquals(1, interSet.size()); Set<String> unionSet = Sets.union(strSet1, strSet2); assertEquals(7, unionSet.size()); }
source code:
public static <E> SetView<E> difference( final Set<E> set1, final Set<?> set2) { final Predicate<Object> notInSet2 = Predicates.not(Predicates.in(set2)); return new SetView<E>() { @Override public Iterator<E> iterator() { return Iterators.filter(set1.iterator(), notInSet2); } @Override public int size() { return Iterators.size(iterator()); } @Override public boolean isEmpty() { return set2.containsAll(set1); } @Override public boolean contains(Object element) { return set1.contains(element) && !set2.contains(element); } }; }
public static <E> SetView<E> intersection( final Set<E> set1, final Set<?> set2) { final Predicate<Object> inSet2 = Predicates.in(set2); return new SetView<E>() { @Override public Iterator<E> iterator() { return Iterators.filter(set1.iterator(), inSet2); } @Override public int size() { return Iterators.size(iterator()); } @Override public boolean isEmpty() { return !iterator().hasNext(); } @Override public boolean contains(Object object) { return set1.contains(object) && set2.contains(object); } @Override public boolean containsAll(Collection<?> collection) { return set1.containsAll(collection) && set2.containsAll(collection); } }; }
public static <E> SetView<E> union( final Set<? extends E> set1, final Set<? extends E> set2) { final Set<? extends E> set2minus1 = difference(set2, set1); return new SetView<E>() { @Override public int size() { return set1.size() + set2minus1.size(); } @Override public boolean isEmpty() { return set1.isEmpty() && set2.isEmpty(); } @Override public Iterator<E> iterator() { return Iterators.unmodifiableIterator( Iterators.concat(set1.iterator(), set2minus1.iterator())); } @Override public boolean contains(Object object) { return set1.contains(object) || set2.contains(object); } @Override public <S extends Set<E>> S copyInto(S set) { set.addAll(set1); set.addAll(set2); return set; } @Override public ImmutableSet<E> immutableCopy() { return new ImmutableSet.Builder<E>() .addAll(set1).addAll(set2).build(); } }; }
4. Maps
1> Maps.newXXXMap()
2> Maps.uniqueIndex(Iterator<V>, Function<V, K>)
@Test public void traditionalTest() { List<Person> personList = Lists.newArrayList(new Person("Davy", "Male", 24), new Person("Calypso", "Female", 22)); Map<String, Person> map = Maps.newHashMap(); for (Person p : personList) { map.put(p.getName(), p); } assertEquals(2, map.size()); } @Test public void uniqueIndexTest() { List<Person> personList = Lists.newArrayList(new Person("Davy", "Male", 24), new Person("Calypso", "Female", 22)); Map<String, Person> map = Maps.uniqueIndex(personList, new Function<Person, String>() { public String apply(Person input) { return input.getName(); } }); assertEquals(2, map.size()); } class Person { String name; String gender; int age; public Person(String name, String gender, int age) { super(); this.name = name; this.gender = gender; this.age = age; } public String getName() { return name; } public String getGender() { return gender; } public int getAge() { return age; } @Override public String toString() { return "Person [name=" + name + ", gender=" + gender + ", age=" + age + "]"; } }
source code:
public static <K, V> ImmutableMap<K, V> uniqueIndex( Iterable<V> values, Function<? super V, K> keyFunction) { return uniqueIndex(values.iterator(), keyFunction); } public static <K, V> ImmutableMap<K, V> uniqueIndex( Iterator<V> values, Function<? super V, K> keyFunction) { ImmutableMap.Builder<K, V> builder = ImmutableMap.builder(); while (values.hasNext()) { V value = values.next(); builder.put(keyFunction.apply(value), value); } return builder.build(); }
3> Maps.asMap(Set<K>, Function<K, V>)
The Maps.asMap method takes a set of objects to be used as keys, and Function is applied to each key to generate the value for entry into a map instance.
@Test public void asMapTest() { Set<String> nameSet = Sets.newHashSet("Davy", "Calypso"); Map<String, Person> map = Maps.asMap(nameSet, new Function<String, Person>() { public Person apply(String name) { return new Person(name, "UNKNOWN", 0); } }); assertEquals(2, map.size()); }
4> Maps.transformEntries
@Test public void transformEntriesTest() { Map<String, Person> personMap = Maps.newHashMap(); personMap.put("Davy", new Person("Davy", "Male", 24)); personMap.put("Calypso", new Person("Calypso", "Female", 22)); Map<String, People> peopleMap = Maps.transformEntries(personMap, new EntryTransformer<String, Person, People>() { public People transformEntry(String key, Person value) { return new People(value.getName(), value.getGender()); } }); assertEquals(2, peopleMap.size()); }
5. Multimaps
1> ArrayListMultimap = HashMap<K, ArrayList<V>>
2> HashMultimap = HashMap<K, HashSet<V>>
3> LinkedHashMultimap = LinkedHashMap<K, LinkedHashSet<V>>
4> TreeMultimap = TreeMap<K, TreeSet<V>>
5> LinkedListMultimap = HashMap<K, LinkedList<V>>
Q: Why the realization of LinkedListMultimap is different from others' ?
Why don't they simply extends AbstractListMultimap and then generalize method createCollection() ?
6. Exercises:
1> Filter Lists
@Test public void filterListTest() { List<String> list = Lists.newArrayList("A", "B", "C", "D"); List<String> filteredList = FluentIterable.from(list) .filter(new Predicate<String>() { @Override public boolean apply(String input) { return "A".compareTo(input) < 0; } }).toList(); List<String> expectedList = Lists.newArrayList("B", "C", "D"); assertEquals(expectedList, filteredList); List<Object> objList = Lists.<Object> newArrayList("A", "B", new Double(1.2), new Double(1.0)); List<Double> doubleList = FluentIterable.from(objList) .filter(Double.class).toList(); List<Double> expDoubleList = Lists.newArrayList(new Double(1.2), new Double(1.0)); assertEquals(expDoubleList, doubleList); }
2> Transform Lists
@Test public void transformListTest() { List<String> list = Lists.newArrayList("A", "B", "C", "D"); List<String> transformedList = FluentIterable.from(list) .transform(new Function<String, String>() { @Override public String apply(String input) { return input.concat("-Postfix"); } }).toList(); List<String> expectedList = Lists.newArrayList("A-Postfix", "B-Postfix", "C-Postfix", "D-Postfix"); assertEquals(expectedList, transformedList); transformedList = FluentIterable.from(list) .filter(new Predicate<String>() { @Override public boolean apply(String input) { return !"A".equals(input); } }).transformAndConcat(new Function<String, Iterable<String>>() { @Override public Iterable<String> apply(String input) { return Lists.newArrayList(input, input.concat("-Postfix")); } }).toList(); expectedList = Lists.newArrayList("B", "B-Postfix", "C", "C-Postfix", "D", "D-Postfix"); assertEquals(expectedList, transformedList); }
3> Filter Map
@Test public void filterMapTest() { Map<String, String> map = Maps.newHashMap(); map.put("A", "A for Alcohol"); map.put("B", "B for Boycott"); map.put("C", "C for Cowboy"); map.put("D", "D for Dodge"); Map<String, String> filteredMap = Maps.filterEntries(map, new Predicate<Map.Entry<String, String>>() { @Override public boolean apply(Entry<String, String> input) { return "A".equals(input.getKey()) && "A for Alcohol".equals(input.getValue()); } }); Map<String, String> expectedMap = Maps.newHashMap(); expectedMap.put("A", "A for Alcohol"); assertEquals(expectedMap, filteredMap); filteredMap = Maps.filterKeys(map, new Predicate<String>() { @Override public boolean apply(String input) { return input.equals("B"); } }); expectedMap = Maps.newHashMap(); expectedMap.put("B", "B for Boycott"); assertEquals(expectedMap, filteredMap); filteredMap = Maps.filterValues(map, new Predicate<String>() { @Override public boolean apply(String input) { return input.equals("C for Cowboy"); } }); expectedMap = Maps.newHashMap(); expectedMap.put("C", "C for Cowboy"); assertEquals(expectedMap, filteredMap); }
4> Transform Map
@Test public void transformMapTest() { Map<String, String> map = Maps.newHashMap(); map.put("A", "A for Alcohol"); map.put("B", "B for Boycott"); map.put("C", "C for Cowboy"); map.put("D", "D for Dodge"); Map<String, Person> transformedMap = Maps.transformValues(map, new Function<String, Person>() { @Override public Person apply(String input) { return new Person(input); } }); Map<String, Person> expectedMap = Maps.newHashMap(); expectedMap.put("A", new Person("A for Alcohol")); expectedMap.put("B", new Person("B for Boycott")); expectedMap.put("C", new Person("C for Cowboy")); expectedMap.put("D", new Person("D for Dodge")); assertEquals(expectedMap, transformedMap); transformedMap = Maps.transformEntries(map, new EntryTransformer<String, String, Person>() { @Override public Person transformEntry(String key, String value) { return "A".equals(key) ? new Person(key) : new Person( value); } }); expectedMap = Maps.newHashMap(); expectedMap.put("A", new Person("A")); expectedMap.put("B", new Person("B for Boycott")); expectedMap.put("C", new Person("C for Cowboy")); expectedMap.put("D", new Person("D for Dodge")); assertEquals(expectedMap, transformedMap); }
5> Add element into ImmutableList/ImmutableSet/ImmutableMap
@Test public void test() { List<String> list = Lists.newArrayList("A", "B", "C", "D", "E"); List<String> filteredList = FluentIterable.from(list) .filter(new Predicate<String>() { @Override public boolean apply(String input) { return "A".equals(input) || "D".equals(input); } }).toList(); filteredList = ImmutableList.<String> builder().addAll(filteredList) .add("F").build(); assertEquals(Lists.newArrayList("A", "D", "F"), filteredList); }
@Test public void test2() { Function<String, String> postfixFunction = new Function<String, String>() { @Override public String apply(String input) { return input.concat("-Postfix"); } }; Map<String, String> map = Maps.toMap( Lists.newArrayList("A", "B", "C", "D"), postfixFunction); Map<String, String> buildedMap = ImmutableMap .<String, String> builder().putAll(map).put("E", "E-Postfix") .build(); assertEquals(Maps.toMap(Lists.newArrayList("A", "B", "C", "D", "E"), postfixFunction), buildedMap); }
Q: Why don't they return MutableCollection/MutableMap instead of ImmutableCollction/ImmutableMap for handy future manipulation(add/remove)?
Reference Links:
1) Getting Started with Google Guava -Bill Bejeck
2) http://stackoverflow.com/questions/12937938/adding-and-removing-items-to-a-guava-immutablelist
相关推荐
Maven坐标:com.google.guava:guava:11.0.2; 标签:google、guava、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构...
Maven坐标:com.google.guava:guava:23.0; 标签:google、guava、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构...
Maven坐标:com.google.guava:guava:24.1-jre; 标签:google、guava、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码...
Maven坐标:com.google.guava:guava:26.0-android; 标签:google、guava、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码...
Maven坐标:com.google.guava:guava:30.1.1-jre; 标签:google、guava、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和...
guava
最新版 guava-30.1-jre.jar
Guava的核心特性包括集合框架、缓存、原生类型支持、并发库、字符串处理、I/O操作等。这个“guava.jar”文件就是包含了所有这些功能的归档包。 Guava的集合框架扩展了Java内置的集合类,如List、Set和Map,提供了更...
在Java开发中,Guava库被广泛使用,因为它包含了大量的集合框架、并发支持、缓存机制、字符串处理、I/O操作等多个方面的功能。 标题中的"guava-19.0.jar"是Guava库的19.0版本的二进制文件,包含了编译后的Java类,...
1. **集合框架增强**:Guava提供了丰富的集合类,如Multiset(多集)、Multimap(多映射)、BiMap(双映射)和Immutable Collections(不可变集合)。这些集合类扩展了Java标准库,提供更强大、更灵活的功能,如泛型...
Guava是Google开发的一个核心库,它为Java平台提供了许多实用工具类,涵盖了集合、并发、I/O、字符串处理、数学运算等多个方面。这个压缩包包含的是Guava库的18.0版本,分为两个部分:`guava-18.0.jar`和`guava-18.0...
标题中的"guava-r09-jarjar.jar"是一个特定版本的Guava库,经过JarJar工具处理后的结果。Guava是Google的一个核心库,它提供了很多Java平台的基础工具,包括集合、缓存、原生类型支持、并发、函数式编程、字符串处理...
赠送jar包:guava-18.0.jar 赠送原API文档:guava-18.0-javadoc.jar 赠送源代码:guava-18.0-sources.jar 包含翻译后的API文档:guava-18.0-javadoc-API文档-中文(简体)-英语-对照版.zip 对应Maven信息:groupId...
Guava: Google Core Libraries for Java Guava is a set of core libraries that includes new collection types (such as multimap and multiset), immutable collections, a graph library, functional types, ...
Guava是Google开发的一个开源Java库,包含了众多的实用工具类和集合框架,极大地提高了Java开发的效率。在本例中,我们关注的是"guava-30.1-jre.jar",这是一个针对Java运行环境(JRE)优化的Guava版本,版本号为...
javaweb/javaee 常用jar包,亲测可用,若需其他版本其他jar包请留言我看到后会上传分享
google的guava工具包很实用,包括之前的字符串处理工具类的,还有大量的collection相关的
guava-18.0.jar 包中包含了所有com.google.common类
Maven坐标:com.google.guava:guava:17.0; 标签:google、guava、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构...
Maven坐标:com.google.guava:guava:20.0; 标签:google、guava、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构...