谷歌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

谷歌guava_Google Guava v07范例相关推荐

  1. Google Guava v07范例

    我们在TouK举办了一个名为"每周技术研讨会"的活动,即每个星期五的16:00,每个愿意参加的人都有一个演讲. 我们展示了我们在家学习和学习的东西,但是我们也设有一个公告板,上面有 ...

  2. 谷歌guava_Google Guava:您永远不会知道的5件事

    谷歌guava 每个开发人员可以使用哪些鲜为人知的Google Guava功能? 它是那里最受欢迎的库之一,它是开源的,您可能已经知道了,它来自人们玩Quidditch作为一项真正的运动的地方(至少在 ...

  3. 谷歌guava_Google Guava BiMaps

    谷歌guava 接下来的番石榴之旅是另一个有用的收藏类型BiMap . 实际上,这非常简单,BiMap只是双向地图. 反转地图 普通的Java映射是一组键和值,您可以按键查找值,这非常有用,例如,说我 ...

  4. 谷歌guava_Google Guava –期货

    谷歌guava 这篇文章是我在Google Guava上的系列文章的延续,这次涵盖了Future. Futures类是用于使用Future / ListenableFuture接口的静态实用程序方法的 ...

  5. 谷歌guava_Google Guava MultiMaps

    谷歌guava 番石榴 这是我尝试解释和探索Google很棒的Guava java库的系列文章中的第一篇. 我在搜索Apache Commons Collections的通用版本时遇到了番石榴(Gua ...

  6. 谷歌guava_Google Guava BloomFilter

    谷歌guava 当Guava项目发布版本11.0时,新添加的功能之一是BloomFilter类. BloomFilter是唯一的数据结构,用于指示元素是否包含在集合中. 使BloomFilter有趣的 ...

  7. Springboot项目中通过谷歌的guava实现令牌桶算法,来进行请求限流

    令牌桶算法是一种对请求限流的有效算法,核心思想是,一定时间内产生固定数量的令牌,拿到该令牌的请求可以通过,进行业务处理,没有拿到令牌的请求需要等待,直到新的令牌产生并领到该令牌,才可以通过,否则一直被 ...

  8. 谷歌Guava LoadingCache介绍

      在工作中,加Cache是非常常见的一种性能优化手段,操作系统底层.计算机硬件层为了性能优化加了各种各样的Cache,当然大多数都是对应用层透明的.但如果你想在应用层加Cache的话,可能就需要你自 ...

  9. 关于Google的Cache使用

    关于Google的Cache使用 1Cache的概述 2 官方文档 1 加载 2 缓存回收 1 基于容量的回收(size-based eviction) 2 定时回收(Timed Eviction) ...

最新文章

  1. CTFshow 命令执行 web55
  2. Bless You Autocorrect!
  3. 551. 学生出勤记录
  4. [LeetCode] 81. Search in Rotated Sorted Array II
  5. APP软件半成品测试技巧
  6. kubernetes StatefulSet介绍
  7. 【LeetCode】题解合集(JavaScript版)
  8. 笔记本计算机信号不强,增强笔记本WiFi无线信号的方法
  9. 云原生2.0时代,保险企业为何要迎智而上?
  10. SNS过早收费扼杀用户成长
  11. zabbix 2.2.2在centos 6.3 x86_64上的安装
  12. 微信公众号oauth授权
  13. 炫我科技渲染集群管理软件
  14. 证券投资深度学习_基于风险中性的深度学习选股策略
  15. 网关短信 群发 为什么卡发短信 群发 贵 ?
  16. [基础代码仓库]基于STM32C8T6的库函数ADC模拟+DMA多通道转运代码
  17. 【嵌入式面试题】C++经典面试题总结
  18. 影响中国软件开发的20人-- 开国元勋篇
  19. 高斯数据库基于mysql_高斯数据库 (gaussDB) - 基于 JDBC 开发 (1)
  20. 热搜第一除了本科生月均5千工资,还告诉了我们什么?

热门文章

  1. Java中的ThreadPoolExecutor类
  2. 13-一对多左连接查询分步查询(查询所有客户及客户对应的订单)
  3. 你想象中的实习是什么样的?
  4. java中如何数组是如何赋值的?
  5. 程序员常用网站收藏[定期更新]——csdn博客
  6. 组合的示例代码 java_java实现Composite组合模式的实例代码
  7. 以太坊地址和公钥_以太坊交易签名解析源码解读
  8. 本地方法(JNI)——使用调用API
  9. java集合——java.util.Properties类
  10. jdk 安全属性_系统属性的JDK 12 Javadoc标记