我希望代码简单,短而又易于阅读。 不必要的复杂性分散了人们对真实情况的理解,使他们难以理解,并且可能成为生产力的真正杀手。

您知道,缠结的for循环和索引可以跟踪是否/其他情况和切换用例,空/验证检查,转换/复制/删除/排序集合,异常处理……列表随着行号和维护负担的增加而继续存在。

我想到了托尼·霍尔的一句名言。

构建软件设计的方法有两种:一种方法是使它变得如此简单,以至于显然没有缺陷,另一种方法是使它变得如此复杂以至于没有明显的缺陷。

换句话说:细节中有魔鬼。

Apache Commons具有补充JDK API的一些最出色的库,但本文与Commons无关。 它是关于Google Guava的 ,在很多方面都与Commons类似。 它为常用的日常任务提供了一个库,例如集合处理,字符串处理,并发,IO,基元,异常等。

Guava中有很多很棒的东西,我没有时间去浏览完整的库,但是这里至少有一些它可以做什么的例子。

对象
使用对象可以轻松地实现哈希码/等式,而不会使您的类过于混乱(对我而言,Eclipse自动生成往往有些冗长)。

实现toString的类在进行调试和日志记录时非常令人愉悦,但是确实是一个痛苦的实现。 Objects.toStringHelper使得此操作非常容易,并且还有助于维护打印对象的一致格式。

public class Item {private String id;private String name;public Item(String id, String name) {this.id = id;this.id = name;}public String getId() {return id;}public String getName() {return name;}@Overridepublic int hashCode() {return Objects.hashCode(getId(), getName());}@Overridepublic String toString() {return Objects.toStringHelper(this).add("id", getId()).add("name", getName()).toString();}@Overridepublic boolean equals(Object o) {if (!(o instanceof Item)) {return false;}Item other = (Item) o;return Objects.equal(getId(), other.getId()) && Objects.equal(getName(), other.getName());}
}

打印此类会输出类似这样的内容。

Item{id=1, name=Book}

可抛物
包装原始异常对象并不总是合适的,因为如果不相关的类加载器之间发生通信,或者在网络上对其进行序列化,则可能导致客户端代码中的ClassNotFoundException。 Throwables可以解除这种依赖关系,仍然允许远程客户端通过将其转换为字符串来查看堆栈跟踪。

try {// throws implementation specific exception
} catch (InternalException e) {throw new ApiException("reason", Throwables.getStackTraceAsString(e));
}

可迭代
连接两个单独的集合并对结果执行操作可能会导致很多混乱。 遍地抢救。 花一点时间,思考一下如果没有Iterables.concat,代码的外观如何。

for (Item item : Iterables.concat(books, electronics)) {// do something useful
}

多图
Multimap就像一个Map,但是允许为每个键存储多个值。 以下示例是类型安全的异构容器的变体,该容器使用multimap来实现商品的产品目录。

public class ProductCatalogue {private Multimap<Class,? extends Item>, Item> catalogue = ArrayListMultimap.create();public void add(Item item) {catalogue.put(item.getClass(), item);}public <T extends Item> Collection<Item> list(Class<T> clazz) {return catalogue.get(clazz);}
}ProductCatalogue catalogue = new ProductCatalogue();
catalogue.add(new Book("1", "Book1"));
catalogue.add(new Movie("2", "Movie1"));
// only get books
System.out.println("Books " + catalogue.list(Book.class));
// only get movies
System.out.println("Movies " + catalogue.list(Movie.class));

双图
BiMap在Map的键和值之间实现了一对一的双向关系。 这是一个使用语言代码获取语言的示例,反之亦然。

BiMap<String, String> languageCodes = HashBiMap.create();
languageCodes.put("en", "English");
languageCodes.put("fr", "French");
languageCodes.put("zh", "Chinese");
assert "English" == languageCodes.get("en");
assert "en" == languageCodes.inverse().get("English");

前提条件
大多数类在构造函数和方法中给定的值都有限制。 无效值应通过在执行前进行显式有效性检查来尽快升级。 快速故障要比以后由于意外的异常而失败,或更糟糕的是,静默地计算错误的结果要好得多。

public Item(String id, String name) {this.id = Preconditions.checkNotNull(id, "id must not be null");this.name = Preconditions.checkNotNull(name, "name must not be null");Preconditions.checkArgument(name.length() > 6, "name must be longer than 6 chars");
}

约束条件
约束与先决条件类似,它们可以限制将哪些值添加到集合中。 由于约束与业务代码分离,因此这使集合的使用更加容易并且代码更加简洁。

public class Voyage {private Country targetcountry;private int capacity;private List<Cargo> items = Constraints.constrainedList(new ArrayList<Cargo>(), new Constraint<Cargo>() {@Overridepublic Cargo checkElement(Cargo cargo) {Preconditions.checkNotNull(cargo);Preconditions.checkArgument(targetcountry.allows(cargo));Preconditions.checkArgument(cargo.getUnits() gt; 0);return cargo;}});public void load(List<Cargo> cargos) {items.addAll(cargos);}
}

谓词和功能
谓词评估是真还是假,但也可以使用“与”,“或”,“非”和“中”组合成更复杂的评估。

现在通常需要for循环和一堆if语句的内容现在可以简化为单行代码。 那有多甜?

Predicate<Item> heavyItemPolicy = new Predicate<Item>() {@Overridepublic boolean apply(Item item) {if(item.getWeight() > 1000){return true;}return false;}
};
Collection<Item> heavyItems = Collections2.filter(order, heavyItemPolicy);

您也可以类似的方式使用Maps.filterKeys或Iterables.filter。 但是请记住,从修改中删除是双向的。 例如从原点移除会影响结果,反之亦然。

另一方面,函数是一种将一个对象转换为另一个对象的方法。 例如,按项目顺序转换并发。

Function currencyConverter = new Function<Double, Item>() {@Overridepublic Double apply(Item item) {return item.getPrice() * ANOTHER_CURRENCY;}
}
Collection<Double> prices = Collections2.transform(order, currencyConverter);

您也可以类似的方式使用Maps.transformValues或Iterables.transform。

查询API
一段时间以来,我一直在考虑如何创建简单但功能强大的Fake Objects 。 但是我不希望假冒产品本身成为维护负担,因此它们必须易于实施。 我的直觉告诉我,我需要一个通用的状态管理框架来使其正常工作。 因此,我使用谓词创建了一个小的流利查询接口,该接口与内存中的存储进行交互。

InMemoryStorage storage = new InMemoryStorage();
// add a few Item.class objects to storage
Criteria middleprice = field("price").is(largerThan(100)).and(lessThan(200));
Criteria expired = field("expires").is(after(currentDate));
Collection<Item> result = storage.select(middleprice.and(not(expired))).from(Item.class);

实际上,我对结果感到非常满意-简短,紧凑,易于理解和类型安全。

我在这里不做详细介绍,但是请检查Criteria和InMemoryStorage的实现以及测试 。

我希望这些示例将触发您进一步研究 Guava,并使用它使您的代码更具可读性,鲁棒性和可维护性。

最后,我确实希望这些功能中的许多功能能够在不久的将来达到标准Java。

参考: Deep Hacks博客上 的详细信息来自我们的JCG合作伙伴 KristofferSjögren 。

相关文章 :

  • Java Lambda语法替代
  • Java中的低GC:使用原语而不是包装器
  • Java泛型快速教程
  • Java最佳实践教程系列

翻译自: https://www.javacodegeeks.com/2011/09/google-guava-libraries-essentials.html

Google Guava库必需品相关推荐

  1. Google Guava 库用法整理

    http://macrochen.iteye.com/blog/737058 参考: http://codemunchies.com/2009/10/beautiful-code-with-googl ...

  2. Google Guava v07范例

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

  3. 使用 Google Guava Striped 实现基于 Key 的并发锁

    写 Java 代码至今,在应对可能冲突的共享资源操作时会尽量用 JDK 1.5 开始引入的并发锁(如 Lock 的各类实现类, ReentrantLock 等) 进行锁定,而不是原来的 synchro ...

  4. Google Guava的5个鲜为人知的特性

    Google Guava有哪些比较冷门但却又实用的特性呢? 它是最流行的开源库之一,你应该听过它的大名,它诞生的地方正是人们举办真正的魁地奇比赛的地方(起码实习期内是这样的).它虽然不是来自哈利波特中 ...

  5. Google Guava 的 5 个鲜为人知的特性

    (点击上方公众号,可快速关注) 来源:花名有孚, it.deepinmind.com/java/2015/03/27/google-guava-5-things-you-never-knew-it-c ...

  6. Google Guava Retry 优雅的重试方案

    Google Guava Retry 优雅的重试方案 前言 使用场景 什么场景不适合重试 了解幂等性 一.Guava Retry是什么? 与Spring retry比较 二.使用步骤 1.引入库 2. ...

  7. Google Guava Collections 使用介绍

    原帖http://www.open-open.com/lib/view/open1325143343733.html 简介: Google Guava Collections 是一个对 Java Co ...

  8. guava_使用Google Guava Cache进行本地缓存

    guava 很多时候,我们将不得不从数据库或另一个Web服务获取数据或从文件系统加载数据. 在涉及网络呼叫的情况下,将存在固有的网络延迟,网络带宽限制. 解决此问题的方法之一是在应用程序本地拥有一个缓 ...

  9. [Google Guava] 1.1-使用和避免null

    原文链接 译文链接 译者: 沈义扬    Doug Lea 说,"Null 真糟糕."   当Sir C. A. R. Hoare 使用了null引用后说,"使用它导致了 ...

最新文章

  1. Asp.net MVC2.0系列文章-添加操作
  2. Python数据类型——整型、布尔型、列表、元祖、字典
  3. vc++基于颜色直方图的图像检索,含代码
  4. 8Linux服务器编程之:chdir()函数和cd命令,getcwd()函数和pwd
  5. 【BZOJ 2298】 2298: [HAOI2011]problem a (DP)
  6. 基于ZooKeeper的Dubbo注册中心【转】
  7. 考研笔记-物理层协议
  8. 苹果公司发布TestFlight Groups,放宽二进制版本提交限制
  9. Android Studio Gradle下载慢解决方法
  10. MATLAB求导函数diff(a,b,c)
  11. Android中TextToSpeech的使用
  12. matlab 平滑曲线连接_基于S型曲线的连续多段曲线插补平滑过渡的规划算法(Matlab)...
  13. MATLAB清除内存中变量
  14. 团队内部分享--工作杂谈(读书推荐)
  15. matlab 呼吸灯,一种控制呼吸灯呼吸效果的方法与流程
  16. 今生梦一场,思念你的殇
  17. 【ct107d】独立键盘
  18. 有哪些图片转excel表格的软件?
  19. 证件照在线生成源代码
  20. 洛克希德马丁可安装在卡车的小型核聚变反应堆10年内诞生

热门文章

  1. apache ignite_Kubernetes集群上的Apache Ignite和Spring第1部分:Spring Boot应用程序
  2. 螺旋测微器 flash_使用测微计收集应用程序指标
  3. java实现资源监视器_实现Java监视的12个步骤程序存在缺陷
  4. jvm7 jvm8_自我修复的JVM
  5. vb使用字符串分隔字符串_为什么要使用字符串
  6. 用户控件 自定义控件_新的自定义控件:TaskProgressView
  7. 流利的接口不利于维护
  8. Apache Kafka简介
  9. 琥珀项目:Java的未来揭晓
  10. 实践中的弹性基础架构