Joiner详细介绍以及和Java8Collector对比
Joiner
@Test
public void testJoiner(){
// 字符串处理Joiner
final List list = Arrays.asList("a","b","c",null);
// System.out.println(Joiner.on("#").join(list)); //NullPointerException
System.out.println(Joiner.on("#").useForNull("default").join(list)); //a#b#c#default
System.out.println(Joiner.on("#").skipNulls().join(list)); //a#b#c
final Map map = ImmutableMap.of("h1","v1","h2","v2");
System.out.println(Joiner.on("#").withKeyValueSeparator("=").join(map)); //h1=v1#h2=v2
}
Joiner.on("#").useForNull("default").appendTo()也可以写到StringBuilder、StringBuffer、FileWriter等里面
JAVA8中的Collectors实现
String collect = list.stream().filter(item -> item != null && !item.isEmpty()).collect(Collectors.joining("#"));
System.out.println(collect);//a#b#c
String collect = list.stream()
.map(item -> item == null || item.isEmpty() ? "default" : item)
.filter(item -> !item.isEmpty())
.collect(Collectors.joining("#")); //a#b#c
System.out.println(collect); //a#b#c#default
Guava Splitter详细介绍
Splitter
@Test
public void testSplit(){
String str = "a#b#c# #e##";
System.out.println(Splitter.on("#").splitToList(str)); //[a, b, c, , e, , ]
System.out.println(Splitter.on("#").omitEmptyStrings().splitToList(str)); //[a, b, c, , e]
System.out.println(Splitter.on("#").trimResults().omitEmptyStrings().splitToList(str)); //[a, b, c, e]
System.out.println(Splitter.fixedLength(4).splitToList(str)); //[a#b#, c# , #e##]
System.out.println(Splitter.on("#").limit(2).splitToList(str)); //[a, b#c# #e##] 两个元素
String str2 = "a1=a;b1=b";
//Map
System.out.println(Splitter.on(";").withKeyValueSeparator("=").split(str2)); //{a1=a, b1=b}
}
还可以支持正则切分
Preconditions&Objects&assert断言介绍
Preconditions
@Test
public void testPreconditions(){
List list = null;
checkNotNullWithMsg(list); //java.lang.NullPointerException: this is null
}
private void checkNotNullWithMsg(List list){
Preconditions.checkNotNull(list,"this is null");
}
Objects
Objects.requireNonNull(null); //java.lang.NullPointerException
...
assert
List list = null;
assert list != null; //java.lang.AssertionError
assert list != null : "this is msg"; //java.lang.AssertionError: this is msg
...
ComparisonChain比较器
@Test
public void testObjects(){
Guava g1 = new Guava("1","2",new Date());
Guava g2 = new Guava("2","2",new Date());
Guava g3 = new Guava("3","2",new Date());
System.out.println(g1.compareTo(g2)); // -1
System.out.println(g3.compareTo(g2)); // 1
}
static class Guava implements Comparable{
private final String factory;
private final String version;
private final Date date;
public Guava(String factory, String version, Date date) {
this.factory = factory;
this.version = version;
this.date = date;
}
@Override
public int compareTo(Guava o) {
return ComparisonChain.start().compare(this.factory,o.factory)
.compare(this.version,o.version)
.compare(this.date,o.date).result();
}
}
Strings&Charsets&CharMatcher介绍
@Test
public void testStrings(){
System.out.println(Strings.emptyToNull("")); //null
System.out.println(Strings.nullToEmpty(null)); //""
System.out.println(Strings.nullToEmpty("h")); //h
System.out.println(Strings.commonPrefix("d1","d2")); //d
System.out.println(Strings.repeat("d1",3)); //d1d1d1
}
@Test
public void testCharsets(){
Charset charset = Charset.forName("UTF-8");
Charset charset2 = Charsets.UTF_8;
}
@Test
public void testCharMatcher(){
System.out.println(CharMatcher.is('A').countIn("Alex A a b")); //2
System.out.println(CharMatcher.breakingWhitespace().collapseFrom("Alex A a b", '*')); //Alex*A*a*b
System.out.println(CharMatcher.javaDigit().or(CharMatcher.whitespace()).removeFrom("Alex A a b 1 231"));//AlexAab
}
函数式接口
Function
Function<传入类型,输出类型>
public class FunctionExample {
public static void main(String[] args) {
//传进去一个词,返回一个这个词的长度
Function getLength = new Function() {
@Override
public Integer apply(String input) {
Preconditions.checkNotNull(input, "check is null");
return input.length();
}
};
Integer testLength = getLength.apply("test");
System.out.println(testLength);
// Functions
}
}
Supplier
提供结果的函数接口.只有返回值,没有输入参数
public class FunctionExample {
public static void main(String[] args) {
//这是一个提供结果的函数接口.
//(1)只有返回值
//(2)没有输入参数
Supplier supplier = new Supplier() {
@Overrider
public String get() {
System.out.println(111);
return "test";
}
};
String s = supplier.get();
System.out.println(s);
//Suppliers
}
}
Predicate
提供test()方法,输出boolean
public class FunctionExample {
public static void main(String[] args) {
Predicate predicate = new Predicate() {
@Override
public boolean apply(String input) {
return Objects.equals("test",input);
}
};
boolean test1 = predicate.equals(predicate); // true
boolean test2 = predicate.test("test2"); // false
boolean test3 = predicate.equals("test"); //false
boolean test4 = predicate.test("test");//true
//Predicates...
}
}
StopWatch
类似于 结束时间 - 开始时间
public class WatchExample {
public static void main(String[] args) throws Exception {
// 创建自动start的计时器
Stopwatch watch = Stopwatch.createStarted();
Thread.sleep(1000L);
long time = watch.elapsed(TimeUnit.MILLISECONDS);
// 结果1003
System.out.println("代码执行时长:" + time);
// 创建非自动start的计时器
// 累计了start到stop的时间
Stopwatch watch1 = Stopwatch.createUnstarted();
Thread.sleep(1000L);
watch1.start();
Thread.sleep(1000L);
watch1.stop();
watch1.start();
Thread.sleep(500L);
time = watch1.elapsed(TimeUnit.MILLISECONDS);
// 结果1500
System.out.println("代码执行时长:" + time);
Stopwatch watch2 = Stopwatch.createUnstarted();
watch2.start();
Thread.sleep(1000L);
time = watch2.elapsed(TimeUnit.MILLISECONDS);
// 结果1000
System.out.println("代码执行时长:" + time);
}
}
IO Files
对InputStream,OutputStream等的一些封装,提供了很多API,
官方文档:https://guava.dev/releases/27.0.1-jre/api/docs/com/google/common/io/Files.html
CharSource和CharSink
ByteSource和ByteSink
Closer使用
try...catch...finally的优化
Base*coding
EventBus
EventBus是Guava的事件处理机制,是设计模式中的观察者模式(生产/消费者编程模型)的优雅实现,在应用中可以处理一些异步任务。对于事件监听和发布订阅模式,EventBus是一个非常优雅和简单解决方案,我们不用创建复杂的类和接口层次结构。
EventBus实际上是一个消息队列,Event Source发送一个消息到EventBus,然后再由EventBus将消息推送到所监听的Listener。
https://blog.csdn.net/wangdong5678999/article/details/80561198
Monitor
Monitor是一个支持任意布尔条件的同步的抽象,Monitor类是作为ReentrantLock的一个替代,代码中使用Monitor比使用ReentrantLock更不易出错,可读性也更强,并且也没有显著的性能损失,使用Monitor甚至有潜在的性能得到优化
https://www.cnblogs.com/hupengcool/p/4250903.html
RateLimiter
常用的限流算法有漏桶算法和令牌桶算法
https://www.jianshu.com/p/8f548e469bbe
https://blog.csdn.net/fanrenxiang/article/details/80949079
简单Demo:
public class RateLimiterExample {
// 一秒钟允许多少个操作
private final static RateLimiter limiter = RateLimiter.create(0.5); // 一秒钟允许0.5个操作,2秒钟1次操作
public static void main(String[] args) throws Exception {
ExecutorService service = Executors.newFixedThreadPool(10);
IntStream.range(0,10).forEach( i -> {
service.submit(RateLimiterExample::testLimiter);
});
}
private static void testLimiter(){
System.out.println(Thread.currentThread() + "waiting " + limiter.acquire());
}
}
---大约两秒打印一次
Thread[pool-1-thread-1,5,main]waiting 0.0
Thread[pool-1-thread-2,5,main]waiting 1.874738
Thread[pool-1-thread-3,5,main]waiting 3.872905
Thread[pool-1-thread-5,5,main]waiting 5.871703
Thread[pool-1-thread-4,5,main]waiting 7.871677
Thread[pool-1-thread-6,5,main]waiting 9.871123
Thread[pool-1-thread-7,5,main]waiting 11.870788
Thread[pool-1-thread-8,5,main]waiting 13.870773
Thread[pool-1-thread-9,5,main]waiting 15.870581
Thread[pool-1-thread-10,5,main]waiting 17.869938
限流桶实现
public class Bucket
{
private final ConcurrentLinkedQueue container = new ConcurrentLinkedQueue<>();
private final static int BUCKET_LIMIT = 1000;
private final RateLimiter limiter = RateLimiter.create(10);
private final Monitor offerMonitor = new Monitor();
private final Monitor pollMonitor = new Monitor();
public void submit(Integer data)
{
if (offerMonitor.enterIf(offerMonitor.newGuard(() -> container.size() < BUCKET_LIMIT)))
{
try
{
container.offer(data);
System.out.println(currentThread() + " submit data " + data + ",current size:" + container.size());
} finally
{
offerMonitor.leave();
}
} else
{
throw new IllegalStateException("The bucket is full.");
}
}
public void takeThenConsume(Consumer consumer)
{
if (pollMonitor.enterIf(pollMonitor.newGuard(() -> !container.isEmpty())))
{
try
{
System.out.println(currentThread() + " waiting " + limiter.acquire());
consumer.accept(container.poll());
} finally
{
pollMonitor.leave();
}
}
}
}
public class BucketTest
{
public static void main(String[] args)
{
final Bucket bucket = new Bucket();
final AtomicInteger DATA_CREATOR = new AtomicInteger(0);
IntStream.range(0, 5).forEach(i ->
{
new Thread(() ->
{
for (; ; )
{
int data = DATA_CREATOR.getAndIncrement();
bucket.submit(data);
try
{
TimeUnit.MILLISECONDS.sleep(200L);
} catch (Exception e)
{
if (e instanceof IllegalStateException)
{
System.out.println(e.getMessage());
}
}
} //25
//10
//5:2
}).start();
});
IntStream.range(0, 5)
.forEach(i -> new Thread(() ->
{
for (; ; )
{
bucket.takeThenConsume(x -> System.out.println(currentThread() + " W " + x));
}
}).start()
);
}
}
令牌桶实现
public class TokenBucket
{
private AtomicInteger phoneNumbers = new AtomicInteger(0);
private final static int LIMIT = 100;
private RateLimiter rateLimiter = RateLimiter.create(10);
private final int saleLimit;
public TokenBucket()
{
this(LIMIT);
}
public TokenBucket(int limit)
{
this.saleLimit = limit;
}
public int buy()
{
Stopwatch started = Stopwatch.createStarted();
boolean success = rateLimiter.tryAcquire(10, TimeUnit.SECONDS);
if (success)
{
if (phoneNumbers.get() >= saleLimit)
{
throw new IllegalStateException("Not any phone can be sale, please wait to next time.");
}
int phoneNo = phoneNumbers.getAndIncrement();
handleOrder();
System.out.println(currentThread() + " user get the Mi phone: " + phoneNo + ",ELT:" + started.stop());
return phoneNo;
} else
{
started.stop();
throw new RuntimeException("Sorry, occur exception when buy phone");
}
}
private void handleOrder()
{
try
{
TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(10));
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
public class TokenBucketExample
{
public static void main(String[] args)
{
final TokenBucket tokenBucket = new TokenBucket();
for (int i = 0; i < 200; i++)
{
new Thread(tokenBucket::buy).start();
}
}
}
ListenableFuture
FutureCallBack
JDK8:CompletableFuture
Cache
Google Guava 快速入门 —— Cache 缓存工具
自定义LRU算法的缓存实现
软引用SoftReference介绍以及简单用法cache
理解StrongReference,SoftReference, WeakReference的区别 SoftReference:当快OOM时才进行回收。 WeakReference:只要调用GC就会被回收。
Cache简单Demo
LoadingCache employeeCache = CacheBuilder.newBuilder()
.maximumSize(100) // 最多可以缓存100条记录
.expireAfterAccess(30, TimeUnit.MINUTES) // 缓存将在访问30分钟后过期
.build(new CacheLoader() {
@Override
public Object load(String key) throws Exception {
// 数据库加载
return getFromDatabase(key);
}
});
第一次调用加载数据库中的数据,第二次调用走缓存
employeeCache.get("key");
employeeCache.getUnchecked("key");
Guava库学习:学习Guava Cache(四)CacheBuilderSpec
Collections
FluentIterable
主要用于过滤集合
Lists
Guava提供了能够推断范型的静态工厂方法
用工厂方法模式,我们可以方便地在初始化时就指定起始元素
通过为工厂方法命名,我们可以提高集合初始化大小的可读性
java代码之美(9)---guava之Lists、Maps
Sets
Maps,BiMap,MultiMap
Table,Range
当我们需要多个索引的数据结构的时候,通常情况下,我们只能用这种丑陋的Map
Range,RangeMap
Guava学习笔记:Guava新集合-Table等
Immutable Collections,Sorted Collections
java代码之美(4)---guava之Immutable(不可变)集合
Google Guava 快速入门
Guava库学习
Java--代码之美