您的位置:首页 > 其它

guava深入理解(4)-集合

2018-01-19 12:02 260 查看
如果说guava的null处理,Preconditions,字符串处理很多别的库也有而且还更强。而且如果使用其他jvm语言,kotlin,groovy等,根本就用不上那些类,语言自带的反而更好。

那么guava的collection类基本上目前还看不出有其他类库,语法特性可以替代。就算你是使用kotlin,groovy,scala。也可以很好的和guava的collection集成

不可变集合Immutable Collections

为什么要使用不可变集合

1.确保集合元素不会被别的库错误更改

2.线程安全(多线程同时读是不会有竞争条件的)

3.因为不可变,所以数据结构可以根据这个假设来优化,所以空间占用更少,集合操作更快

当你不需要修改一个集合时,(或者当某个可变集合在一段操作内都不可变时*),你都可以创建一个不可变集合,或者将一个可变集合转化为一个不可变集合。

guava对所有java的集合类,和guava自己的增强集合类,都提供了对应的不可变集合。

创建不可变集合

public static final ImmutableSet<Color> GOOGLE_COLORS =
ImmutableSet.<Color>builder()
.addAll(WEBSAFE_COLORS)
.add(new Color(0, 191, 255))
.build();


ImmutableSet.of("a", "b", "c", "a", "d", "b")


当然,你总是可以在不可变集合和可变集合之间互相转换,你可以将一个不可变集合转换为可变集合,添加元素之后再转换为可变集合(只有在添加操作很少的时候才建议这样做,不然直接用可变集合更方便)。你只需要明确什么时候用可变集合,什么时候用不可变集合。

Multiset

我们经常写出以下的计数代码,multiset就是为了解决这种问题出现的

Map<String, Integer> counts = new HashMap<String, Integer>();
for (String word : words) {
Integer count = counts.get(word);
if (count == null) {
counts.put(word, 1);
} else {
counts.put(word, count + 1);
}
}


HashMultiset<String> hashMultiset=HashMultiset.create();
for(int i=0;i<1000;i++)
{
hashMultiset.add(Math.floor(Math.random()*10)+"");

}

System.out.println(hashMultiset);


Multimap

类似Map<K, List<>> or Map<K, Set<V>>,value可以容纳多个元素
常规的map
a -> 1
a -> 2
a -> 4
b -> 3
c -> 5
Multimap
a -> [1, 2, 4]
b -> [3]
c -> [5]


public void testArrayListMultiMap(){
ArrayListMultimap<String,String> multiMap =
ArrayListMultimap.create();
multiMap.put("Foo","1");
multiMap.put("Foo","2");
multiMap.put("Foo","3");
List<String> expected = Lists.newArrayList("1","2","3");
assertEquals(multiMap.get("Foo"),expected);
}


BiMap

bimap是支持反向查找的map,当然,这就意味着key和value是唯一对应的,多个key不能对应同个value

BiMap<String,String> biMap = HashBiMap.create();
biMap.put("1","Tom");
//相同的value会报错
biMap.put("2","Tom");


//可以使用force put 来强制覆盖之前的pair对
public void testBiMapForcePut() throws Exception {
BiMap<String,String> biMap = HashBiMap.create();
biMap.put("1","Tom");
biMap.forcePut("2","Tom");
assertThat(biMap.containsKey("1")
4000
,is(false));
assertThat(biMap.containsKey("2"),is(true));
}


//使用
public void testBiMapInverse() throws Exception {
BiMap<String,String> biMap = HashBiMap.create();
biMap.put("1","Tom");
biMap.put("2","Harry");
assertThat(biMap.get("1"),is("Tom"));
assertThat(biMap.get("2"),is("Harry"));
BiMap<String,String> inverseMap = biMap.inverse();
assertThat(inverseMap.get("Tom"),is("1"));
assertThat(inverseMap.get("Harry"),is("2"));
}


Table

table差不多就是二维数组,但是有很多额外方法,例如返回整行,返回整列的元素

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

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


RangeSet

rangeset代表一系列range的并集,用过python,ruby的应该都知道range是个什么东西了。

RangeSet<Integer> rangeSet = TreeRangeSet.create();
rangeSet.add(Range.closed(1, 10)); // {[1, 10]}
rangeSet.add(Range.closedOpen(11, 15)); // disconnected range: {[1, 10], [11, 15)}
rangeSet.add(Range.closedOpen(15, 20)); // connected range; {[1, 10], [11, 20)}
rangeSet.add(Range.openClosed(0, 0)); // empty range; {[1, 10], [11, 20)}
rangeSet.remove(Range.open(5, 10)); // splits [1, 10]; {[1, 5], [10, 10], [11, 20)}


实际上这种离散的range不怎么常用,单个的range像ruby,python里那种常用一些,不知道java什么时候才支持语法级别的range。

Collection Utilities

guava提供了很多工具类,和java自带的collections不一样,guava几乎是为每个数据结构都提供了一个工具类。实际上大多数guava集合的创建都是使用静态方法的,至于静态方法为什么比构造器好请看effective java

List<String> theseElements = Lists.newArrayList("alpha", "beta", "gamma");
List<Type> exactly100 = Lists.newArrayListWithCapacity(100);
List<Type> approx100 = Lists.newArrayListWithExpectedSize(100);
Set<Type> approx100Set = Sets.newHashSetWithExpectedSize(100);


特别是guava为sets提供了一系列数学集合的运算,例如并集,交集(这个我早觉得java该有了)

Set<String> wordsWithPrimeLength = ImmutableSet.of("one", "two", "three", "six", "seven", "eight");
Set<String> primes = ImmutableSet.of("two", "three", "five", "seven");

SetView<String> intersection = Sets.intersection(primes, wordsWithPrimeLength); // 交集运算


欢迎关注我的github

https://github.com/luckyCatMiao
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  groovy scala jvm 语言 class