fundamentals\java\guava

Guava 常用功能

guava 是 google 项目团队多年沉淀下来的工具包,在现代的分布式系统中得到广泛的应用。

基于最新版本 Guava:

<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
	<groupId>com.google.guava</groupId>
	<artifactId>guava</artifactId>
	<version>31.1-jre</version>
</dependency>

guava.common

Precondition

异常判断

public static void main(String[] args) {
    
    
		
	TestPrecondition condition = new TestPrecondition();
	
	// 静态引入,
	condition = checkNotNull(condition);
	
	// 建议静态引入,提升效率import static com.google.common.base.Preconditions.checkArgument
	checkArgument(args.length == 0, "args %s missing. ", args.length);
	
	checkState(args.length == 0, "args not running");
	
	System.out.println(condition.toString());
	
}

@Override
public String toString() {
    
    
	
	// 输出 TestPrecondition{name='zs', id=1}
	return MoreObjects.toStringHelper(this)
			.add("name", name)
			.add("id", id)
			.add("petName", petName)
			// 剔除为空的属性
			.omitNullValues()
			.toString();
}

CharMatcher

public static void main(String[] args) {
    
    
		
	// CharMatcher 字符比较器,封装了常用字符比较算法
	String charMatcherResult = CharMatcher
			// 匹配字符 '0' ~ '9'
			.inRange('0', '9')
			// 或者:匹配任意字符 'a','b','c'
			.or(CharMatcher.anyOf("abc"))
			// 或者:不属于以下字符 'z' 'd' 'a' 'd' 'f'
			.or(CharMatcher.noneOf("zdadf"))
			// 或者:等于 '-'
			.or(CharMatcher.is('-'))
			// 原始字符
			.retainFrom("zdasd0dfdf-");
	
	// 结果 as0-
	System.out.println(charMatcherResult);
}

Comparators

public static void main(String[] args) {
    
    

	// JDK 原有比较器,tzId1,tzId2 是正序还是逆序?比较难于阅读
	Comparator<String> byReverserOffsetThenName = new Comparator<String>() {
    
    

		@Override
		public int compare(String tzId1, String tzId2) {
    
    
			int offset1 = tzId1 == null ? -1 : tzId1.indexOf("id");
			int offset2 = tzId2 == null ? -1 : tzId2.indexOf("id");
			
			int result = offset2 - offset1;
			return result == 0 ? tzId1.compareTo(tzId2) : result;
		}
	};
	
	Lists.newArrayList("aid", "ida", "idb", "bid").sort(byReverserOffsetThenName);
	
	// guava 提供 ComparisonChain 机制,代码更清晰易懂
	Ordering<String> byReverserOffsetThenName2 = new Ordering<String>() {
    
    

		@Override
		public int compare(String tzId1, String tzId2) {
    
    
			return ComparisonChain.start()
				.compare(tzId1 == null ? -1 : tzId1.indexOf("id"), tzId2 == null ? -1 : tzId2.indexOf("id"))
				.compare(tzId1, tzId2)
				.result();
		}
	};
	
	// Ordering 函数
	Ordering<String> cityOrdering = Ordering.from(byReverserOffsetThenName);
	
	ArrayList<String> list = Lists.newArrayList("aid", "ida", "idb", "bid");
	
	Lists.newArrayList("aid", "ida", "idb", "bid").sort(cityOrdering);
	
	list.sort(byReverserOffsetThenName2);
	
	list.forEach(System.out::println);

	Ordering.natural().reverse().thenComparing((a, b) -> a.toString().compareTo(b.toString()));
	
}

Optional

public static void main(String[] args) {
    
    
		
	final TestOptional obj = new TestOptional();
	
	// Optional
	Optional<TestOptional> optional = Optional.of(obj);
	
	// 使用 or 提供为空默认值
	System.out.println(optional.or(new TestOptional()));
	
	// 使用 Optional 做数据转换
	optional.transform(c -> c.equals(obj)).get();
}

Splitter

public static void main(String[] args) {
    
    
	// Splitter
	String str = " foo, ,bar, quux,";
	
	// 字符串 Splitter
	Iterable<String> result = Splitter.on(',')
			// 移除字符串前后空格
			.trimResults()
			// 移除为空或者为 null
			.omitEmptyStrings()
			.split(str);
	
	result.forEach(System.out::println);
	
	// 字符串 Joiner
	System.out.println(Joiner.on(", ")
			// 跳过为 null 的元素
			.skipNulls()
			.join(result));
}

Stopwatch

public static void main(String[] args) {
    
    
		
	// stopWatch 相对时间, System.nanoTime() 的替代
	Stopwatch stopWatch = Stopwatch.createStarted();
	
	try {
    
    
		Thread.sleep(1000);
	} catch (InterruptedException e) {
    
    
		e.printStackTrace();
	}
	
	// 获得 stopWatch start() 以来经过的时间
	Duration time1 = stopWatch.elapsed();
	
	System.out.println(time1.toMillis());
	
	// 停止 stopWatch
	stopWatch.stop();
}

guava.collection

Hash

public static void main(String[] args) {
    
    
		
	TestHash obj = new TestHash();
	obj.setAge(18);
	obj.setId(100000000l);
	
	// 指定对象分解为原生字段值
	Funnel<Pet> petFunnel = new Funnel<Pet>() {
    
    
		
		private static final long serialVersionUID = -5516438913441382127L;

		@Override
		public void funnel(Pet from, PrimitiveSink into) {
    
    
			into.putString(from.getName(), Charset.defaultCharset());
		}
	};
	
	// 为了减少 hash 冲突,解决 JDK 自带 hashCode() 长度限制为 32 位,无插件机制等问题
	HashCode hash = 
			// 支持算法切换 md5,sha1, sha256, sha512 
			// Hashing.goodFastHash(32) 让 guava 帮你选择 hash 算法
			Hashing.murmur3_128().newHasher()
			// 加入顺序不同,得到的 hash 值不同
			.putInt(obj.getAge())
			.putLong(obj.getId())
			.putObject(obj.getPet(), petFunnel)
			.hash();
	
	System.out.println(hash);
	System.out.println(hash.asInt());
	System.out.println(hash.asLong());
}

BloomFilter

public static void main(String[] args) {
    
    
		
	// 布隆过滤器
	//
	// 牺牲了正确率和时间以节省空间
	// public boolean mightContain(T);
	// true: 该元素不一定在集合中
	// false: 该元素一定不在集合中
	//
	
	// 预计大小 = 500,预计 99.99 使用率
	BloomFilter<Integer> filter = BloomFilter.create(
			  Funnels.integerFunnel(),
			  500,
			  0.01);
	
	System.out.println(filter.put(50));
	System.out.println(filter.put(150));
	System.out.println(filter.put(250));
	System.out.println(filter.put(350));
	System.out.println(filter.put(450));
	System.out.println(filter.put(550));
	System.out.println(filter.put(650));
	System.out.println(filter.put(750));
	System.out.println(filter.put(850));
	System.out.println(filter.put(950));
	System.out.println(filter.mightContain(150));
	System.out.println(filter.mightContain(250));
	System.out.println(filter.mightContain(25));

	
}

ImmutableCollections

public static void main(String[] args) {
    
    
		
	// ImmutableCollection 类似 JDK 的线程安全的不可变集合
	ImmutableList<String> list = ImmutableList.of("a", "b", "c", "d");
	
	ImmutableList<String> list2 = ImmutableList.of("a", "b", "c", "d", "e");
	
	// 使用 copyOf 修改 ImmutableList
	list = ImmutableList.copyOf(list2);
	
	list.forEach(System.out::println);
	
	// 初始化示栗
	ImmutableSet<String> set = ImmutableSet.<String>builder()
			.addAll(list2)
			.add("f")
			.build();
	
	set.forEach(System.out::println);
}

Multimap

public static void main(String[] args) {
    
    
		
	// Multimap 的使用 Multimap 类似于 Java 的 Map<String, Collection<String>>
	Multimap<String, String> map = HashMultimap.create();
	
	map.put("a", "1");
	map.put("a", "1");
	map.put("a", "2");
	map.put("b", "2");
	
	Collection<String> c = map.get("c");
	
	// 输出为 0
	System.out.println(c.size());
	
	// 输出为 true
	System.out.println(map.containsKey("a"));
	
	// size = 3
	System.out.println("size=" + map.size());
	
	// ListMultimap 类似于 Java 的 Map<String, List<String>>
	ListMultimap<String, String> listMultimap = ArrayListMultimap.create();
	
	listMultimap.put("a", "1");
	listMultimap.put("a", "1");
	listMultimap.put("b", "1");
	listMultimap.put("b", "2");
	
	// 输出 [1, 2]
	System.out.println(listMultimap.get("b"));

	// 输出 {a=[1, 1], b=[1, 2]}
	System.out.println(listMultimap);
	
	// k,v 都不能重复,否则会报错
	BiMap<String, String> biMap = HashBiMap.create();
	biMap.put("a", "1");
	biMap.put("b", "2");
	BiMap<String,String> biMap2 = biMap.inverse();
	
	// 输出 1:a \n 2:b
	biMap2.forEach((k, v) -> System.out.println(k + ":" + v));
}

Multiset

public static void main(String[] args) {
    
    
		
	// 类似于 HashMap<String, Integer>()
	Multiset<String> multiset = HashMultiset.create();
	
	multiset.add("aa");
	multiset.add("aa");
	multiset.add("bb");
	
	// 输出 2
	System.out.println(multiset.count("aa"));
	
	// 输出 3
	System.out.println(multiset.size());
	
	// 输出 aa \n bb \n cc \n
	Iterator<String> iter = multiset.iterator();
	while (iter.hasNext()) {
    
    
		String str = iter.next();
		System.out.println(str);
	}
	System.out.println("-------------------");
	
	// 输出 aa \n bb \n
	for (String str : multiset.elementSet()) {
    
    
		System.out.println(str);
	}
}

Table

public static void main(String[] args) {
    
    
		
	// table 类似于数据库的 table 结果结构 R = 主键 ,C = 列名,V = 值
	Table<Integer, Character, String> table = ArrayTable.create(
			// 主键序列 1, 2, 3
			ImmutableList.of(1, 2, 3),
			// 列定义序列:'A', 'B', 'C'
			ImmutableList.of('A', 'B', 'C'));
	
	// 相当于 Map<R, Map<C, V>>
	
	table.put(1, 'A', "1A");
	table.put(1, 'B', "1B");
	table.put(2, 'A', "2A");
	
	// 输出为 2A
	System.out.println(table.get(2, 'A'));
	
	// 输出为 1 \n 2 \n 3 \n
	table.rowKeySet().forEach(System.out::println);
	
	/*
	 * 1:A:1A
	 * 1:B:1B
	 * 1:C:null
	 * 2:A:2A
	 * 2:B:null
	 * 2:C:null
	 * 3:A:null
	 * 3:B:null
	 * 3:C:null 
	 */
	table.cellSet().forEach(cell -> System.out.println(cell.getRowKey() + ":" + cell.getColumnKey() + ":" + cell.getValue()));
	
	HashBasedTable<Integer, Character, String> hashTable = HashBasedTable.create();
	
	// 输出为 {}
	System.out.println(hashTable);
	
}

guava.func 函数式编程

Predicate

public static void main(String[] args) {
    
    
		
	// guava 函数式编程,谓词函数,返回值为 布尔 类型
	Predicate<TestFPredicate> fp = new Predicate<TestFPredicate>() {
    
    
		
		@Override
		public boolean apply(TestFPredicate input) {
    
    
			return true;
		}
	};
	
	// Predicate 谓词函数使用示栗
	List<TestFPredicate> list = Lists.newArrayList(new TestFPredicate(), new TestFPredicate());
	
	// FluentIterable 类似于 stream
	ImmutableList<String> resultList = FluentIterable
		.from(list)
		.filter(fp)
		.transform(Functions.toStringFunction())
		.limit(10)
		.toList();
	
	resultList.forEach(System.out::println);

	// FluentIterable 可以是哦那个 cycle 循环
	boolean allMatch = FluentIterable.from(list)
		.skip(0)
		.cycle()
		.limit(10)
		.allMatch(a -> !a.equals(new TestFPredicate()));
	
	System.out.println(allMatch);
	
}

Functional

public static void main(String[] args) {
    
    
		
	List<String> strings = Lists.newArrayList("aa", "AA", "cc", "BB");

	// 函数式编程,获得字符串的长度
	Function<String, Integer> lengthFunction = new Function<String, Integer>() {
    
    

		@Override
		public Integer apply(String input) {
    
    
			return input.length();
		}
	};
	
	// 函数式编程,谓词函数,判断一个字符串是否只包含大写
	Predicate<String> allCaps = new Predicate<String>() {
    
    
		
		@SuppressWarnings("deprecation")
		@Override
		public boolean apply(String input) {
    
    
			return CharMatcher.javaUpperCase().matchesAllOf(input);
		}
	};
	
	// lengthFunction 和 allCaps 使用示栗 Iterables.transform
	Multiset<Integer> lengths = HashMultiset.create(
			Iterables.transform(Iterables.filter(strings, allCaps), lengthFunction)
	);
	
	lengths.forEach(System.out::println);
}

guava.cache

Cache

public static void main(String[] args) {
    
    
	// 
	CacheLoader<String, String> loader = new CacheLoader<String, String>() {
    
    

		@Override
		public String load(String key) throws Exception {
    
    
			if ("a".equals(key)) {
    
    
				return "1";
			}
			if ("b".equals(key)) {
    
    
				return "2";
			}
			return "3";
		}
	};
	
	// 初始化缓存
	LoadingCache<String, String> cache = CacheBuilder.newBuilder()
			.maximumSize(2000)
			.expireAfterAccess(10, TimeUnit.SECONDS)
			.removalListener(new RemovalListener<String, String>() {
    
    

				@Override
				public void onRemoval(RemovalNotification<String, String> notification) {
    
    
					System.out.println("removing..." + notification.getKey());
				}
			})
			.build(loader);
	
	try {
    
    
		String value = cache.get("a");
		System.out.println(value);
	} catch (ExecutionException e) {
    
    
		e.printStackTrace();
	}
}
public static void main(String[] args) {
    
    
		
	// Guava 建议使用 LoadingCache 而不是 Cache
	CacheLoader<String, String> loader = new CacheLoader<String, String>(){
    
    

		@Override
		public String load(String key) throws Exception {
    
    
			return key.toUpperCase();
		}};
	LoadingCache<String, String> cache = CacheBuilder.newBuilder().build(loader);
	
	cache.put("a", "b");
	
	System.out.println("size = " + cache.size());
	System.out.println("a = " + cache.getUnchecked("a"));
	System.out.println("b = " + cache.getUnchecked("b"));
}
public static void main(String[] args) {
    
    
		
	CacheLoader<String, String> loader = new CacheLoader<String, String>(){
    
    

		@Override
		public String load(String key) throws Exception {
    
    
			return key.toUpperCase();
		}};
	LoadingCache<String, String> cache = CacheBuilder.newBuilder()
			// 允许垃圾收集器回收
			.softValues()
			.build(loader);
	
	String spec = "maximumSize=2000,expireAfterWrite=2m";
	LoadingCache<String, String> cache2 = CacheBuilder.from(spec)
			.build(loader);
	
	cache.put("a", "b");
	cache2.put("a", "b");
	
	System.out.println("size = " + cache.size());
	System.out.println("a = " + cache.getUnchecked("a"));
	System.out.println("b = " + cache.getUnchecked("b"));
}
public static void main(String[] args) {
    
    
		
	CacheLoader<String, String> loader = new CacheLoader<String, String>(){
    
    

		@Override
		public String load(String key) throws Exception {
    
    
			return key.toUpperCase();
		}};
	LoadingCache<String, String> cache = CacheBuilder.newBuilder()
			// 当key 被 JVM GC 回收时,自动移除该 key
			.weakKeys()
			.build(loader);
	
	cache.put("a", "b");
	
	System.out.println("size = " + cache.size());
	System.out.println("a = " + cache.getUnchecked("a"));
	System.out.println("new String(a) = " + cache.getUnchecked(new String("a")));
	System.out.println("b = " + cache.getUnchecked("b"));
}
public static void main(String[] args) {
    
    
		
	// CacheLoader,相当于缓存的 init 方法,用于从持久化存储中读取缓存内容
	CacheLoader<String, String> loader = new CacheLoader<String, String>(){
    
    

		// 读取单个 key
		@Override
		public String load(String key) throws Exception {
    
    
			return key.toUpperCase();
		}

		// 与 cache.getAll 相对应的,loadAll,批量读取,提升效率
		@Override
		public Map<String, String> loadAll(Iterable<? extends String> keys) throws Exception {
    
    
			Map<String, String> result = Maps.newHashMap();
			System.out.println("------------------------getAll 会批量读取------------------------");
			for (String key : keys) {
    
    
				
				result.put(key, key.toUpperCase());
			}
			return result;
		}
		
		
	};
	LoadingCache<String, String> cache = CacheBuilder.newBuilder().build(loader);
	
	cache.put("a", "b");
	
	// 输出 a=b
	cache.getAllPresent(Iterables.concat(Lists.newArrayList("a", "b", "c"))).forEach((k, v) -> System.out.println(k + "=" + v));
	
	System.out.println("=========================================================");
	
	try {
    
    
		/**
		 * 输出
		 * ------------------------getAll 会批量读取------------------------
		 * a=b
		 * b=B
		 * c=C
		 */
		cache.getAll(Iterables.concat(Lists.newArrayList("a", "b", "c"))).forEach((k, v) -> System.out.println(k + "=" + v));
	} catch (ExecutionException e) {
    
    
		e.printStackTrace();
	};
	
	// 输出 size = 3
	System.out.println("size = " + cache.size());
	// 输出 a = b
	System.out.println("a = " + cache.getUnchecked("a"));
	// 输出 b = B
	System.out.println("b = " + cache.getUnchecked("b"));
}
public static void main(String[] args) {
    
    
		
	CacheLoader<String, String> loader = new CacheLoader<String, String>(){
    
    

		@Override
		public String load(String key) throws Exception {
    
    
			return loadFromeDisk(key);
		}};
	LoadingCache<String, String> cache = CacheBuilder.newBuilder().build(loader);
	
	cache.put("a", "b");
	
	System.out.println("size = " + cache.size());
	// CheckedException
	System.out.println("a = " + cache.getUnchecked("a"));
	System.out.println("b = " + cache.getUnchecked("b"));
}

protected static String loadFromeDisk(String key) throws ExecutionException {
    
    
	throw new ExecutionException("not exists", new Throwable("not exists2"));
}
public static void main(String[] args) {
    
    
		
	CacheLoader<String, String> loader = new CacheLoader<String, String>(){
    
    

		@Override
		public String load(String key) throws Exception {
    
    
			return key.toUpperCase();
		}};
	LoadingCache<String, String> cache = CacheBuilder.newBuilder()
			.removalListener(new RemovalListener<String, String>() {
    
    

				@Override
				public void onRemoval(RemovalNotification<String, String> notification) {
    
    
					System.out.println(notification.getKey() + ":" + notification.getValue());
				}
			})
			.build(loader);
	
	cache.put("a", "1");
	cache.put("b", "2");
	cache.put("c", "3");
	cache.put("d", "4");
	
	/*
	 * d:4
	 * b:2
	 * c:3
	 * a:1
	 */
	cache.invalidateAll();
	
	// 设置 maximumSize=0,标识禁用该缓存
	cache = CacheBuilder.from("maximumSize=0").build(loader);
	
	cache.put("a", "1");
	cache.put("b", "2");
	cache.put("c", "3");
	
	// 输出为 A
	System.out.println(cache.getUnchecked("a"));
}
public static void main(String[] args) {
    
    
		
	CacheLoader<String, String> loader = new CacheLoader<String, String>(){
    
    

		@Override
		public String load(String key) throws Exception {
    
    
			return key.toUpperCase();
		}};
	LoadingCache<String, String> cache = CacheBuilder.newBuilder()
			// 最大缓存数
			.maximumSize(2000)
			.build(loader);
	
	LoadingCache<String, String> cache2 = CacheBuilder.newBuilder()
			// 使用 weight 替代 最大缓存数
			.weigher((s1, s2) -> s2.toString().length())
			.maximumWeight(20000)
			.build(loader);
	
	LoadingCache<String, String> cache3 = CacheBuilder.newBuilder()
			// 记录缓存命中率等统计信息
			.recordStats()
			.build(loader);
	
	LoadingCache<String, String> cache4 = CacheBuilder.newBuilder()
			// 2 秒不使用
			.expireAfterAccess(2, TimeUnit.SECONDS)
			.build(loader);
	
	LoadingCache<String, String> cache5 = CacheBuilder.newBuilder()
			// 写入 2 秒后
			.expireAfterWrite(2, TimeUnit.SECONDS)
			.build(loader);
	
	LoadingCache<String, String> cache6 = CacheBuilder.newBuilder()
			// 写入 2 秒后,自动获得新数据
			.refreshAfterWrite(2, TimeUnit.SECONDS)
			.build(loader);
	
	CacheStats stats = cache3.stats();
	
	// 命中率,输出 1.0
	System.out.println(stats.hitRate());
	
	cache.put("a", "b");
	cache2.put("a", "b");
	cache4.put("a", "b");
	cache5.put("a", "b");
	cache6.put("a", "b");
	
	// 输出 size = 1
	System.out.println("size = " + cache.size());
	// 输出 a = b
	System.out.println("a = " + cache.getUnchecked("a"));
	// 输出 b = B
	System.out.println("b = " + cache.getUnchecked("b"));
}
public static void main(String[] args) throws ExecutionException {
    
    
		
	CacheLoader<String, String> loader = new CacheLoader<String, String>(){
    
    

		@Override
		public String load(String key) throws Exception {
    
    
			return key.toUpperCase();
		}};
	LoadingCache<String, String> cache = CacheBuilder.newBuilder().build(loader);
	
	System.out.println("size = " + cache.size());
	String key = "1";
	// 使用 Callable 指定获得值的方法
	String v = cache.get(key, new Callable<String>() {
    
    

		@Override
		public String call() throws Exception {
    
    
			return key.toLowerCase();
		}
	});
	
	System.out.println("v=" + v);
}
public static void main(String[] args) {
    
    
		
	CacheLoader<String, String> loader = new CacheLoader<String, String>(){
    
    

		@Override
		public String load(String key) throws Exception {
    
    
			return key.toUpperCase();
		}};
	LoadingCache<String, String> cache = CacheBuilder.newBuilder()
			.maximumSize(2000)
			.removalListener(new RemovalListener<String, String>() {
    
    

				@Override
				public void onRemoval(RemovalNotification<String, String> notification) {
    
    
					// 当数量达到 2000 时,可以通过 RemovalListener 收到通知
					if (notification.wasEvicted()) {
    
    
					}
				}
			})
			.build(loader);
	
	LoadingCache<String, String> cache2 = CacheBuilder.newBuilder()
			.maximumSize(2000)
			// 异步的移除监听
			.removalListener(RemovalListeners.asynchronous(new RemovalListener<String, String>() {
    
    

				@Override
				public void onRemoval(RemovalNotification<String, String> notification) {
    
    
					// 当数量达到 2000 时,可以通过 RemovalListener 收到通知
					if (notification.wasEvicted()) {
    
    
					}
				}
			}, new ScheduledThreadPoolExecutor(2)))
			.build(loader);
	
	cache.put("a", "b");
	cache2.put("a", "b");
	
	System.out.println("size = " + cache.size());
	System.out.println("a = " + cache.getUnchecked("a"));
	System.out.println("b = " + cache.getUnchecked("b"));
}

猜你喜欢

转载自blog.csdn.net/u012296499/article/details/125043822
今日推荐