`
DavyJones2010
  • 浏览: 154331 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Guava: Working with Collections I

阅读更多

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

  • 大小: 82 KB
分享到:
评论

相关推荐

    guava-11.0.2-API文档-中文版.zip

    Maven坐标:com.google.guava:guava:11.0.2; 标签:google、guava、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构...

    guava-23.0-API文档-中文版.zip

    Maven坐标:com.google.guava:guava:23.0; 标签:google、guava、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构...

    guava-24.1-jre-API文档-中英对照版.zip

    Maven坐标:com.google.guava:guava:24.1-jre; 标签:google、guava、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码...

    guava-26.0-android-API文档-中文版.zip

    Maven坐标:com.google.guava:guava:26.0-android; 标签:google、guava、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码...

    guava-30.1.1-jre-API文档-中文版.zip

    Maven坐标:com.google.guava:guava:30.1.1-jre; 标签:google、guava、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和...

    guava-31.1-jre.jar

    guava

    最新版 guava-30.1-jre.jar

    最新版 guava-30.1-jre.jar

    google开源项目guava.jar包

    Guava的核心特性包括集合框架、缓存、原生类型支持、并发库、字符串处理、I/O操作等。这个“guava.jar”文件就是包含了所有这些功能的归档包。 Guava的集合框架扩展了Java内置的集合类,如List、Set和Map,提供了更...

    guava-19.0 jar和sources

    在Java开发中,Guava库被广泛使用,因为它包含了大量的集合框架、并发支持、缓存机制、字符串处理、I/O操作等多个方面的功能。 标题中的"guava-19.0.jar"是Guava库的19.0版本的二进制文件,包含了编译后的Java类,...

    Guava常用类库 v33.0.0.zip

    1. **集合框架增强**:Guava提供了丰富的集合类,如Multiset(多集)、Multimap(多映射)、BiMap(双映射)和Immutable Collections(不可变集合)。这些集合类扩展了Java标准库,提供更强大、更灵活的功能,如泛型...

    guava-18.0(guava-18.0.jar和guava-18.0-sources.jar)

    Guava是Google开发的一个核心库,它为Java平台提供了许多实用工具类,涵盖了集合、并发、I/O、字符串处理、数学运算等多个方面。这个压缩包包含的是Guava库的18.0版本,分为两个部分:`guava-18.0.jar`和`guava-18.0...

    guava-r09-jarjar.jar

    标题中的"guava-r09-jarjar.jar"是一个特定版本的Guava库,经过JarJar工具处理后的结果。Guava是Google的一个核心库,它提供了很多Java平台的基础工具,包括集合、缓存、原生类型支持、并发、函数式编程、字符串处理...

    guava-18.0-API文档-中英对照版.zip

    赠送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...

    Android代码-guava

    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-30.1-jre.jar

    Guava是Google开发的一个开源Java库,包含了众多的实用工具类和集合框架,极大地提高了Java开发的效率。在本例中,我们关注的是"guava-30.1-jre.jar",这是一个针对Java运行环境(JRE)优化的Guava版本,版本号为...

    guava-32.1.3-android.jar

    javaweb/javaee 常用jar包,亲测可用,若需其他版本其他jar包请留言我看到后会上传分享

    guava-25.1-jre.jar

    google的guava工具包很实用,包括之前的字符串处理工具类的,还有大量的collection相关的

    guava-18.0.jar

    guava-18.0.jar 包中包含了所有com.google.common类

    guava-17.0-API文档-中文版.zip

    Maven坐标:com.google.guava:guava:17.0; 标签:google、guava、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构...

    guava-20.0-API文档-中文版.zip

    Maven坐标:com.google.guava:guava:20.0; 标签:google、guava、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构...

Global site tag (gtag.js) - Google Analytics