guava
最近在公司的项目中注意到了一个依赖guava,在项目中很多地方都用到了它,特别是集合转换时大量使用,而Guava的通用性和实用性相信每一个javaer都有所体会,今天就来介绍一下这款来自Google的Java核心工具库。
官方是这样介绍Guava
Guava is a set of core Java libraries from Google that includes new collection types (such as multimap and multiset), immutable collections, a graph library, and utilities for concurrency, I/O, hashing, primitives, strings, and more! It is widely used on most Java projects within Google, and widely used by many other companies as well.
翻译过来就是,Guava 是 Google 的一组核心 Java 库,其中包括新的集合类型(例如 multimap 和 multiset)、不可变集合、图形库以及用于并发、I/O、哈希、原语、字符串等的实用程序!它被广泛用于 Google 内部的大多数 Java 项目,也被许多其他公司广泛使用。
字符串
Joiner
使用分隔符将字符串序列连接在一起可能会非常棘手,但事实并非如此。如果您的序列包含空值,则可能会更加困难。 Joiner 流畅的风格让它变得简单。
public void test() {
// Hello,null,World
log.info("{}", String.join(",", "Hello", null, "World"));
}
Joiner joiner = Joiner.on(", ").skipNulls();
// Harry, Ron, Hermione
log.info("{}", joiner.join("Harry", null, "Ron", "Hermione"));
您还可以在对象上使用 Joiner,这些对象将使用其 toString() 进行转换,然后连接。
Joiner.on(",").join(Arrays.asList(1, 5, 7)); // returns "1,5,7"
Splitter
用于分割字符串的内置 Java 实用程序有一些奇怪的行为。例如,String.split 会默默地丢弃尾随分隔符。
",a,,b,".split(",")
会返回什么?正确答案是"", "a", "", "b"
。丢失了最后一个空字符串,至于为什么我也不知道。Splitter 允许使用令人放心的简单流畅模式完全控制所有这些令人困惑的行为。
Splitter.on(',')
.trimResults()
.omitEmptyStrings()
.split("foo,bar,, qux");
返回一个Iterable<String>
包含"foo", "bar", "qux"
。Splitter 可以设置为根据任何 Pattern、char、String 或 CharMatcher 进行拆分。
Method | Description | Example |
---|---|---|
Splitter.on(char) | 根据出现的特定单个字符进行拆分。 | Splitter.on(';') |
Splitter.on(CharMatcher) | 在某个类别中出现任何字符时进行拆分。 | Splitter.on(CharMatcher.BREAKING_WHITESPACE) Splitter.on(CharMatcher.anyOf(";,.")) |
Splitter.on(String) | 拆分文字字符串。 | Splitter.on(", ") |
Splitter.on(Pattern) Splitter.onPattern(String) | 根据正则表达式进行拆分。 | Splitter.onPattern("\r?\n") |
Splitter.fixedLength(int) | 将字符串拆分为指定固定长度的子字符串。最后一块可以小于 length,但绝不会为空。 | Splitter.fixedLength(3) |
修饰
Method | Description | Example |
---|---|---|
omitEmptyStrings() | 自动从结果中省略空字符串。 | Splitter.on(',').omitEmptyStrings().split("a,,c,d") returns "a", "c", "d" |
trimResults() | 修剪结果中的空格;相当于trimResults(CharMatcher.WHITESPACE)。 | Splitter.on(',').trimResults().split("a, b, c, d") returns "a", "b", "c", "d" |
trimResults(CharMatcher) | 从结果中修剪与指定 CharMatcher 匹配的字符。 | Splitter.on(',').trimResults(CharMatcher.is('_')).split("_a ,_b_ ,c__") returns "a ", "b_ ", "c" . |
limit(int) | 返回指定数量的字符串后停止拆分。 | Splitter.on(',').limit(3).split("a,b,c,d") returns "a", "b", "c,d" |
还可以通过使用 splitToList()
返回一个列表
Ranges
Guava 强大的 API,可用于处理可比较类型的范围,包括连续的和离散的。
List<Double> scores;
Iterable<Double> belowMedianScores = Iterables.filter(scores, Range.lessThan(median));
...
Range<Integer> validGrades = Range.closed(1, 12);
for(int grade : ContiguousSet.create(validGrades, DiscreteDomain.integers())) {
...
}
表达式:
(a..b) = {x | a < x < b}
[a..b] = {x | a <= x <= b}
[a..b) = {x | a <= x < b}
(a..b] = {x | a < x <= b}
(a..+∞) = {x | x > a}
[a..+∞) = {x | x >= a}
(-∞..b) = {x | x < b}
(-∞..b] = {x | x <= b}
(-∞..+∞) = 全集
对应的静态方法:
Range type | Method |
---|---|
(a..b) | open(C, C) |
[a..b] | closed(C, C) |
[a..b) | closedOpen(C, C) |
(a..b] | openClosed(C, C) |
(a..+∞) | greaterThan(C) |
[a..+∞) | atLeast(C) |
(-∞..b) | lessThan(C) |
(-∞..b] | atMost(C) |
(-∞..+∞) | all() |
Range.closed("left", "right"); // “left”和“right”之间的所有字符串
Range.lessThan(4.0); // 严格小于4的double
Range<String> range = Range.closed("left", "right");
// false
log.info("{}", range.test("lefs"));
// true
log.info("{}", range.test("lefu"));
操作:
-
查询操作
Range.closedOpen(4, 4).isEmpty(); // returns true Range.openClosed(4, 4).isEmpty(); // returns true Range.closed(4, 4).isEmpty(); // returns false Range.open(4, 4).isEmpty(); // Range.open throws IllegalArgumentException Range.closed(3, 10).lowerEndpoint(); // returns 3 Range.open(3, 10).lowerEndpoint(); // returns 3 Range.closed(3, 10).lowerBoundType(); // returns CLOSED Range.open(3, 10).upperBoundType(); // returns OPEN
-
区间运算
-
encloses
[3..6]
encloses[4..5]
(3..6)
encloses(3..6)
[3..6]
encloses[4..4)
(即使后者是空的)(3..6]
does not enclose[3..6]
[4..5]
does not enclose(3..6)
即使它包含后一个范围包含的每个值,尽管使用离散域可以解决这个问题[3..6]
does not enclose(1..1]
即使它包含后一个范围包含的每个值
-
isConnected
Range.closed(3, 5).isConnected(Range.open(5, 10)); // returns true Range.closed(0, 9).isConnected(Range.closed(3, 4)); // returns true Range.closed(0, 5).isConnected(Range.closed(3, 9)); // returns true Range.open(3, 5).isConnected(Range.open(5, 10)); // returns false Range.closed(1, 5).isConnected(Range.closed(6, 10)); // returns false
-
intersection
Range.closed(3, 5).intersection(Range.open(5, 10)); // returns (5, 5] Range.closed(0, 9).intersection(Range.closed(3, 4)); // returns [3, 4] Range.closed(0, 5).intersection(Range.closed(3, 9)); // returns [3, 5] Range.open(3, 5).intersection(Range.open(5, 10)); // throws IAE Range.closed(1, 5).intersection(Range.closed(6, 10)); // throws IAE
-
span
Range.closed(3, 5).span(Range.open(5, 10)); // returns [3, 10) Range.closed(0, 9).span(Range.closed(3, 4)); // returns [0, 9] Range.closed(0, 5).span(Range.closed(3, 9)); // returns [0, 9] Range.open(3, 5).span(Range.open(5, 10)); // returns (3, 10) Range.closed(1, 5).span(Range.closed(6, 10)); // returns [1, 10]
-
Math
JDK 未提供经过优化、经过彻底测试的数学实用程序。
根据所涉及的主要数值类型,基本独立数学函数分为 IntMath、LongMath、DoubleMath 和 BigIntegerMath 类。这些类具有并行结构,但每个类仅支持相关的功能子集。
int logFloor = LongMath.log2(n, FLOOR);
int mustNotOverflow = IntMath.checkedMultiply(x, y);
long quotient = LongMath.divide(knownMultipleOfThree, 3, RoundingMode.UNNECESSARY); // fail fast on non-multiple of 3
BigInteger nearestInteger = DoubleMath.roundToBigInteger(d, RoundingMode.HALF_EVEN);
BigInteger sideLength = BigIntegerMath.sqrt(area, CEILING);