guava学习笔记-集合

时间:2022-02-18 16:51:33

静态工厂方法创建集合

    public void testCreateCollection(){
List<String> stringList = Lists.newArrayList();
Map<String, Integer> map = Maps.newHashMap();
Set<String> stringSet = Sets.newHashSet();
}

创建真正的不可修改的集合

好处:
- 防御性编程,不可修改的集合
- 可读性强,非常直观;
- 线程安全的;可以被使用为一个常量
- 节省空间,效率更高

    @Test
public void testCreateUnmodifiableCollection(){
//Java标准库支持
Set<String> stringSet = Sets.newHashSet();
Set<String> unmodifiableSet = Collections.unmodifiableSet(stringSet);
//guava方式创建
ImmutableList<String> unmodifiableList = ImmutableList.of("t1", "t2");
thrown.expect(UnsupportedOperationException.class);
unmodifiableList.add("t3");
//保护性拷贝
ImmutableSet setCopy = ImmutableSet.copyOf(stringSet);
//通过构造模式创建
ImmutableSet.Builder<String> builder = ImmutableSet.builder();
ImmutableSet<String> immutableSet = builder.add("RED").addAll(stringSet).build();
}

新集合类型

Mltiset

传统集合set不能存放重复的元素,而Multiset可以分组存放相同的元素;换句话说,就是把相同的元素分为一组,每组有个count属性。可以通过count知道每个元素重复次数。
如{“a”, “b”,”c”, “c”,”c”,”a”},放入到Multiset变为[b, c x 3, a x 2]。

    @Test
public void testMultitset(){
String[] strings = new String[]{"a", "b","c", "c","c","a"};
Multiset<String> multiset = HashMultiset.create();
for (String str : strings){
multiset.add(str);
}
//multiset存放方式为{"a" * 2, "b" * 1, "c" * 3}
assertEquals(multiset.count("a"), 2);
assertEquals(multiset.count("b"), 1);
assertEquals(multiset.count("c"), 3);
assertThat(multiset.elementSet(), hasItems("a", "b", "c"));
// 打印输出[b, c x 3, a x 2]
System.out.println(multiset.entrySet());
assertEquals(strings.length, multiset.size());
}

Multimap

类似Map

   @Test
public void testMultimap(){
Multimap<String, Integer> multimap = HashMultimap.create();
multimap.put("foo", 1);
multimap.put("foo", 2);
multimap.put("foo", 3);
multimap.put("bar", 4);
multimap.put("bar",6);
multimap.put("milk", 5);
//一个key对应多个value
assertThat(multimap.get("foo"), containsInAnyOrder(1, 2, 3));
//输出一个Multiset:[milk, foo x 3, bar x 2]
System.out.println(multimap.keys());
//返回key的集合
assertThat(multimap.keySet(), containsInAnyOrder("foo", "bar", "milk"));
//返回value的集合
assertThat(multimap.values(), containsInAnyOrder(1, 2, 3, 4, 5, 6));
//输出一个Map<K, Collection<V>>:{milk=[5], foo=[1, 2, 3], bar=[4, 6]}
System.out.println(multimap.asMap());
//输出Collection<Map.Entry<K, V>>:[milk=5, foo=1, foo=2, foo=3, bar=4, bar=6]
System.out.println(multimap.entries());
}

BiMap

BiMap是个特殊的map,它的key既可以是key,也可以变为value。换句话说,可以通过value找key。只要通过inverse()反转就行了。

    @Test
public void testBiMap(){
BiMap<String, Integer> biMap = HashBiMap.create();
biMap.put("foo", 1);
biMap.put("bar", 2);
biMap.put("mild", 3);
//inverse()反转
assertThat(biMap.inverse().keySet(), containsInAnyOrder(1, 2, 3));
assertTrue(biMap.inverse().containsValue("foo"));
}

Table

Table<Vertex, Vertex, Double> weightedGraph = HashBasedTable.create();
2
weightedGraph.put(v1, v2, 4);
3
weightedGraph.put(v1, v3, 20);
4
weightedGraph.put(v2, v3, 5);
5

6
weightedGraph.row(v1); // returns a Map mapping v2 to 4, v3 to 20
7
weightedGraph.column(v3); // returns a Map mapping v1 to 20, v2 to 5

通常来说,当你想使用多个键做索引的时候,你可能会用类似Map

    @Test
public void testTable(){
Table<String, String, Integer> table = HashBasedTable.create();
table.put("t11", "t12", 1);
table.put("t11", "t22", 2);
table.put("t21", "t22", 3);
table.put("t31", "t32", 4);
//输出:[(t21,t22)=3, (t11,t22)=2, (t11,t12)=1, (t31,t32)=4]
System.out.println(table.cellSet());
//输出:{t21={t22=3}, t11={t22=2, t12=1}, t31={t32=4}}
System.out.println(table.rowMap());
//输出:{t22={t21=3, t11=2}, t12={t11=1}, t32={t31=4}}
System.out.println(table.columnMap());
//返回row的keys
assertThat(table.rowKeySet(), containsInAnyOrder("t11", "t21", "t31"));
//返回column的keys
assertThat(table.columnKeySet(), containsInAnyOrder("t12", "t22", "t32"));
//获取value
assertThat(table.get("t21","t22"), is(3));
}

强大集合工具

Iterables

   @Test
public void testIterables(){
Set<Integer> set1 = Sets.newHashSet(1, 2, 3, 4);
Set<Integer> set2 = Sets.newHashSet(5, 6, 7, 8);
//串联多个集合
assertThat(Iterables.concat(set1, set2), containsInAnyOrder(1, 2, 3, 4, 5, 6, 7, 8));
//输出:[[1, 2], [3, 4]]
System.out.println(Iterables.partition(set1, 2));
//所有元素满足条件就返回true
assertFalse(Iterables.all(set1, new Predicate<Integer>() {
@Override
public boolean apply(Integer input) {
if(input % 2 == 0)
return false;
else
return true;
}
}));
//如果有一个元素满足条件就返回true
assertTrue(Iterables.any(set1, new Predicate<Integer>() {
@Override
public boolean apply(Integer input) {
if(input % 2 == 0)
return false;
else
return true;
}
}));
//返回满足条件的第一个元素
int i = Iterables.find(set1, new Predicate<Integer>() {
@Override
public boolean apply(Integer input) {
if(input % 2 == 0)
return false;
else
return true;
}
});
assertEquals(i, 1);
//过滤满足条件的元素,这里返回集合里面的奇数
Iterable<Integer> odds = Iterables.filter(set1, new Predicate<Integer>() {
@Override
public boolean apply(Integer input) {
if(input % 2 == 0)
return false;
else
return true;
}
});
assertThat(odds, containsInAnyOrder(1, 3));
//返回对象在iterable中出现的次数
assertEquals(Iterables.frequency(set1, 2), 1);
}

函数式编程

函数最常见的用途为转换集合

  @Test
public void testFunctions(){
Set<String> set = Sets.newHashSet("a", "b", "c");
Iterable<String> set2 = Iterables.transform(set, new Function<String, String>() {
//在每个元素后加“1”
public String apply(String input){
return input + "1";
}
});
assertThat(set2, containsInAnyOrder("a1", "b1", "c1"));
Map<String, Integer> map = ImmutableMap.of("a", 1, "b", 2, "c", 3);
Map<String, String> map2 = Maps.transformValues(map, new Function<Integer, String>() {
//将Map中每个元素的Value从Integer变为String
public String apply(Integer input){
return String.valueOf(input);
}
});
assertThat(map2, allOf(hasValue("1"), hasValue("2"),hasValue("3")));
}