guava深入理解(4)-集合
2018-01-19 12:02
260 查看
如果说guava的null处理,Preconditions,字符串处理很多别的库也有而且还更强。而且如果使用其他jvm语言,kotlin,groovy等,根本就用不上那些类,语言自带的反而更好。
那么guava的collection类基本上目前还看不出有其他类库,语法特性可以替代。就算你是使用kotlin,groovy,scala。也可以很好的和guava的collection集成
1.确保集合元素不会被别的库错误更改
2.线程安全(多线程同时读是不会有竞争条件的)
3.因为不可变,所以数据结构可以根据这个假设来优化,所以空间占用更少,集合操作更快
当你不需要修改一个集合时,(或者当某个可变集合在一段操作内都不可变时*),你都可以创建一个不可变集合,或者将一个可变集合转化为一个不可变集合。
guava对所有java的集合类,和guava自己的增强集合类,都提供了对应的不可变集合。
创建不可变集合
当然,你总是可以在不可变集合和可变集合之间互相转换,你可以将一个不可变集合转换为可变集合,添加元素之后再转换为可变集合(只有在添加操作很少的时候才建议这样做,不然直接用可变集合更方便)。你只需要明确什么时候用可变集合,什么时候用不可变集合。
实际上这种离散的range不怎么常用,单个的range像ruby,python里那种常用一些,不知道java什么时候才支持语法级别的range。
特别是guava为sets提供了一系列数学集合的运算,例如并集,交集(这个我早觉得java该有了)
欢迎关注我的github
https://github.com/luckyCatMiao
那么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不能对应同个valueBiMap<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 javaList<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
相关文章推荐
- Java 集合深入理解(9):Queue 队列
- 深入理解Java之集合框架
- 深入理解Java虚拟机笔记---字段表集合
- 深入理解Java虚拟机笔记---属性表集合
- Java 集合深入理解(3):Collection
- Java 集合深入理解(10):Deque 双端队列
- 深入理解C#的装箱和拆箱、使用非泛型集合时引发的装箱和拆箱操作
- Java 集合深入理解(8):AbstractSequentialList
- 深入理解javascript中的动态集合——NodeList、HTMLCollection和NamedNodeMap
- Java 集合深入理解(10):Deque 双端队列
- Java集合(2)——深入理解ArrayList、Vector和LinkedList
- Java 集合深入理解(3):Collection
- Java 集合深入理解(13):Stack 栈
- 深入理解Java集合之Map
- Java 集合深入理解(7):ArrayList
- 【深入理解java集合系列】LinkedHashMap实现原理
- Java 集合深入理解(15):AbstractMap
- Java 集合深入理解(9):Queue 队列
- 集合和反编译间的深入理解和认识
- Java 集合深入理解(6):AbstractList