欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入了解集合操作工具Guava?Collect

 更新時(shí)間:2022年10月12日 09:07:13   作者:指北君  
Guava?Collect是Guava工具包中的一個(gè)子模塊,主要對(duì)jdk中的集合操作添加了一些簡(jiǎn)易的API,同時(shí)也是對(duì)Collections工具類的擴(kuò)展。本文將結(jié)合實(shí)例詳細(xì)說說它的使用,需要的可以參考一下

集合操作是編程中使用頻率非常高的,所有有一款針對(duì)集合的操作工具是非常有必要的。通過框架提供的工具一方面可以減少開發(fā)相似功能的耗時(shí);同時(shí)框架在安全與穩(wěn)定性上更被推薦。

Guava Collect是Guava工具包中的一個(gè)子模塊,主要對(duì)jdk中的集合操作添加了一些簡(jiǎn)易的API,同時(shí)也是對(duì)Collections工具類的擴(kuò)展。當(dāng)然Guava還定義了一些特定場(chǎng)景的數(shù)據(jù)結(jié)構(gòu)以及一些針對(duì)jdk集合的優(yōu)化,最典型的就是Immutable Collections(不可變集合),你會(huì)發(fā)現(xiàn)調(diào)用Guava API很多都是不可變的

意義

我們常見的集合類有:

  • List
  • Set
  • Vector
  • Stack
  • Map
  • Queue

集合是一種非常常見的數(shù)據(jù)結(jié)構(gòu),JDK在處理各種數(shù)據(jù)集時(shí),提供了以上集合類型的數(shù)據(jù)結(jié)構(gòu)以及其對(duì)應(yīng)API方便開發(fā)者高效簡(jiǎn)易地對(duì)數(shù)據(jù)對(duì)象操作

特色

guava主要提供了以下幾個(gè)方面的支持:

增加了不可變集合

  • 不受信任的庫可以安全使用。
  • 線程安全:可以被許多線程使用,沒有競(jìng)爭(zhēng)條件的風(fēng)險(xiǎn)。
  • 不需要支持突變,并且可以通過該假設(shè)節(jié)省時(shí)間和空間。所有不可變集合實(shí)現(xiàn)都比它們的可變兄弟更節(jié)省內(nèi)存。(分析)
  • 可以用作常數(shù),期望它保持不變。

增加了新的集合類型

  • Multiset 與普通的Set相比,提供了元素出現(xiàn)頻率的記錄??捎糜谠爻霈F(xiàn)次數(shù)的記錄
  • Multimap 一個(gè)與Map相比,一個(gè)建可以對(duì)應(yīng)對(duì)應(yīng)多個(gè)值。與Spring中MultiValueMap一樣
  • BiMap 鍵值都是唯一的Map
  • Table 具有行、列的表格,數(shù)據(jù)視圖中可能更直觀。
  • ClassToInstanceMap 鍵為Class,值為Class實(shí)例的特殊Map
  • RangeSet 代表一組數(shù)據(jù)區(qū)間,類似數(shù)學(xué)中的 [1,9)
  • RangeMap 與RangeSet類似,不過將其區(qū)間作為建,可以有自己的值。[1,9) -> 'VAL'

優(yōu)化了常用的操作

集合的創(chuàng)建

  • ImmutableSet.of(elem ...)
  • Lists.newArrayList(elem ...)
  • Sets.newHashSet(elem ...)
  • Maps.newHashMap()
  • ...

常用的操作 判斷兩個(gè)集合是否相等:Iterables.elementsEqual()

  • 集合分段處理:Lists.partition()
  • 取集合的交集:Sets.intersection()
  • 取集合的差集:Sets.difference()
  • ...

使用

Guava Collect作為集合操作工具,我們主要從實(shí)際業(yè)務(wù)中了解其能夠幫助我們實(shí)現(xiàn)怎樣的需求,下面看下其API的使用情況:

假設(shè)我們有10000名學(xué)生,通過Faker生成這些模擬的學(xué)生數(shù)據(jù)數(shù)據(jù):

List<Student>?students?=?new?ArrayList<>();
Faker?faker?=?new?Faker(Locale.CHINA);
@Before
public?void?init(){
????Faker?enFaker?=?new?Faker();
????Name?name?=?faker.name();
????IntStream.range(0,10000).forEach(index->{
????????students.add(
????????Student.of()
????????.setId(String.valueOf(index+1))
????????.setName(name.name())
????????.setAge(faker.number().numberBetween(18,22))
????????.setGender(new?String[]{"男","女"}[faker.number().numberBetween(0,2)])
????????.setAddress(faker.address().streetAddress())
????????.setScore(faker.number().randomDouble(3,50,100))
????????.setEmail(?faker.internet().emailAddress(enFaker.name().username()))
????????.setTelephone(faker.phoneNumber().cellPhone())
????????);
????});
}

Multiset

獲取元素出現(xiàn)頻次。比如獲取男生與女生的學(xué)生數(shù)量分別為多少

????@Test
????public?void?multiset(){
????????Multiset?multiset?=?HashMultiset.create();
????????students.forEach(student?->?{
????????????if(Objects.equals(student.getGender(),"男")){
????????????????multiset.add("男");
????????????}else{
????????????????multiset.add("女");
????????????}
????????});

????????System.out.println("學(xué)生中男生數(shù)量:"+?multiset.count("男"));
????????System.out.println("學(xué)生中女生數(shù)量:"+?multiset.count("女"));
????}

Multimap

一個(gè)鍵對(duì)應(yīng)多個(gè)值時(shí)。比如查看各個(gè)年齡的學(xué)生是哪些

????@Test
????public?void?multimap(){
????????ListMultimap<Integer,?Student>?multimap?=
????????????????MultimapBuilder.hashKeys().arrayListValues().build();

????????students.forEach(student?->?{
????????????multimap.put(student.getAge(),student);
????????});

????????System.out.println(?multimap.get(20)?);
????}

BiMap

鍵和值都是唯一時(shí)。比如處理學(xué)生的郵箱和手機(jī)號(hào),客戶互換鍵值位置

????@Test
????public?void?biMap(){
????????BiMap?biMap?=?HashBiMap.create();

????????students.forEach(student?->?{
????????????biMap.put(student.getEmail(),student.getTelephone());
????????});

????????BiMap?inverse?=?biMap.inverse();//?鍵值更換

????????System.out.println(?biMap?);
????????System.out.println(?inverse?);
????}

Table

二維表,通過行(鍵)、列(鍵)取值 比如可以以學(xué)生為行數(shù)據(jù),其中id為行鍵,列名分別為學(xué)生屬性名稱

ID姓名年齡性別
1TOM22
????@Test
????public?void?table(){
????????Table<String,?String,?Object>?weightedGraph?=?HashBasedTable.create();
????????students.forEach(student?->?{
????????????weightedGraph.put(student.getId(),?"姓名",?student.getName());
????????????weightedGraph.put(student.getId(),?"年齡",?student.getAge());
????????????weightedGraph.put(student.getId(),?"性別",?student.getGender());
????????????weightedGraph.put(student.getId(),?"郵箱",?student.getEmail());
????????????weightedGraph.put(student.getId(),?"電話",?student.getTelephone());
????????????weightedGraph.put(student.getId(),?"地址",?student.getAddress());
????????????weightedGraph.put(student.getId(),?"分?jǐn)?shù)",?student.getScore());
????????});

????????Map<String,?Object>?row?=?weightedGraph.row("1");
????????Map<String,?Object>?column?=?weightedGraph.column("姓名");
????????Set<Table.Cell<String,?String,?Object>>?cells?=?weightedGraph.cellSet();

????????System.out.println(?row?);
????????System.out.println(?column?);
????????System.out.println(?cells?);
????}

ClassToInstanceMap

當(dāng)值是鍵的類型實(shí)例時(shí),通過該Map現(xiàn)在鍵值關(guān)系

????@Test
????public?void?classToInstanceMap(){
????????ClassToInstanceMap<Number>?numberDefaults?=?MutableClassToInstanceMap.create();
????
????????numberDefaults.put(Number.class,1);
????
????????Map<Class,Object>?objectMap?=?new?HashMap<>();
????????objectMap.put(Number.class,2);
????}

RangeSet

區(qū)間Set。比如通過學(xué)生分?jǐn)?shù)確定學(xué)生等級(jí)

????@Test
????public?void?rangeSet(){
????????RangeSet<Double>?ArangeSet?=?TreeRangeSet.create();
????????ArangeSet.add(Range.closed(90d,100d));?//?[90,100]
????????RangeSet<Double>?BrangeSet?=?TreeRangeSet.create();
????????BrangeSet.add(Range.closedOpen(80d,90d));?//?[80,90)
????????RangeSet<Double>?CrangeSet?=?TreeRangeSet.create();
????????CrangeSet.add(Range.closedOpen(70d,80d));?//?[70,80)
????????RangeSet<Double>?DrangeSet?=?TreeRangeSet.create();
????????DrangeSet.add(Range.closedOpen(60d,70d));?//?[60,70)
????????RangeSet<Double>?ErangeSet?=?TreeRangeSet.create();
????????ErangeSet.add(Range.lessThan(60d));?//?[...,60)

????????students.forEach(student?->?{
????????????System.out.print(?"?學(xué)生:"+?student.getName()?);
????????????System.out.print(?",分?jǐn)?shù)為:"+?student.getScore()?);
????????????String?rank?=?"";
????????????if(ArangeSet.contains(student.getScore())){
????????????????rank?=?"A";
????????????}else?if(BrangeSet.contains(student.getScore())){
????????????????rank?=?"B";
????????????}else?if(CrangeSet.contains(student.getScore())){
????????????????rank?=?"C";
????????????}else?if(DrangeSet.contains(student.getScore())){
????????????????rank?=?"D";
????????????}else?if(ErangeSet.contains(student.getScore())){
????????????????rank?=?"E";
????????????}
????????????System.out.print(?",等級(jí)為:"+?rank?+"\n");
????????});
????}

RangeMap和RangeSet類似,區(qū)別是添加了區(qū)間命名。和上面一樣

????@Test
????public?void?rangeMap(){
????????RangeMap<Double,?String>?rangeMap?=?TreeRangeMap.create();
????????rangeMap.put(Range.closed(90d,100d),"A");?//?[90,100]
????????rangeMap.put(Range.closedOpen(80d,90d),"B");?//?[80,90)
????????rangeMap.put(Range.closedOpen(70d,80d),"C");?//?[70,80)
????????rangeMap.put(Range.closedOpen(60d,70d),"D");?//?[60,70)
????????rangeMap.put(Range.lessThan(60d),"E");?//?[...,60)

????????students.forEach(student?->?{
????????????System.out.print(?"?學(xué)生:"+?student.getName()?);
????????????System.out.print(?",分?jǐn)?shù)為:"+?student.getScore()?);
????????????System.out.print(?",等級(jí)為:"+?rangeMap.get(student.getScore())?+"\n");
????????});
????}

下面看下對(duì)常用集合的一些操作

當(dāng)然我們首先需要將數(shù)據(jù)使用Guava Collect對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)來存儲(chǔ)數(shù)據(jù),這樣才能使用其對(duì)應(yīng)的API:

集合創(chuàng)建 FluentIterable.of(elem ...)

  • Lists.newArrayList(elem ...)
  • Sets.newHashSet(elem ...)
  • Maps.newHashMap()
  • HashMultiset.create()
  • ArrayListMultimap.create()
  • Tables.newCustomTable(Maps.newLinkedHashMap(), () -> Maps.newLinkedHashMap())\

條件過濾

FluentIterable.filter(predicate); FluentIterable.anyMatch(predicate); FluentIterable.allMatch(predicate); FluentIterable.firstMatch(predicate);

拆分 Iterables.partition(list, pageSize); // 拆解集合

計(jì)算 Iterables.frequency(list, elem); //元素出現(xiàn)的次數(shù)

集合的并集、交集、差集 // 并集 Sets.union(set1, set2); // 交集 Sets.intersection(set1, set2); // 差集  set1為參考 Sets.difference(set1, set2); // 并集-交集 Sets.symmetricDifference(set1, set2); // 同上 Sets.difference(Sets.union(set1, set2),Sets.intersection(set1, set2) ); // 笛卡爾積 Sets.cartesianProduct(Arrays.asList(Sets.newHashSet(1, 2, 3), Sets.newHashSet(3, 4, 5, 6)); // Map,KV相同的部分 difference.entriesInCommon(); // 同K不同V difference.entriesDiffering(); // 左邊存在的右邊不存的K difference.entriesOnlyOnLeft(); // 右邊存在的左邊不存的K difference.entriesOnlyOnRight();

索引 // 將元素中的子項(xiàng)作為索引,由于元素檢索 Maps.uniqueIndex() Multimaps.index()

Jdk中的集合操作

自從Jdk中引入了集合Stream的操作后,從很大程度上簡(jiǎn)化了對(duì)集合的操作,以前大量代碼現(xiàn)在可能簡(jiǎn)單幾行就能夠達(dá)到相同的效果,同時(shí)支持并發(fā)處理,一并提升了效率。

下面看下常見的集合基于stream操作,同樣以上面的學(xué)生為例:

遍歷 forEach

????@Test
????public?void?forEach(){
????????students.stream().forEach(System.out::println);
????}

轉(zhuǎn)換 map

將元素轉(zhuǎn)換成其他類型。比如根據(jù)學(xué)生名稱、性別組成新的List;以id為鍵元素為值的Map或者學(xué)生姓名拼接的字符串等等

????@Test
????public?void?transform(){
????????//?轉(zhuǎn)換為數(shù)組
????????List<String>?listResult?=?students.stream()
????????.map((val)->?val.getName()?+?":"?+?val.getGender()).collect(Collectors.toList());
????????System.out.println(?listResult?);
????
????????//?轉(zhuǎn)換成String
????????String?stringResult?=?students.stream().map(Student::getName).collect(Collectors.joining());
????????System.out.println(?stringResult?);
????
????????//?轉(zhuǎn)換成Map
????????Map<String,?Student>?mapResult?=?students.stream().collect(
????????//?key?,value?,mergerOperation,?initialization
????????Collectors.toMap(Student::getName,Student::self,(v1,v2)->{
????????????//?出現(xiàn)相同key時(shí)的合并規(guī)則
????????????return?null;
????????????},HashMap::new)
????????);
????????System.out.println(?mapResult?);
????}

過濾 filter

根據(jù)條件匹配滿足要求的元素。如找出分?jǐn)?shù)大于80分的學(xué)生

?????@Test
????public?void?filter(){
????????List<Student>?filterResult?=?students.stream().filter((val)->{
????????????return?val.getScore()>80;
????????}).collect(Collectors.toList());
????????System.out.println(filterResult);
????}

拆解 flatMap

將二層級(jí)集合進(jìn)行拆解,并成一級(jí)集合。如[[1,2,3],[4,5,6]] -> [1,2,3,4,5,6]

????@Test
????public?void?flatMap(){
????????//復(fù)合拆解
????????List<Integer>?result?=?Stream.of(Arrays.asList(1,?2,?3),?Arrays.asList(4,?5,?6))
????????????????.flatMap(subList?->?subList.stream())
????????????????.collect(Collectors.toList());
????????System.out.println(result);//?1?2?3?4?5?6
????}

計(jì)算實(shí)現(xiàn)數(shù)據(jù)的匯總、求平均值、最大值...,當(dāng)然主要針對(duì)數(shù)字(Number)類型

????@Test
????public?void?calculate(){
????????//?求和
????????double?sum?=?students.stream().mapToDouble(Student::getScore).sum();
????????//?最大值
????????double?max?=?students.stream().mapToDouble(Student::getScore).max().getAsDouble();
????????//?最小值
????????double?min?=?students.stream().mapToDouble(Student::getScore).min().getAsDouble();
????????//?平均值
????????double?avg?=?students.stream().mapToDouble(Student::getScore).average().getAsDouble();
????????//?歸約運(yùn)算?fold?.?count、sum、min、max、average
????????DoubleSummaryStatistics?doubleSummaryStatistics?=?students.stream().mapToDouble(Student::getScore).summaryStatistics();
????}

歸納計(jì)算 reduce

在很多語言中都存在的函數(shù),如python、javascript。數(shù)據(jù)的累加、map的功能

????@Test
????public?void?reduce(){
????????//?結(jié)果和identity(初始值)類型相同
????????//?identity?accumulator?combiner
????????Map?result?=?students.stream().reduce(
????????????????new?HashMap<String,Student>(),?//初始值
????????????????(map,?student)?->?{
????????????????????map.put(student.getId(),student);
????????????????????return?map;
????????????????},
????????????????(map1,?map2)?->?{
????????????????????//?并發(fā)執(zhí)行時(shí)的map合并
????????????????????return?null;
????????????????}
????????);
????}

并發(fā) parallel

上面的操作我們還可以使用parallel對(duì)stream并發(fā)處理

????Arrays.asList().stream().parallel()...;
????Arrays.asList().parallelStream()...;

分段處理對(duì)集合按固定規(guī)格分段處理,處理大批量數(shù)據(jù)時(shí),結(jié)合parallel實(shí)現(xiàn)分段并發(fā)處理來提示效率

????@Test
????public?void?partition(){
????????List<String>?list?=?new?ArrayList<>();
????????int?partition?=?100;?//每段100個(gè)元素
????
????????int?part?=?list.size()?/?partition??+?(list.size()?%?partition==0??0:1);
????????Stream.iterate(0,?n?->?n+1)
????????????????.limit(part)
????????????????.parallel()?//并發(fā)
????????????????.map(index?->?list.stream().skip(index?*?partition).limit(partition).parallel().collect(Collectors.toList()))
????????????????.forEach(System.out::println);
????}

總結(jié)

本章主要介紹了Guava Collect部分,以及對(duì)集合操作的常用API,通過示例可以看到有其對(duì)JDK集合的擴(kuò)展有了更廣泛與簡(jiǎn)易的操作。同時(shí)在JDK引入 了Stream操作后,Guava Collect中的很多功能通過Stream也可以比較容易的實(shí)現(xiàn)了,當(dāng)然具體如何選擇根據(jù)實(shí)際情況。需要注意的是Guava Collect中 返回的基本都是不可變的集合,這樣在對(duì)數(shù)據(jù)的操作會(huì)更加的安全。

到此這篇關(guān)于深入了解集合操作工具Guava Collect的文章就介紹到這了,更多相關(guān)Guava Collect集合操作內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java.lang.OutOfMemoryError: Metaspace異常解決的方法

    java.lang.OutOfMemoryError: Metaspace異常解決的方法

    這篇文章主要介紹了java.lang.OutOfMemoryError: Metaspace異常解決的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • java原裝代碼完成pdf在線預(yù)覽和pdf打印及下載

    java原裝代碼完成pdf在線預(yù)覽和pdf打印及下載

    本文主要介紹了java原裝代碼完成pdf在線預(yù)覽和pdf打印及下載的方法,具有一定的參考價(jià)值,下面跟著小編一起來看下吧
    2017-02-02
  • Java ExecutorService四種線程池使用詳解

    Java ExecutorService四種線程池使用詳解

    這篇文章主要介紹了Java ExecutorService四種線程池使用詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-02-02
  • Spring AOP 與代理的概念與使用

    Spring AOP 與代理的概念與使用

    大家知道我現(xiàn)在還是一個(gè) CRUD 崽,平時(shí)用 AOP 也是 CV 大法。最近痛定思痛,決定研究一下 Spring AOP 的原理。 這里寫一篇文章總結(jié)一下。主要介紹 Java 中 AOP 的實(shí)現(xiàn)原理,最后以兩個(gè)簡(jiǎn)單的示例來收尾。
    2020-10-10
  • 基于google zxing的Java二維碼生成與解碼

    基于google zxing的Java二維碼生成與解碼

    這篇文章主要為大家詳細(xì)介紹了基于google zxing的Java二維碼生成與解碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • maven+阿里云創(chuàng)建國(guó)內(nèi)鏡像的中央倉庫(親測(cè)可用)

    maven+阿里云創(chuàng)建國(guó)內(nèi)鏡像的中央倉庫(親測(cè)可用)

    本篇文章主要介紹了maven+阿里云創(chuàng)建國(guó)內(nèi)鏡像的中央倉庫(親測(cè)可用),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-12-12
  • java多線程數(shù)據(jù)分頁處理實(shí)例講解

    java多線程數(shù)據(jù)分頁處理實(shí)例講解

    在本篇內(nèi)容里小編給大家分享了一篇關(guān)于java多線程數(shù)據(jù)分頁處理實(shí)例講解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2021-01-01
  • Java 條件控制與循環(huán)控制實(shí)例

    Java 條件控制與循環(huán)控制實(shí)例

    下面小編就為大家?guī)硪黄狫ava 條件控制與循環(huán)控制實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-05-05
  • Spring?Boot在啟動(dòng)時(shí)執(zhí)行一次的功能實(shí)現(xiàn)

    Spring?Boot在啟動(dòng)時(shí)執(zhí)行一次的功能實(shí)現(xiàn)

    這篇文章主要給大家介紹了關(guān)于Spring?Boot在啟動(dòng)時(shí)執(zhí)行一次的功能實(shí)現(xiàn),在實(shí)習(xí)過程中,有時(shí)候會(huì)遇到一些項(xiàng)目啟動(dòng)初始化的需求,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08
  • SpringBoot通過JSON傳遞請(qǐng)求參數(shù)的實(shí)例詳解

    SpringBoot通過JSON傳遞請(qǐng)求參數(shù)的實(shí)例詳解

    這篇文章主要介紹了SpringBoot通過JSON傳遞請(qǐng)求參數(shù),示例介紹SpringMVC如何通過JSON格式傳遞入?yún)?,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-11-11

最新評(píng)論