Java工具库Guava的不可变集合和新集合类型Multiset、Multimap、BiMap、RangeSet、RangeMap等的使用示例
admin
2024-01-29 06:56:58
0

场景

Java核心工具库Guava介绍以及Optional和Preconditions使用进行非空和数据校验:

Java核心工具库Guava介绍以及Optional和Preconditions使用进行非空和数据校验_霸道流氓气质的博客-CSDN博客_guava 校验

在上面引入Guava的基础上。学习其不可变集合和新集合类型的使用

不可变集合

1、当对象被不可信的库调用时,不可变形式是安全的。

2、不可变对象被多个线程调用时,不存在竞态条件问题。

3、不可变集合不需要考虑变化,因此可以节省时间和空间。所有不可变的集合都比他们的可变形式有更好的内存利用率。

4、不可变对象因为固定不变,可以作为常量来安全使用。

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi 
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

不可变集合的创建

1、copyOf方法

        //创建不可变集合的方式List list = new ArrayList(){{this.add("badao");this.add("de");this.add("chengxvyuan");}};//1、copyOf方法ImmutableList strings = ImmutableList.copyOf(list);System.out.println(strings);//[badao, de, chengxvyuan]list.add("add");System.out.println(strings);//[badao, de, chengxvyuan]

并且当原集合改变时,copy的不会改变

2、of方法

        ImmutableList of = ImmutableList.of("a", "b", "d", "c");System.out.println(of);//[a, b, d, c]

3、Builder工具

        ImmutableSet add = ImmutableSet.builder().addAll(list).add("add").build();System.out.println(add);//[badao, de, chengxvyuan, add] 

ImmutableSortedSet有序不可变集合

对于有序不可变集合,排序在构造集合时就完成

        ImmutableSortedSet of2 = ImmutableSortedSet.of("a", "d", "a", "c", "b", "a");System.out.println(of2);//[a, b, c, d]

asList视图

所有不可变集合都有一个asList()方法提供ImmutableList视图

        System.out.println(ImmutableSet.of("a","a","b","c").asList());//[a, b, c]System.out.println(ImmutableSet.of("a","a","b","c").asList().get(0));//a

新集合类型

Multiset

Multiset,可以多次添加相等的元素,Multiset元素顺序是无关的,Multiset{a,a,b} 与{a,b,a}是相等的

可以将其看做是没有元素顺序限制的ArrayList

1、添加单个给定元素

        Multiset multiSet = HashMultiset.create();multiSet.add("badao");multiSet.add("badao");multiSet.add("de");multiSet.add("de");

2、获取元素个数

        System.out.println(multiSet.size());//4

3、添加多个给定元素

        List list = new ArrayList(){{this.add("badao");this.add("de");this.add("chengxvyuan");}};//size获取元素个数System.out.println(multiSet.size());//4//添加多个给定元素multiSet.addAll(list);System.out.println(multiSet.size());//7

4、iterator()返回一个迭代器,包含Multiset的所有元素(包括重复元素)

        Iterator it = multiSet.iterator();while (it.hasNext()) {System.out.println(it.next());}

也可以将其看做是Map 键为元素,值为计数

1、count(Object)返回给定元素的计数

System.out.println("badao元素的计数为:"+multiSet.count("badao"));//badao元素的计数为:3

2、elementSet() Multiset不重复元素的集合,类型为Set

System.out.println(multiSet.elementSet());//[badao, de, chengxvyuan]

3、entrySet()和Map的entrySet类似,返回Set> 其中包含的Entry支持getElement()和getCount()方法

        multiSet.entrySet().forEach(stringEntry -> {System.out.println(stringEntry.getElement()+stringEntry.getCount());});

4、add(E,int) 增加给定元素在Multiset中的计数

        System.out.println( multiSet.count("badao"));//3multiSet.add("badao",3);System.out.println(multiSet.count("badao"));//6

5、设置给定元素在Multiset中的计数

        multiSet.setCount("badao",1);System.out.println(multiSet.count("badao"));//1

SortedMultiset

SortedMultiset是Multiset接口的变种,它支持高效地获取指定范围的子集

        SortedMultiset sortedMultiset = TreeMultiset.create();sortedMultiset.add(0);sortedMultiset.add(1);sortedMultiset.add(2);sortedMultiset.add(2);sortedMultiset.add(3);sortedMultiset.add(5);sortedMultiset.add(6);sortedMultiset.add(8);sortedMultiset.add(9);//统计在0到5以内的数量,包含0,不包含5int size = sortedMultiset.subMultiset(0, BoundType.CLOSED, 5, BoundType.OPEN).size();int size1 = sortedMultiset.size();// 创建一个数值格式化对象NumberFormat numberFormat = NumberFormat.getInstance();// 设置精确到小数点后2位numberFormat.setMaximumFractionDigits(2);String result = numberFormat.format((float)size/(float)size1);System.out.println(result);//0.56

Multimap

Multimap 是把键映射到任意多个值的一般方式,不会有任何键映射到空集合:一个键要么至少到一个值,要么不存在Multimap中

1、Multimap的创建

Multimap multimap = HashMultimap.create();

2、添加键到单个值的映射

        multimap.put("a",1);multimap.put("a",2);multimap.put("a",3);multimap.put("b",3);

3、get(key)以集合形式返回键所对应的值视图,即使没有任何对应的值,也会返回空集合

        Collection a = multimap.get("a");System.out.println(a);//[1, 2, 3]

4、putAll(K,Iterable) 依次添加键到多个值的映射

        multimap.putAll("c",new ArrayList(){{this.add(1);this.add(2);this.add(3);this.add(4);}});System.out.println(multimap.get("c"));//[1, 2, 3, 4]

5、remove(K,V)移除键到值的映射;如果有这样的键值并成功移除,返回true

        multimap.remove("c",1);System.out.println(multimap.get("c"));//[2, 3, 4]

6、removeAll(K) 清除键对应的所有值,返回的集合包含所有之前映射到K的值,但修改这个集合就不会影响到Multimap了

        //multimap.removeAll("c");System.out.println(multimap.get("c"));//[]

7、replaceValues(K,Iterable)清除键对应的所有值,并重新把key关联到Iterable中的每个元素。

        multimap.replaceValues("c",new ArrayList(){{this.add(6);this.add(7);}});System.out.println(multimap.get("c"));//[6, 7]

8、asMap为Multimap提供Map形式的视图。返回的Map支持remove操作,并且会

反映到底层的Multimap,但它不支持put或putAll操作。

        Map map = multimap.asMap();System.out.println(map);//{a=[1, 2, 3], b=[3], c=[6, 7]}

9、entries用Collection>返回Multimap中所有“键-单个值映射”,包括重复键

        Collection entries = multimap.entries();System.out.println(entries);//[a=1, a=2, a=3, b=3, c=6, c=7]

10、keySet用Set表示Multimap中所有不同的键

System.out.println(multimap.keySet());//[a, b, c]

11、keys用Multiset表示Multimap中的所有键,每个键重复出现的次数等于它映射的值的个数

可以从这个Multiset中移除元素,但不能做添加操作;移除操作会反映到底层的Multimap

System.out.println(multimap.keys());//[a x 3, b, c x 2]

12、values()用一个扁平的Collection包含Multimap中的所有值。

System.out.println(multimap.values());//[1, 2, 3, 3, 6, 7]

BiMap

BiMap是特殊的Map: 可以用inverse()反转BiMap的键值映射,保证值是唯一的,因此valus()返回Set而不是普通的Collection

1、在BiMap中,如果你想把键映射到已经存在的值,会抛出IllegalArgumentException

        HashBiMap biMap = HashBiMap.create();biMap.put("a",1);//biMap.put("b",1);//java.lang.IllegalArgumentException

2、如果对特定的值,想要强制替换它的键,使用forcePut

        System.out.println(biMap.get("a"));//1biMap.forcePut("b",1);System.out.println(biMap.get("b"));//1

3、put和Inverse

        HashBiMap biMap2 = HashBiMap.create();biMap2.put("a",1);biMap2.put("a",2);System.out.println(biMap2);//{a=2}BiMap inverse = biMap2.inverse();System.out.println(inverse);//{2=a}

Table

Guava提供了Table,它有两个支持所有类型的键:“行“和”列“

1、put

        HashBasedTable table = HashBasedTable.create();table.put(1,1,"java");table.put(1,2,"c");table.put(2,1,"c++");table.put(2,2,"c#");

2、row(r)用Map返回给定“行”的所有列,对这个map进行的写操作也将写入Table中

        Map row = table.row(1);System.out.println(row);//{1=java, 2=c}

3、rowMap() 用Map> 表现Table

        Map> integerMapMap = table.rowMap();System.out.println(integerMapMap);//{1={1=java, 2= c},2={1=c++, 2=c#}}

4、rowKeySet()返回行的集合set

        Set integers = table.rowKeySet();System.out.println(integers);//[1, 2]

5、column 返回指定列

System.out.println(table.column(2));//{1=c, 2= c#}

6、columnMap 用Map> 表现Table

System.out.println(table.columnMap());//{1={1=java, 2= c++},2={1=c, 2=c#}}

7、columnKeySet返回所有列的集合set

System.out.println(table.columnKeySet());//[1, 2]

8、cellSet()用元素类型为Table.Cell的Set表现Table

System.out.println(table.cellSet());//[(1,1)=java, (1,2)=c, (2,1)=c++, (2,2)=c#]

ClassToInstanceMap

ClassToInstanceMap是一种特殊的Map:它的键是类型,而值是符合键所指类型的对象。

ClassToInstabceMap额外声明了两个方法 T getInstance(Class) 和 T putInstance(Class,T),从而避免强制类型转换,同时保证了类型安全

        ClassToInstanceMap instanceMap = MutableClassToInstanceMap.create();instanceMap.putInstance(Integer.class,Integer.valueOf(0));System.out.println(instanceMap.getInstance(Integer.class));//0

RangeSet

RangeSet描述了一组不相连的、非空的区间。当把一个区间添加到可变的RangeSet时,所有相连的区间会被合并,空区间会被忽略

1、创建和添加

        RangeSet rangeSet = TreeRangeSet.create();rangeSet.add(Range.closed(1,10));System.out.println(rangeSet);//[[1..10]]rangeSet.add(Range.closedOpen(11,15));System.out.println(rangeSet);//[[1..10], [11..15)]rangeSet.add(Range.closedOpen(15,20));System.out.println(rangeSet);//[[1..10], [11..20)]rangeSet.add(Range.openClosed(0,0));System.out.println(rangeSet);//[[1..10], [11..20)]rangeSet.remove(Range.open(5,10));System.out.println(rangeSet);//[[1..5], [10..10], [11..20)]

2、complement()返回RangeSet的补集视图

System.out.println(rangeSet.complement());//[(-∞..1), (5..10), (10..11), [20..+∞)]

3、subRangeSet(Range)返回RangeSet与Range的交集视图

System.out.println(rangeSet.subRangeSet(Range.closedOpen(15,30)));//[[15..20)]

4、asRanges()用Set表现RangeSet,这样可以遍历其中的Range

        Set> ranges = rangeSet.asRanges();System.out.println(ranges);//[[1..5], [10..10], [11..20)]

5、contains(C) 判断RangeSet中是否有任何区间包含给定元素

        System.out.println(rangeSet.contains(6));//falseSystem.out.println(rangeSet.contains(11));//true

6、rangeContaining(C)返回包含给定元素的区间;若没有这样的区间,则返回null

        System.out.println(rangeSet.rangeContaining(6));//nullSystem.out.println(rangeSet.rangeContaining(11));//[11..20)

7、encloses判断RangeSet中是否有任何区间包括给定区间

        System.out.println(rangeSet.encloses(Range.closedOpen(11,15)));//trueSystem.out.println(rangeSet.encloses(Range.closedOpen(6,9)));//falseSystem.out.println(rangeSet.encloses(Range.closedOpen(15,25)));//false

8、span返回包含RangeSet中所有区间的最小区间

System.out.println(rangeSet.span());//[1..20)

RangeMap

RangeMap描述了“不想交的、非空的区间” 到特定值的映射,和RangeSet不同,RangeMap不会和并相邻的映射,即使相邻的区间映射到相同的值

1、创建和put

        RangeMap rangeMap = TreeRangeMap.create();rangeMap.put(Range.closed(1,10),"badao");System.out.println(rangeMap);//[[1..10]=badao]rangeMap.put(Range.open(3,6),"de");System.out.println(rangeMap);//[[1..3]=badao, (3..6)=de, [6..10]=badao]rangeMap.put(Range.open(10,20),"chengxvyuan");System.out.println(rangeMap);//[[1..3]=badao, (3..6)=de, [6..10]=badao, (10..20)=chengxvyuan]rangeMap.remove(Range.closed(5,11));System.out.println(rangeMap);//[[1..3]=badao, (3..5)=de, (11..20)=chengxvyuan]

2、asMapOfRanges() 用Map表现RangeMap,这可以用来遍历RangeMap

        Map, String> rangeStringMap = rangeMap.asMapOfRanges();System.out.println(rangeStringMap);//{[1..3]=badao, (3..5)=de, (11..20)=chengxvyuan}

3、subRangeMap(Range)用RangeMap类型返回RangeMap与给定Range的交集视图

System.out.println(rangeMap.subRangeMap(Range.closed(2,4)));//{[2..3]=badao, (3..4]=de}

相关内容

热门资讯

原创 三... “三伏吃果,胜过补药”!老祖宗的智慧藏在时令里 —— 三伏天暑热蒸腾,人体易被 “暑湿” 困住,吃对...
邂逅一杯金银花茶,清热解毒又养... 天气越来越热啦,是不是感觉有点上火呢?今天给大家推荐一款能清热解毒的茶饮——金银花茶哦。 金银花茶...
中国节气里的京味非遗:小暑 “小暑大暑,上蒸下煮。”7月7日,小暑节气来临。此时节,暑气渐盛,雷雨增多,蝉鸣蛙声里尽显盛夏光景。...
原创 这... 在朋友的聚会上,一道令人垂涎欲滴的烤羊肉串无疑是餐桌上的明星。今天,就让我们跟随美食作家的脚步,一起...
原创 1... 一碗大米配上三个鸡蛋,不用煎烤油炸,就能做出一道比馅饼还简单的美味,这听起来似乎有些不可思议,但事实...
原创 豆... 在探索美食的旅途中,我们总能找到那些能够唤醒味蕾记忆的经典菜肴。今天,我将与大家分享一道简单而美味的...
原创 自... 标题:自从我学会这几道菜,老公再也不说下馆子了,每次吃的盘子光光的 在这个快节奏的时代,美食不仅仅...
原创 糯... 说起糯米,很多人第一时间想到的就是粽子。确实,端午时节家家户户包粽子的场景已经深深烙印在我们的记忆中...
原创 不... 天热不想炒菜时不妨就来一道简单的炖菜,有汤有菜的也是一道下饭好菜。当然了,夏天的炖菜还是以“清爽清淡...
茄子和它天生一对,知道的人不多... 导语:茄子和它天生一对,知道的人不多!三天两头炒一盘,又鲜嫩、又解馋,一个菜扫光一锅饭! 七月盛夏,...
关于万历年间的一些民间故事? 关于万历年间的一些民间故事?万历年间的一天,广宁一个叫孙林的药材商在大街上闲逛,一个看相的一看到他,...
随身翻译机选择什么品牌好? 随身翻译机选择什么品牌好?1、随身翻译机怎么选购?2、随身翻译机随身翻译机到哪里买?3、随身翻译机里...
求“困知勉行”的解释 求“困知勉行”的解释kùn zhī miǎn xíng困知:遇困而求知;勉行:尽力实行。在不断克服困...
我该怎么整容了? 我该怎么整容了?我觉得你不用整容,你长得挺好的,男人结结实实就行,皮肤不太好,有豆豆,不要吃辛辣食物...
为什么叫云时代 为什么叫云时代就是一切资源都在云上,云指终端
综合来说,空客和波音哪家公司的... 综合来说,空客和波音哪家公司的飞机更好?波音比空客更好些。根据规模比较波音排名64,空客排名105。...
哪个季节适合出去旅游? 哪个季节适合出去旅游?在各种季节游玩中,人们讲的最多的是春游。因为人最喜欢的是新生的物品,而春天是万...
股市,情绪指标什么意思 股市,情绪指标什么意思市场情绪指标,是反应市场情绪的一种技术指标,可以反应出市场的情绪是否过热,还是...