目录

Google Guava

Google core libraries for Java

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.1-jre</version>
</dependency>
1
implementation 'com.google.guava:guava:31.1-jre'

Object common methods

equals

1
2
3
4
Objects.equal("a", "a"); // returns true
Objects.equal(null, "a"); // returns false
Objects.equal("a", null); // returns false
Objects.equal(null, null); // returns true

注意:JDK 7 中新引入的Objects类提供了等效的 Objects.equals 方法。

hashCode

Guava Objects.hashCode(Object...) 为指定的字段序列创建了一个合理的、顺序敏感的散列。

注意:JDK 7 中新引入的Objects类提供了等价物 Objects.hash(Object...)

toString

使用 MoreObjects.toStringHelper() 很容易创建 toString

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public class User {

    private long id;
    private String name;

    public User(long id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
            .add("id", id)
            .add("name", name)
            .toString();
    }
}

compare/compareTo

ComparisonChain 执行“惰性”比较:它只执行比较,直到找到非零结果,然后忽略进一步的输入。

1
2
3
4
5
6
7
public int compareTo(Foo that) {
     return ComparisonChain.start()
         .compare(this.aString, that.aString)
         .compare(this.anInt, that.anInt)
         .compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast())
         .result();
   }

Comparing Doubles in Java

1
2
3
4
5
6
7
double epsilon = 0.000001d;
// JDK
assertThat(Math.abs(d1 - d2) < epsilon).isTrue();
// JUnit
assertEquals(d1, d2, epsilon);
// Guava
assertThat(DoubleMath.fuzzyEquals(d1, d2, epsilon)).isTrue();

Collections

Immutable Collections

1
2
3
4
5
6
7
8
public static final ImmutableSet<Color> GOOGLE_COLORS =
   ImmutableSet.<Color>builder()
       .addAll(WEBSAFE_COLORS)
       .add(new Color(0, 191, 255))
       .build();

ImmutableSet<String> foobar = ImmutableSet.of("foo", "bar", "baz");
ImmutableList<String> defensiveCopy = ImmutableList.copyOf(foobar);

New Collection Types

Multiset

支持添加相同元素

Multimap

映射 key 到多个值

1
2
3
4
5
6
7
// creates a ListMultimap with tree keys and array list values
ListMultimap<String, Integer> treeListMultimap =
    MultimapBuilder.treeKeys().arrayListValues().build();

// creates a SetMultimap with hash keys and enum set values
SetMultimap<Integer, MyEnum> hashEnumMultimap =
    MultimapBuilder.hashKeys().enumSetValues(MyEnum.class).build();

BiMap

不仅可以通过 key 找到 value,还可以通过 value 找到 key。确保你的 values 是唯一的,不然会报 IllegalArgumentExceptionBiMap.forcePut(key, value) 可以强制更新相同 value 的 key。

1
2
BiMap<String, Integer> userId = HashBiMap.create();
String userForId = userId.inverse().get(id);

Table

1
2
3
4
5
6
7
8
Table<Vertex, Vertex, Double> weightedGraph = HashBasedTable.create();
weightedGraph.put(v1, v2, 4);
weightedGraph.put(v1, v3, 20);
weightedGraph.put(v2, v3, 5);
// returns a Map mapping v2 to 4, v3 to 20
weightedGraph.row(v1);
// returns a Map mapping v1 to 20, v2 to 5
weightedGraph.column(v3);

String utilities

Strings

1
2
3
4
5
6
7
// 最长共同前缀
commonPrefix(java.lang.CharSequence a, java.lang.CharSequence b)
// 如果给定 string 为 non-null 则返回空字符串
nullToEmpty(java.lang.String string)
isNullOrEmpty(java.lang.String string)

repeat(java.lang.String string, int count)

Joiner

1
2
Joiner joiner = Joiner.on("; ").skipNulls();
return joiner.join("Harry", null, "Ron", "Hermione");

Splitter

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Splitter.on(',')
    .trimResults()
    .omitEmptyStrings()
    .split("foo,bar,,   qux");

String example = "Mary;Thomas:Jane-Kate";
String[] expectedArray = new String[]{"Mary", "Thomas", "Jane", "Kate"};

Iterable<String> names = Splitter.on(Pattern.compile("[;:-]")).split(example);
Iterable<String> names = Splitter.onPattern("[;:-]").split(example);
Iterable<String> names = Splitter.on(CharMatcher.anyOf(";:-")).split(example);

Assertions.assertEquals(4, Iterators.size(names.iterator()));
Assertions.assertIterableEquals(Arrays.asList(expectedArray), names);

CharMatcher

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// remove control characters
String noControl = CharMatcher.javaIsoControl().removeFrom(string);
// only the digits
String theDigits = CharMatcher.digit().retainFrom(string);
// trim whitespace at ends, and replace/collapse whitespace into single spaces
String spaced = CharMatcher.whitespace().trimAndCollapseFrom(string, ' ');
 // star out all digits
String noDigits = CharMatcher.javaDigit().replaceFrom(string, "*");
// 排除非数字及小写字符
String lowerAndDigit = CharMatcher.javaDigit().or(CharMatcher.javaLowerCase()).retainFrom(string);

Charsets

1
bytes = string.getBytes(Charsets.UTF_8);

JDK7 后你可以使用 StandardCharsets

Ranges

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()
1
2
3
4
Range.closed(1, 3).contains(2); // returns true
Range.closed(1, 3).contains(4); // returns false
Range.lessThan(5).contains(5); // returns false
Range.closed(1, 4).containsAll(Ints.asList(1, 2, 3)); // returns true

I/O utilities

ByteStreams and CharStreams

ByteStreams CharStreams
byte[] toByteArray(InputStream) String toString(Readable)
N/A List<String> readLines(Readable)
long copy(InputStream, OutputStream) long copy(Readable, Appendable)
void readFully(InputStream, byte[]) N/A
void skipFully(InputStream, long) void skipFully(Reader, long)
OutputStream nullOutputStream() Writer nullWriter()

Sources and sinks

Operations Bytes Chars
Reading ByteSource CharSource
Writing ByteSink CharSink
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// Read the lines of a UTF-8 text file
ImmutableList<String> lines = Files.asCharSource(file, Charsets.UTF_8)
    .readLines();

// Count distinct word occurrences in a file
Multiset<String> wordOccurrences = HashMultiset.create(
    Splitter.on(CharMatcher.whitespace())
        .trimResults()
        .omitEmptyStrings()
        .split(Files.asCharSource(file, Charsets.UTF_8).read()));

// SHA-1 a file
HashCode hash = Files.asByteSource(file).hash(Hashing.sha1());

// Copy the data from a URL to a file
Resources.asByteSource(url).copyTo(Files.asByteSink(file));

Hashing

Provided Hash Functions

  • md5()
  • murmur3_128()
  • murmur3_32()
  • sha1()
  • sha256()
  • sha512()
  • goodFastHash(int bits)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
HashFunction hf = Hashing.md5();
HashCode hc = hf.newHasher()
       .putLong(id)
       .putString(name, Charsets.UTF_8)
       .putObject(person, personFunnel)
       .hash();
// generate the MD5 checksum for a file
File file = new File(filePath);
ByteSource byteSource = com.google.common.io.Files.asByteSource(file);
HashCode hc = byteSource.hash(Hashing.md5());
String checksum = hc.toString();


int receivedData = 123;
HashCode hashCode = Hashing.crc32c().hashInt(receivedData);

BloomFilter

1
2
3
4
5
6
7
8
9
BloomFilter<Person> friends = BloomFilter.create(personFunnel, 500, 0.01);
for (Person friend : friendsList) {
  friends.put(friend);
}
// much later
if (friends.mightContain(dude)) {
  // the probability that dude reached this place if he isn't a friend is 1%
  // we might, for example, start asynchronously loading things for dude while we do a more expensive exact check
}

附录