分类 编程 下的文章

新集合类型

Guava引入了很多JDK没有的、但我们发现非常有用的新集合类型。这些新类型是为了和JDK集合框架共存,而没有往JDK集合抽象中硬塞其他概念。作为一般规则,Guava集合非常精准地遵循了JDK接口契约。

Multiset

统计一个词在文档中出现了多少次,传统的做法是这样的:

Map<String, Integer> counts = new HashMap<String, Integer>();
for (String word : words) {
    Integer count = counts.get(word);
    if (count == null) {
        counts.put(word, 1);
    } else {
        counts.put(word, count + 1);
    }
}

- 阅读剩余部分 -

异常传播

有时候,你会想把捕获到的异常再次抛出。这种情况通常发生在Error或RuntimeException被捕获的时候,你没想捕获它们,但是声明捕获Throwable和Exception的时候,也包括了了Error或RuntimeException。Guava提供了若干方法,来判断异常类型并且重新传播异常。例如:

try {
    someMethodThatCouldThrowAnything();
} catch (IKnowWhatToDoWithThisException e) {
    handle(e);
} catch (Throwable t) {
    Throwables.propagateIfInstanceOf(t, IOException.class);
    Throwables.propagateIfInstanceOf(t, SQLException.class);
    throw Throwables.propagate(t);
}

所有这些方法都会自己决定是否要抛出异常,但也能直接抛出方法返回的结果——例如,throw Throwables.propagate(t);—— 这样可以向编译器声明这里一定会抛出异常。

- 阅读剩余部分 -

在本文中,我们将介绍Guava库中Ordering类。

Ordering类实现了Comparator接口,它可以用来为构建复杂的比较器,以完成集合排序的功能。

从实现上说,Ordering实例就是一个特殊的Comparator实例。Ordering把很多基于Comparator的静态方法(如Collections.max)包装为自己的实例方法(非静态方法),并且提供了链式调用方法,来定制和增强现有的比较器。

创建

natural()

使用自然顺序排序

List<Integer> list = Arrays.asList(1, 5, 3, 8, 2);
Collections.sort(list, Ordering.natural());

- 阅读剩余部分 -

Java中的Object类是所有Java类的超类(也就是祖先),所有对象都实现Object类中的方法,在日常的工作中,我们经常需要重写其中的几个 方法, 如:equals、toString、hashCode等方法,而在工作中,我们实现这些方法有时候也比较痛苦,如equals方法判断非空、 toString调试信息不完整等等,在Guava中,其提供了Objects类帮助我们简化了这些常用方法的实现,接下来,我们一起来学习一下。

equals

当一个对象中的字段可以为null时,实现Object.equals方法会很痛苦,因为不得不分别对它们进行null检查。使用Objects.equal帮助你执行null敏感的equals判断,从而避免抛出NullPointerException。

例如:

Objects.equal("a", "a"); // returns true
Objects.equal(null, "a"); // returns false
Objects.equal("a", null); // returns false
Objects.equal(null, null); // returns true

- 阅读剩余部分 -

"Null sucks." -Doug Lea
"I call it my billion-dollar mistake." - Sir C. A. R. Hoare, on his invention of the null reference

轻率地使用null可能会导致很多令人费解的问题。我们发现95%的集合类不接受null值作为元素。我们认为,相比默默地接受null,使用快速失败操作拒绝null值对开发者更有帮助。

null的含糊语义让人很不舒服。null很少可以明确地表示某种语义,例如,Map.get(key)返回null时,可能表示map中的值是null,亦或map中没有key对应的值。null可以表示失败、成功或几乎任何情况。使用Null以外的特定值,会让你的逻辑描述变得更清晰。

null确实也有合适和正确的使用场景,如在性能和速度方面null是廉价的,而且在对象数组中,出现null也是无法避免的。但相对于底层库来说,在应用级别的代码中,null往往是导致混乱,疑难问题和模糊语义的元凶,就如同我们举过的Map.get(key)的例子。最关键的是,null本身没有定义它表达的意
思。

鉴于这些原因,很多Guava工具类对Null值都采用快速失败操作,除非工具类本身提供了针对Null值的因变措施。此外,Guava还提供了很多工具类,让你更方便地用特定值替换Null值。

- 阅读剩余部分 -

概述

在我们的日常开发中,经常要对入参进行一定的参数校验,比如是否为空,参数的取值范围是否符合要求等等。这种参数校验如果我们单独进行校验的话,代码的重复率比较高,也不是很优雅。Guava提供了一个类Preconditions来统一校验我们的参数,同时可以抛出对应的异常信息,将参数校验的工作进行了统一。

Preconditions

Preconditions类中的每个静态方法都支持三种方式:

  • 无额外参数, 抛出的异常中没有错误消息
  • 指定error message 抛出指定error message的异常
  • 额外的字符串参数 替换带有占位符的error message消息。这个变种处理异常消息的方式有点类似printf,但考虑GWT的兼容性和效率,只支持%s指示符。
注意:checkNotNull、checkArgument和checkState有大量的重载,它们采用可变参数方式。
checkArgument(i >= 0, "Argument was %s but expected nonnegative", i);
checkArgument(i < j, "Expected i < j, but %s > %s", i, j);

以下是com.google.common.base.Preconditions类的声明:

@GwtCompatible
public final class Preconditions {}

- 阅读剩余部分 -

简介

Guava是Google开源的核心Java库,Google Guava源于2007年的"Google Collections Library"。这个库是为了方便编码,并减少编码错误。主要功能包括集合 [collections] 、缓存 [caching] 、原生类型支持 [primitives support] 、并发库 [concurrency libraries] 、通用注解 [common annotations] 、字符串处理 [string processing] 、I/O 等等。这些每天都在被Google的工程师应用在产品服务中。

优点

  • 标准化 - Guava库是由谷歌托管。
  • 高效 - 可靠,快速和有效的扩展JAVA标准库
  • 优化 -Guava库经过高度的优化。

函数式编程:增加Java功能和处理能力。

实用程序:提供经常需要在应用程序中开发的许多实用程序类。

验证:提供标准的故障安全验证机制。

最佳实践:强调最佳的做法。

总之,它是一个提高代码质量、简化工作,促使代码更有弹性、更加简洁的工具。

- 阅读剩余部分 -

Linux 平台上不同发行版的包管理不一样, 因此工具的使用也有区别, 这里我们介绍下常见的一些发行版系统包管理的流程, 顺带也介绍下 FreeBSD 的包管理机制.

Debian/Ubuntu

在基于 Debian 的发行版上一般使用 apt-get 工具来对软件包进行管理, 当然也有些变种, 比如 apt/aptitute, 使用起来有些区别, 但是核心功能基本一致, 一般还需要配合 apt-cache, dpkg等等工具

安装软件包

apt-get install package_name

卸载软件包

卸载的过程中, 不清理配置文件

apt-get remove package_name

或者

卸载时同时卸载软件和其配置文件

apt-get purge package_name

- 阅读剩余部分 -

分割字符串是一种非常常见的操作,本教程主要介绍一些我们可以在Java中简单使用的API。

String.split()

让我们从核心库开始,String类本身提供了一个split()方法——这对于大多数场景都非常方便和充分。它只是根据分隔符分割给定的字符串,返回字符串数组。

String[] splitted = "peter,james,thomas".split(",");

String[] splitted = "car jeep scooter".split(" ");

String[] splitted = "192.168.1.178".split("\\.")

String[] splitted = "b a, e, l.d u, n g".split("\\s+|,\\s*|\\.\\s*"));

- 阅读剩余部分 -

线程是在一个进程里,一个并发执行的顺序的流程。

例如,考虑一个文本编辑器,它在输入特定长度的文本后执行自动保存操作。
现在有两个任务,首先显示输入到编辑器中的文本,然后执行自动保存。
因为这两个任务应该并行执行,所以它们在不同的线程中执行。如果两个操作都在同一个线程上执行,那么当线程忙于保存时,它就不能执行输入过程,并且会显示一个延迟,直到保存操作完成。

创建线程有两种方法。

继承Thread类

每个线程都是线程的一个实例。因此,可以通过扩展thread类来创建一个新线程。扩展Thread的类应该运行其中定义的方法。Run方法包含要在线程中执行的任务。通过调用start方法启动新线程。

- 阅读剩余部分 -