谷歌guava_Google Guava v07范例

谷歌guava

我们在TouK举办了一个名为“每周技术研讨会”的活动,即每个星期五的16:00,每个愿意参加的人都有一个演讲。 我们展示了我们在家学习和学习的东西,但是我们还设有一个公告板,上面有人们想听的话题。 上周MaciejPróchniak谈论了Clojure ,这次有几个人要求介绍Google Guava库 。

由于这是一项艰巨而简单的任务,所以我很乐意交付。

WTF是番石榴吗?

这是一组非常简单的基本类,您最终还是要自己编写。 仅由Google来思考Apache的共同点。 只是为了让您的生活更轻松一点。

Wiktor Gworek在Javarsowia 2010上做了一个早期(v04) 演讲 ,另外一个是波兰语演讲 。

在撰写本文时,最新版本是v07,已经过Mavenized,可以在公共Maven repo上找到 。

这是一些有趣的事情的快速回顾。 不过,不要指望任何东西,Guava非常基础。

@VisibleForTesting

一个简单的注释,告诉您为什么放宽了特定的属性访问限制。

在测试中使用的一个常见技巧是放宽对特定属性默认值的访问限制,以便您可以在单元测试中使用它,该单元测试位于相同的程序包中(尽管在不同的目录中)。 无论是好是坏,都请给开发者一个提示。

考虑:

public class User {private Long id;private String firstName;private String lastName;String login;

为什么登录程序包有作用域?

public class User {private Long id;private String firstName;private String lastName;@VisibleForTesting String login;

啊,那是为什么。

前提条件

Guava有一些防御性编程的先决条件(按合同设计),但不如Apache Commons / Spring框架具备的条件好。 有趣的一件事是Guava解决方案返回了对象,因此可以进行内联。 考虑:

使用手写的前提条件:

public User(Long id, String firstName, String lastName, String login) {validateParameters(id, firstName, lastName, login);this.id = id;this.firstName = firstName;this.lastName = lastName;this.login = login.toLowerCase();}private void validateParameters(Long id, String firstName, String lastName, String login) {if(id == null ) {throw new IllegalArgumentException('id cannot be null');}if(firstName == null || firstName.length() == 0) {throw new IllegalArgumentException('firstName cannot be empty');}if(lastName == null || lastName.length() == 0) {throw new IllegalArgumentException('lastName cannot be empty');}if(login == null || login.length() == 0) {throw new IllegalArgumentException('login cannot be empty');}}

使用番石榴先决条件:

public void fullyImplementedGuavaConstructorWouldBe(Long id, String firstName, String lastName, String login) {this.id = checkNotNull(id);this.firstName = checkNotNull(firstName);this.lastName = checkNotNull(lastName);this.login = checkNotNull(login);checkArgument(firstName.length() > 0);checkArgument(lastName.length() > 0);checkArgument(login.length() > 0);}

(感谢Yom注意到checkNotNull必须在checkArgument之前执行,尽管这有点不直观)

使用spring或apache commons前提(两个库的用法看起来完全一样):

public void springConstructorWouldBe(Long id, String firstName, String lastName, String login) {notNull(id); hasText(firstName); hasText(lastName); hasText(login);this.id = id;this.firstName = firstName;this.lastName = lastName;this.login = login;}

CharMatcher

对于讨厌regexp或只想要简单美观的对象样式模式匹配解决方案的人。

例子:

和/或易用性

String input = 'This invoice has an id of 192/10/10';CharMatcher charMatcher = CharMatcher.DIGIT.or(CharMatcher.is('/'));String output = charMatcher.retainFrom(input);

输出是:192/10/10

否定:

String input = 'DO NOT scream at me!';CharMatcher charMatcher = CharMatcher.JAVA_LOWER_CASE.or(CharMatcher.WHITESPACE).negate();String output = charMatcher.retainFrom(input);

输出是:DONOT!

范围:

String input = 'DO NOT scream at me!';CharMatcher charMatcher = CharMatcher.inRange('m', 's').or(CharMatcher.is('a').or(CharMatcher.WHITESPACE));String output = charMatcher.retainFrom(input);

输出是:sram am

木工/分离器

顾名思义,它是正确完成字符串连接/拆分的方法,尽管我发现调用有点儿反转了……哦,那是java。

String[] fantasyGenres = {'Space Opera', 'Horror', 'Magic realism', 'Religion'};String joined = Joiner.on(', ').join(fantasyGenres);

输出:太空歌剧,恐怖片,魔幻现实主义,宗教

您可以跳过空值:

String[] fantasyGenres = {'Space Opera', null, 'Horror', 'Magic realism', null, 'Religion'};String joined = Joiner.on(', ').skipNulls().join(fantasyGenres);

输出:太空歌剧,恐怖片,魔幻现实主义,宗教

您可以填写空值:

String[] fantasyGenres = {'Space Opera', null, 'Horror', 'Magic realism', null, 'Religion'};String joined = Joiner.on(', ').useForNull('NULL!!!').join(fantasyGenres);

输出:太空歌剧,NULL !!!,恐怖,魔术现实主义,NULL !!!,宗教

您可以加入地图

Map<Integer, String> map = newHashMap();map.put(1, 'Space Opera');map.put(2, 'Horror');map.put(3, 'Magic realism');String joined = Joiner.on(', ').withKeyValueSeparator(' -> ').join(map);

输出:1? 太空歌剧2 恐怖3? 魔幻现实主义

Split返回Iterable而不是JDK数组:

String input = 'Some very stupid data with ids of invoces like 121432, 3436534 and 8989898 inside';Iterable<String> splitted = Splitter.on(' ').split(input);

尽管您不能为每个“列”指定不同的长度,但Split会进行固定长度的拆分,这使得在解析某些导出效果不佳的Excel时,它的使用受到了一些限制。

String input ='A  1  1  1  1\n' +'B  1  2  2  2\n' +'C  1  2  3  3\n' +'D  1  2  5  3\n' +'E  3  2  5  4\n' +'F  3  3  7  5\n' +'G  3  3  7  5\n' +'H  3  3  9  7';Iterable<String> splitted = Splitter.fixedLength(3).trimResults().split(input);

您可以在拆分时使用CharMatcher

String input = 'Some very stupid data with ids of invoces like 123231/fv/10/2010, 123231/fv/10/2010 and 123231/fv/10/2010';Iterable<String> splitted = Splitter.on(CharMatcher.DIGIT.negate()).trimResults().omitEmptyStrings().split(input);

谓词/功能

谓词本身并不多,它只是一个带有返回true的方法的接口,但是如果您将谓词与函数和Collections2(简化了集合处理的番石榴类)结合使用,则可以在工具箱中找到一个不错的工具。

但是,让我们从基本谓词使用开始。 假设我们要查找是否存在用数字登录的用户。 接种将是(返回布尔值):

Predicates.in(users).apply(shouldNotHaveDigitsInLoginPredicate);

谓词看起来像

public class ShouldNotHaveDigitsInLoginPredicate implements Predicate<User> {@Overridepublic boolean apply(User user) {checkNotNull(user);return CharMatcher.DIGIT.retainFrom(user.login).length() == 0;}    
}

现在让我们添加一个函数,该函数会将用户转换为他的全名:

public class FullNameFunction implements Function<User, String> {@Overridepublic String apply(User user) {checkNotNull(user);return user.getFirstName() + ' ' + user.getLastName();}    
}

您可以使用静态方法转换调用它:

List<User> users = newArrayList(new User(1L, 'sylwek', 'stall', 'rambo'),new User(2L, 'arnold', 'schwartz', 'commando'));List<String> fullNames = transform(users, new FullNameFunction());

现在,让谓词与函数结合使用,以打印登录名不包含数字的用户名:

List<User> users = newArrayList(new User(1L, 'sylwek', 'stall', 'rambo'), new User(2L, 'arnold', 'schwartz', 'commando'), new User(3L, 'hans', 'kloss', 'jw23'));Collection<User> usersWithoutDigitsInLogin = filter(users, new ShouldNotHaveDigitsInLoginPredicate());
String names = Joiner.on('\n').join( transform(usersWithoutDigitsInLogin, new FullNameFunction()) );

我们没有得到的是: 折叠(减少)和元组 。 哦,好吧,如果您想使用Java中的函数 ,您可能还是会转向Java Functional Library ,对吧?

案例格式

是否曾经想过用一个衬里将这些丑陋的PHP Pear名称转换为漂亮的java / cpp样式? 没有? 好吧,无论如何,您可以:

String pearPhpName = 'Really_Fucked_Up_PHP_PearConvention_That_Looks_UGLY_because_of_no_NAMESPACES';
String javaAndCPPName = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL , pearPhpName);

输出:ReallyFuckedUpPhpPearconventionThatLooksUglyBecauseOfNoNamespaces

但是由于Oracle接管了Sun,您实际上可能希望将其转换为sql风格,对吗?

String sqlName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, javaAndCPPName);

输出:real_fucked_up_php_pearconvention_that_looks_ugly_because_of_no_namespaces

馆藏

番石榴具有Google馆藏库1.0的超集,这确实是将这种依赖关系包含在pom中的一个很好的理由。 我什至不会尝试描述所有功能,而只是指出一些不错的东西:

  • 您拥有几乎所有内容的不可变版本
  • 您可以在常见类型(如列表,集合,地图,对象数组)上获得一些不错的静态和静态类型化方法,这些方法包括:
    • 基于返回类型创建的简单方法:例如newArrayList
    • 转换(应用返回不可变版本的函数的方式)
    • 分区(分页)
    • 逆转

现在还有更多有趣的收藏。

多图

Mutlimap基本上是一个映射,单个键可以具有多个值。 是否曾经在您的代码中创建Map <T1,Set <T2 >>? 您不再需要了。

Multimap<Integer, String> multimap = HashMultimap.create();multimap.put(1, 'a');multimap.put(2, 'b');multimap.put(3, 'c');multimap.put(1, 'a2');

当然也有不可变的实现:ImmutableListMultimap,ImmutableSetMultomap等。

您可以在线(最多5个元素)或使用构建器构造不可变项:

Multimap<Integer, String> multimap = ImmutableSetMultimap.of(1, 'a', 2, 'b', 3, 'c', 1, 'a2'); 
Multimap<Integer, String> multimap = new ImmutableSetMultimap.Builder<Integer, String>().put(1, 'a').put(2, 'b').put(3, 'c').put(1, 'a2').build();

双图

BiMap是仅具有唯一值的地图。 考虑一下:

@Test(expected = IllegalArgumentException.class)
public void biMapShouldOnlyHaveUniqueValues() {BiMap<Integer, String> biMap = HashBiMap.create();biMap.put(1, 'a');biMap.put(2, 'b');biMap.put(3, 'a'); //argh! an exception
}

这使您可以反转地图,因此值成为关键,反之亦然:

BiMap<Integer, String> biMap = HashBiMap.create();
biMap.put(1, 'a');
biMap.put(2, 'b');
biMap.put(3, 'c');BiMap<String, Integer> invertedMap = biMap.inverse();

不知道我实际上想用它做什么。

约束条件

这使您可以在集合上添加约束检查,以便仅添加通过约束的值。

想象一下,我们想要一个在其登录名中带有首字母“ r”的用户集合。

Constraint<User> loginMustStartWithR = new Constraint<User>() {@Overridepublic User checkElement(User user) {checkNotNull(user);if(!user.login.startsWith('r')) {throw new IllegalArgumentException('GTFO, you are not Rrrrrrrrr');}return user;}
};

现在进行测试:

@Test(expected = IllegalArgumentException.class)
public void shouldConstraintCollection() {//givenCollection<User> users = newArrayList(new User(1L, 'john', 'rambo', 'rambo'));Collection<User> usersThatStartWithR = constrainedCollection(users, loginMustStartWithR);//whenusersThatStartWithR.add(new User(2L, 'arnold', 'schwarz', 'commando'));
}

您还可以立即获得notNull约束:

//notice it's not an IllegalArgumentException :( 
@Test(expected = NullPointerException.class)
public void notNullConstraintShouldWork() {//givenCollection<Integer> users = newArrayList(1);Collection<Integer> notNullCollection = constrainedCollection(users, notNull());//whennotNullCollection.add(null);
}

要记住的事情:约束条件不是检查集合中已经存在的数据。

桌子

正如预期的那样,表是具有列,行和值的集合。 我猜没有更多的Map <T1,Map <T2,T3 >>。 用法很简单,您可以转置:

Table<Integer, String, String> table = HashBasedTable.create();
table.put(1, 'a', '1a');
table.put(1, 'b', '1b');
table.put(2, 'a', '2a');
table.put(2, 'b', '2b');Table transponedTable = Tables.transpose(table);

就是这样,伙计们。 我没有介绍util.concurrent,原语,io和net软件包,但您可能已经知道会发生什么。

祝您编程愉快,别忘了分享!

参考: Solid Craft博客上来自我们JCG合作伙伴 Jakub Nabrdalik的Google Guava v07示例 。


翻译自: https://www.javacodegeeks.com/2012/10/google-guava-v07-examples.html

谷歌guava

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/351987.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

arduinoesp8266定时器_ESP8266深度睡眠与Arduino IDE(NodeMCU)

本指南展示了如何使用Arduino IDE与ESP8266(NodeMCU)一起使用深度睡眠。我们将使用定时器唤醒来唤醒深度睡眠&#xff0c;并使用复位(RST)引脚来唤醒外部唤醒。引入深度睡眠模式如果您使用电池供电的ESP8266板制作了一个项目&#xff0c;或者只是将ESP8266 NodeMCU板连接到了移…

MATLAB对图片格式批量转换

从网上下载一些数据集&#xff0c;发现是PPM或者PGM格式的&#xff0c;一般照片查看器打不开。可以用MATLAB对其进行批量转换格式。当然&#xff0c;任何两种格式之间相互转换都可以用这个程序&#xff1a;% 本示例程序将 pgm 图片转换为 jpg 图片 % 如果仅对一张 pgm 图片作…

gunicorn部署Flask服务

作为一个Python选手&#xff0c;工作中需要的一些服务接口一般会用Flask来开发。 Flask非常容易上手&#xff0c;它自带的app.run(host"0.0.0.0", port7001)用来调试非常方便&#xff0c;但是用于生产环境无论是处理高并发还是鲁棒性都有所欠缺&#xff0c;一般会配合…

linux shell 中判断字符串为空的正确方法

help命令可以查看帮助 help test 正确做法&#xff1a; #!/bin/sh STRING if [ -z "$STRING" ]; then echo "STRING is empty" fi if [ -n "$STRING" ]; then echo "STRING is not empty" fi rootjames-desktop:~#…

打开wmware没反应_没呼吸没脉搏,溺水女孩危在旦夕!预产期只差9天的她挺着大肚子出手相助...

8月9日晚上8点半南海桂城中海锦城小区游泳池一位小女孩溺水了&#xff01;脸色青紫、嘴唇发绀没有呼吸也没有脉搏情况非常不妙&#xff01;↓↓↓救生员立马给女孩做心肺复苏。站在泳池边陪女儿才游不到200米的南海医院妇科医生胡碧洪&#xff0c;听见泳池边的骚动&#xff0c;…

使用JAXB的简介

我正在将一些依赖于Apache XMLBeans的模块迁移到JAXB。 这是令人兴奋且充满挑战的几天。 我想记下我遇到的一些重要事情&#xff0c;以供将来可能会发现有用的任何人使用。 首先&#xff0c;让我们来看一下设置用于JAXB代码生成的maven插件。 在撰写本文时&#xff0c;我遇到了…

关于opencv读取摄像头的未解之谜

前段时间做项目需要用opencv读usb摄像头的视频数据&#xff0c;遇到很多无解的问题&#xff0c;虽然后来没有用到&#xff0c;但是还是记录下来&#xff0c;也许以后就知道答案了呢。 1、无论摄像头的实际分辨率是多少&#xff0c;opencv读进来的视频分辨率都是640*480大小的&a…

[BZOJ2834]回家的路

Description Input Output Sample Input 2 1 1 2 1 1 2 2Sample Output 5思路还是很简单的&#xff0c;然而最短路打错各种对拍各种调了一早上代码&#xff1a;1 #include<iostream>2 #include<cstdio>3 #include<cstring>4 #include<vector>5 #includ…

dubbo优势_Dubbo与SpringCloud核心组件Ribbon、Hystrix、Feign的优劣势比较

在微服务架构中&#xff0c;分布式通信、分布式事务、分布式锁等问题是亟待解决的几个重要问题。Spring Cloud是一套完整的微服务解决方案&#xff0c;基于 Spring Boot 框架。确切的说&#xff0c;Spring Cloud是一个大容器(而不是一个框架)&#xff0c;它可以将通过集成一些好…

使用Java更新DynamoDB项

在上一篇文章中&#xff0c;我们继续使用Java将项目插入DynamoDB。 DynamoDB还支持更新项目。 我们将使用Login表获取更新示例。 发布更新时&#xff0c;必须指定要更新的项目的主键。 public void updateName(String email,String fullName) {Map<String,AttributeValue…

Python执行系统命令的方法 os.system(),os.popen(),commands

最近在做那个测试框架的时候发现 Python 的另一个获得系统执行命令的返回值和输出的类。 最开始的时候用 Python 学会了 os.system() 这个方法是很多比如 C&#xff0c;Perl 相似的。 os.system(cat /proc/cpuinfo) 但是这样是无法获得到输出和返回值的&#xff0c;继续 Goog…

opencv的两个错误

1、imwrite未定义标识符先检查opencv和C有没有配置好&#xff0c;再看有没有包含相应的头文件&#xff0c;最后发现是因为没有使用cv的命名空间&#xff0c;需要加上using namespase cv&#xff1b; 2、cvCvtColor的使用函数原型&#xff1a;cvCvtColor&#xff08;src&#xf…

BTC、BCH和BSV三者到底有什么区别?

比特币发展到今天已经有10个年头了&#xff0c;在这十年的发展中&#xff0c;比特币一共经历了两次重要的分裂&#xff0c;现在变成了三种货币&#xff0c;第一种是目前继承了比特币绝大多数遗产的BTC&#xff1b;第二种是BCH&#xff1b;第三种是BSV。那这三种货币到底有什么区…

ping 不通 华为三层交换机vlan_华为三层交换机如何让VLAN间不能互通配置精编版...

时可以利用hybrid属性定义分属于不同的vlan的端口之间的互访&#xff0c;这是access和trunk端口所不能实现的。在一台交换机上不允许trunk端口和hybrid端口同时存在。1.先创建业务需要的vlan[SwitchA]vlan 10[SwitchA]vlan 20[SwitchA]vlan 30[SwitchA]vlan 40[SwitchA]vlan 50…

python进程池:multiprocessing.pool

阅读目录 例1&#xff1a;使用进程池例2&#xff1a;使用进程池&#xff08;阻塞&#xff09;例3&#xff1a;使用进程池&#xff0c;并关注结果例4&#xff1a;使用多个进程池 在利用Python进行系统管理的时候&#xff0c;特别是同时操作多个文件目录&#xff0c;或者远程控制…

eclipse juno_放弃Eclipse Juno

eclipse juno在上一个博客中&#xff0c;我发布了有关Eclipse 4.2 Juno设置的信息。 在需要重新安装其他东西的情况下&#xff0c;为我提供了很多参考。 那时我没有谈论的是我与Juno共同遇到的问题。 我以为这是我自己的安装程序&#xff0c;很麻烦&#xff0c;但是此后并没有太…

C语言结构体数组的使用

1、结构体数组的优点结构体可以存储不同的数据类型&#xff0c;将他们互相联系起来。结构体数组可以连续存储多个结构体&#xff0c;和数组作用相似。比如想定义同一个最小外接矩形的四个坐标值&#xff0c;并给予这个矩形一个特征编号。当需要存储多个最小外接矩形的信息时&am…

arthas 查看哪个方法调用最耗时_Java开源诊断工具Arthas使用方法详解

一、前言1、热更新代码的场景(1)当线上服务器出现问题时&#xff0c;有些时候现有的手段不足以发现问题所在&#xff0c;可能需要追加打印日志或者增加一些调试代码&#xff0c;如果我们去改代码重新部署&#xff0c;会破坏问题现场&#xff0c;可以通过热部署的手段来增加调试…

Java 12 - Java StringBuffer和StringBuilder类

Java StringBuffer和StringBuilder类 当对字符串进行修改的时候&#xff0c;需要使用StringBuffer和StringBuilder类。 和String类不同的是&#xff0c;StringBuffer和StringBuilder类的对象能够被多次的修改&#xff0c;并且不产生新的未使用对象。 StringBuilder类在Java 5中…

将你的Vim 打造成轻巧强大的IDE

Vim和Emacs一个称为神之编辑器一个被称为编辑器之神&#xff0c;固然很是夸张&#xff0c;但也足以说明这两 款软件的优秀和在程序员界的地位。但是它们都已漫长的学习曲线让人望而生畏&#xff0c;阻止了大 多数人进入。作为一名几乎完全使用Vim写各种代码、文档的人&#xff…