Comprehensive Java library providing essential utilities, immutable collections, caching, and concurrency tools for modern Java development.
—
Hash functions, mathematical operations with overflow checking, and statistical utilities for precise numerical computations and data integrity verification.
Core interfaces for computing hash codes with various algorithms.
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hasher;
import com.google.common.hash.HashCode;
import com.google.common.hash.Hashing;
import java.nio.charset.StandardCharsets;
// Get hash functions
HashFunction murmur3 = Hashing.murmur3_32_fixed(); // Fixed seed Murmur3
HashFunction sha256 = Hashing.sha256();
HashFunction md5 = Hashing.md5();
HashFunction crc32 = Hashing.crc32();
// Simple hashing
HashCode hash1 = murmur3.hashString("Hello World", StandardCharsets.UTF_8);
HashCode hash2 = sha256.hashBytes("Hello World".getBytes(StandardCharsets.UTF_8));
HashCode hash3 = crc32.hashInt(42);
HashCode hash4 = murmur3.hashLong(123456789L);
// Using Hasher for complex objects
Hasher hasher = murmur3.newHasher();
hasher.putString("user", StandardCharsets.UTF_8);
hasher.putInt(25); // age
hasher.putLong(System.currentTimeMillis()); // timestamp
hasher.putBytes("additional data".getBytes());
HashCode complexHash = hasher.hash();
// Hash code representations
String hexString = hash1.toString(); // Hex representation
byte[] bytes = hash1.asBytes(); // Raw bytes
int intValue = hash1.asInt(); // As 32-bit int (if hash is 32-bit)
long longValue = hash1.asLong(); // As 64-bit long (if hash is 64-bit or larger)
// Hash function properties
int bits = murmur3.bits(); // Number of bits in hash (32 for murmur3_32)
boolean goodForSigning = sha256.bits() >= 256; // Cryptographically secureComprehensive set of hash functions for different use cases.
// Non-cryptographic hash functions (fast, good distribution)
HashFunction murmur3_32 = Hashing.murmur3_32(); // 32-bit Murmur3
HashFunction murmur3_32_fixed = Hashing.murmur3_32_fixed(); // Fixed seed
HashFunction murmur3_128 = Hashing.murmur3_128(); // 128-bit Murmur3
HashFunction sipHash24 = Hashing.sipHash24(); // SipHash-2-4
// Cryptographic hash functions (secure but slower)
HashFunction md5 = Hashing.md5(); // MD5 (128-bit, deprecated for security)
HashFunction sha1 = Hashing.sha1(); // SHA-1 (160-bit, deprecated for security)
HashFunction sha256 = Hashing.sha256(); // SHA-256 (256-bit, secure)
HashFunction sha384 = Hashing.sha384(); // SHA-384 (384-bit, secure)
HashFunction sha512 = Hashing.sha512(); // SHA-512 (512-bit, secure)
// Checksums
HashFunction crc32 = Hashing.crc32(); // CRC32 checksum
HashFunction crc32c = Hashing.crc32c(); // CRC32C checksum
// Good general-purpose hash function
HashFunction good = Hashing.goodFastHash(32); // Good 32-bit hash
HashFunction good128 = Hashing.goodFastHash(128); // Good 128-bit hash
// Use cases:
// - Hash tables, bloom filters: murmur3_32, goodFastHash
// - Checksums, data integrity: crc32, crc32c
// - Cryptographic signatures: sha256, sha512
// - Consistent hashing: murmur3_128Type-safe way to feed data into hash functions.
import com.google.common.hash.Funnel;
import com.google.common.hash.Funnels;
import com.google.common.hash.PrimitiveSink;
// Built-in funnels for common types
Funnel<byte[]> byteArrayFunnel = Funnels.byteArrayFunnel();
Funnel<String> stringFunnel = Funnels.stringFunnel(StandardCharsets.UTF_8);
Funnel<Integer> integerFunnel = Funnels.integerFunnel();
Funnel<Long> longFunnel = Funnels.longFunnel();
// Using funnels with hash functions
HashFunction hasher = Hashing.murmur3_32();
HashCode stringHash = hasher.hashObject("Hello", stringFunnel);
HashCode intHash = hasher.hashObject(42, integerFunnel);
// Custom funnel for complex objects
public class Person {
private final String name;
private final int age;
private final String email;
// Constructor, getters...
public static final Funnel<Person> FUNNEL = new Funnel<Person>() {
@Override
public void funnel(Person person, PrimitiveSink into) {
into.putString(person.name, StandardCharsets.UTF_8)
.putInt(person.age)
.putString(person.email, StandardCharsets.UTF_8);
}
};
}
// Use custom funnel
Person person = new Person("John", 30, "john@example.com");
HashCode personHash = murmur3.hashObject(person, Person.FUNNEL);
// Sequential funnel for collections
Funnel<Iterable<String>> listFunnel = Funnels.sequentialFunnel(stringFunnel);
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
HashCode listHash = murmur3.hashObject(names, listFunnel);Probabilistic data structure for testing set membership with configurable false positive rate.
import com.google.common.hash.BloomFilter;
// Create bloom filter for strings
BloomFilter<String> bloomFilter = BloomFilter.create(
Funnels.stringFunnel(StandardCharsets.UTF_8),
1000, // Expected number of insertions
0.01 // Desired false positive probability (1%)
);
// Add elements
bloomFilter.put("apple");
bloomFilter.put("banana");
bloomFilter.put("cherry");
// Test membership
boolean mightContain1 = bloomFilter.mightContain("apple"); // true (definitely in set)
boolean mightContain2 = bloomFilter.mightContain("grape"); // false (definitely not in set)
boolean mightContain3 = bloomFilter.mightContain("date"); // might be false positive
// Bloom filter for custom objects
BloomFilter<Person> personFilter = BloomFilter.create(
Person.FUNNEL,
10000, // Expected 10,000 people
0.001 // 0.1% false positive rate
);
personFilter.put(new Person("Alice", 25, "alice@example.com"));
boolean found = personFilter.mightContain(new Person("Bob", 30, "bob@example.com"));
// Monitor bloom filter performance
double fpp = bloomFilter.expectedFpp(); // Current false positive probability
long approximateCount = bloomFilter.approximateElementCount(); // Estimated elements added
// Combining bloom filters (union operation)
BloomFilter<String> filter1 = BloomFilter.create(stringFunnel, 100, 0.01);
BloomFilter<String> filter2 = BloomFilter.create(stringFunnel, 100, 0.01);
filter1.put("a");
filter2.put("b");
filter1.putAll(filter2); // filter1 now contains elements from both filtersUtility methods for combining and manipulating hash codes.
// Combining hash codes
HashCode hash1 = Hashing.sha256().hashString("part1", StandardCharsets.UTF_8);
HashCode hash2 = Hashing.sha256().hashString("part2", StandardCharsets.UTF_8);
// Ordered combination (order matters)
HashCode combined = Hashing.combineOrdered(Arrays.asList(hash1, hash2));
// Unordered combination (order doesn't matter)
HashCode combinedUnordered = Hashing.combineUnordered(Arrays.asList(hash1, hash2));
// Consistent hashing (for distributed systems)
int bucket = Hashing.consistentHash(hash1, 100); // Map to bucket 0-99
int bucket2 = Hashing.consistentHash(hash1.asLong(), 100); // Alternative
// Creating hash codes from existing values
HashCode fromInt = HashCode.fromInt(42);
HashCode fromLong = HashCode.fromLong(123456789L);
HashCode fromBytes = HashCode.fromBytes(new byte[]{1, 2, 3, 4});
HashCode fromString = HashCode.fromString("deadbeef"); // From hex stringSafe mathematical operations on integers with overflow checking.
import com.google.common.math.IntMath;
import java.math.RoundingMode;
// Checked arithmetic (throws ArithmeticException on overflow)
int sum = IntMath.checkedAdd(Integer.MAX_VALUE - 1, 1); // OK
// int overflow = IntMath.checkedAdd(Integer.MAX_VALUE, 1); // Throws ArithmeticException
int difference = IntMath.checkedSubtract(100, 50); // 50
int product = IntMath.checkedMultiply(1000, 1000); // 1,000,000
int power = IntMath.checkedPow(2, 10); // 1024
// Mathematical operations
int gcd = IntMath.gcd(48, 18); // 6 (greatest common divisor)
int mod = IntMath.mod(-5, 3); // 1 (always non-negative result)
int pow = IntMath.pow(3, 4); // 81
// Square root with rounding
int sqrt1 = IntMath.sqrt(15, RoundingMode.DOWN); // 3
int sqrt2 = IntMath.sqrt(15, RoundingMode.UP); // 4
int sqrt3 = IntMath.sqrt(16, RoundingMode.EXACT); // 4 (exact)
// Logarithms
int log2 = IntMath.log2(8, RoundingMode.EXACT); // 3
int log10 = IntMath.log10(1000, RoundingMode.EXACT); // 3
int log2Rounded = IntMath.log2(15, RoundingMode.UP); // 4
// Factorial
int factorial5 = IntMath.factorial(5); // 120
int factorial0 = IntMath.factorial(0); // 1
// Binomial coefficient (n choose k)
int binomial = IntMath.binomial(10, 3); // 120 (10 choose 3)
// Power of two operations
boolean isPowerOfTwo = IntMath.isPowerOfTwo(16); // true
int nextPowerOfTwo = IntMath.ceilingPowerOfTwo(15); // 16
int prevPowerOfTwo = IntMath.floorPowerOfTwo(15); // 8
// Mean calculation (avoids overflow)
int mean = IntMath.mean(1000000000, 2000000000); // Doesn't overflowSimilar mathematical operations for long values.
import com.google.common.math.LongMath;
// Checked arithmetic for longs
long checkedSum = LongMath.checkedAdd(Long.MAX_VALUE - 1, 1);
long checkedProduct = LongMath.checkedMultiply(1000000L, 1000000L);
long checkedPower = LongMath.checkedPow(2L, 62);
// Mathematical operations
long gcd = LongMath.gcd(123456789L, 987654321L);
long mod = LongMath.mod(-15L, 7L); // 6
long pow = LongMath.pow(10L, 9); // 1,000,000,000
// Square root and logarithms
long sqrt = LongMath.sqrt(1000000L, RoundingMode.DOWN); // 1000
long log2 = LongMath.log2(1024L, RoundingMode.EXACT); // 10
long log10 = LongMath.log10(1000000L, RoundingMode.EXACT); // 6
// Large factorials (as long as they fit in long)
long factorial10 = LongMath.factorial(10); // 3,628,800
long factorial20 = LongMath.factorial(20); // 2,432,902,008,176,640,000
// Binomial coefficients
long binomial = LongMath.binomial(20, 10); // 184,756
// Power of two operations
boolean isPowerOfTwo = LongMath.isPowerOfTwo(1024L); // true
long mean = LongMath.mean(1000000000000L, 2000000000000L);Mathematical operations on double values with proper rounding and precision handling.
import com.google.common.math.DoubleMath;
import java.math.BigInteger;
// Rounding operations
int roundedToInt = DoubleMath.roundToInt(3.7, RoundingMode.HALF_UP); // 4
long roundedToLong = DoubleMath.roundToLong(3.14159, RoundingMode.DOWN); // 3
BigInteger roundedToBigInt = DoubleMath.roundToBigInteger(1.23e15, RoundingMode.UP);
// Logarithms
double log2 = DoubleMath.log2(8.0); // 3.0
double log2Approx = DoubleMath.log2(10.0); // ~3.3219
// Factorial as double (for larger values)
double factorial100 = DoubleMath.factorial(100); // Very large number
// Fuzzy comparison (with tolerance)
boolean equal = DoubleMath.fuzzyEquals(3.14159, 3.14160, 0.001); // true
int comparison = DoubleMath.fuzzyCompare(3.14, 3.15, 0.1); // 0 (equal within tolerance)
// Mathematical properties
boolean isInteger = DoubleMath.isMathematicalInteger(3.0); // true
boolean isInteger2 = DoubleMath.isMathematicalInteger(3.1); // false
boolean isPowerOfTwo = DoubleMath.isPowerOfTwo(8.0); // true
// Finite check
boolean isFinite = DoubleMath.isFinite(3.14); // true
boolean isFinite2 = DoubleMath.isFinite(Double.POSITIVE_INFINITY); // falseMathematical operations on BigInteger values for arbitrary precision.
import com.google.common.math.BigIntegerMath;
import java.math.BigInteger;
// Square root
BigInteger big = new BigInteger("1000000000000000000000"); // 10^21
BigInteger sqrt = BigIntegerMath.sqrt(big, RoundingMode.DOWN);
// Logarithms
BigInteger large = new BigInteger("1024");
int log2 = BigIntegerMath.log2(large, RoundingMode.EXACT); // 10
int log10 = BigIntegerMath.log10(new BigInteger("1000"), RoundingMode.EXACT); // 3
// Factorial (can handle very large values)
BigInteger factorial50 = BigIntegerMath.factorial(50);
BigInteger factorial100 = BigIntegerMath.factorial(100);
// Binomial coefficient
BigInteger binomial = BigIntegerMath.binomial(100, 50); // 100 choose 50
// Power of two test
boolean isPowerOfTwo = BigIntegerMath.isPowerOfTwo(new BigInteger("1024")); // true
// Divide and round
BigInteger dividend = new BigInteger("1000");
BigInteger divisor = new BigInteger("3");
BigInteger quotient = BigIntegerMath.divide(dividend, divisor, RoundingMode.UP); // 334Statistical operations and data analysis utilities.
import com.google.common.math.Stats;
import com.google.common.math.StatsAccumulator;
import com.google.common.math.PairedStats;
import com.google.common.math.PairedStatsAccumulator;
// Creating statistics from data
double[] values = {1.0, 2.0, 3.0, 4.0, 5.0};
Stats stats = Stats.of(values);
// Basic statistics
long count = stats.count(); // 5
double mean = stats.mean(); // 3.0
double sum = stats.sum(); // 15.0
double min = stats.min(); // 1.0
double max = stats.max(); // 5.0
// Variance and standard deviation
double popVariance = stats.populationVariance(); // Population variance
double popStdDev = stats.populationStandardDeviation(); // Population std dev
double sampleVariance = stats.sampleVariance(); // Sample variance
double sampleStdDev = stats.sampleStandardDeviation(); // Sample std dev
// Accumulating statistics incrementally
StatsAccumulator accumulator = new StatsAccumulator();
accumulator.add(1.0);
accumulator.add(2.0, 3.0, 4.0); // Add multiple values
accumulator.addAll(Arrays.asList(5.0, 6.0)); // Add from collection
Stats incrementalStats = accumulator.snapshot(); // Get current stats
// Paired statistics (for correlation analysis)
double[] xValues = {1.0, 2.0, 3.0, 4.0, 5.0};
double[] yValues = {2.0, 4.0, 6.0, 8.0, 10.0};
PairedStatsAccumulator pairedAccumulator = new PairedStatsAccumulator();
for (int i = 0; i < xValues.length; i++) {
pairedAccumulator.add(xValues[i], yValues[i]);
}
PairedStats pairedStats = pairedAccumulator.snapshot();
// Individual variable statistics
Stats xStats = pairedStats.xStats();
Stats yStats = pairedStats.yStats();
// Correlation analysis
double correlation = pairedStats.pearsonsCorrelationCoefficient(); // 1.0 (perfect positive)
// Linear regression
PairedStats.LinearTransformation regression = pairedStats.leastSquaresFit();
double slope = regression.slope(); // 2.0
double intercept = regression.intercept(); // 0.0
// Predict y value for given x
double predicted = regression.transform(3.5); // 7.0Computing percentiles, quartiles, and other quantiles from data.
import com.google.common.math.Quantiles;
double[] data = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0};
// Median (50th percentile)
double median = Quantiles.median().compute(data); // 5.5
// Quartiles
Map<Integer, Double> quartiles = Quantiles.quartiles().compute(data);
double q1 = quartiles.get(1); // 25th percentile (3.25)
double q2 = quartiles.get(2); // 50th percentile (5.5) - same as median
double q3 = quartiles.get(3); // 75th percentile (7.75)
// Percentiles
Map<Integer, Double> percentiles = Quantiles.percentiles().compute(data);
double p10 = percentiles.get(10); // 10th percentile
double p90 = percentiles.get(90); // 90th percentile
// Custom quantile scale
Quantiles.ScaleAndIndex scale = Quantiles.scale(100); // Percentiles (0-100)
double p95 = scale.index(95).compute(data); // 95th percentile
// Multiple quantiles at once
Map<Integer, Double> deciles = Quantiles.scale(10).indexes(1, 2, 3, 4, 5, 6, 7, 8, 9)
.compute(data); // 10th, 20th, ..., 90th percentiles
// Working with collections
List<Double> dataList = Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0);
double medianFromList = Quantiles.median().compute(dataList);Real-world examples combining hash and math utilities.
// Data integrity verification
public class DataVerifier {
private final HashFunction hashFunction = Hashing.sha256();
public String computeChecksum(File file) throws IOException {
HashCode hash = Files.asByteSource(file).hash(hashFunction);
return hash.toString();
}
public boolean verifyIntegrity(File file, String expectedChecksum) throws IOException {
String actualChecksum = computeChecksum(file);
return actualChecksum.equals(expectedChecksum);
}
}
// Consistent hashing for load balancing
public class ConsistentHashLoadBalancer {
private final List<String> servers;
private final HashFunction hashFunction = Hashing.murmur3_32();
public ConsistentHashLoadBalancer(List<String> servers) {
this.servers = ImmutableList.copyOf(servers);
}
public String selectServer(String key) {
HashCode hash = hashFunction.hashString(key, StandardCharsets.UTF_8);
int bucket = Hashing.consistentHash(hash, servers.size());
return servers.get(bucket);
}
}
// Mathematical analysis with overflow protection
public class SafeCalculator {
public OptionalLong safeMultiply(int... values) {
try {
long result = 1L;
for (int value : values) {
result = LongMath.checkedMultiply(result, value);
}
return OptionalLong.of(result);
} catch (ArithmeticException e) {
return OptionalLong.empty(); // Overflow occurred
}
}
public Stats analyzeDataset(double[] values) {
Stats stats = Stats.of(values);
System.out.println("Dataset Analysis:");
System.out.println("Count: " + stats.count());
System.out.println("Mean: " + stats.mean());
System.out.println("Std Dev: " + stats.populationStandardDeviation());
// Detect outliers (values more than 2 std devs from mean)
double threshold = 2.0 * stats.populationStandardDeviation();
List<Double> outliers = Arrays.stream(values)
.filter(v -> Math.abs(v - stats.mean()) > threshold)
.boxed()
.collect(Collectors.toList());
System.out.println("Outliers: " + outliers);
return stats;
}
}
// Bloom filter for duplicate detection
public class DuplicateDetector<T> {
private final BloomFilter<T> bloomFilter;
private final Set<T> confirmedItems = new HashSet<>();
public DuplicateDetector(Funnel<T> funnel, int expectedItems) {
this.bloomFilter = BloomFilter.create(funnel, expectedItems, 0.01);
}
public boolean addIfAbsent(T item) {
if (bloomFilter.mightContain(item)) {
// Might be duplicate, check actual set
if (confirmedItems.contains(item)) {
return false; // Confirmed duplicate
}
}
// Add to both bloom filter and confirmed set
bloomFilter.put(item);
confirmedItems.add(item);
return true; // Successfully added
}
}Guava's hash and math utilities provide robust, efficient solutions for data integrity, mathematical computations, and statistical analysis with proper error handling and precision control.
Install with Tessl CLI
npx tessl i tessl/maven-com-google-guava--guava