java的三大特性有哪些,java八大特性
在本文中,您将了解到一些您可能没有听说过的有用的Java特性。以上是我个人使用的或者从其他文章中学到的一些特性,侧重于API而非语言本身。
拖延是众所周知的。Java中可以使用的集合类型有很多种,但是你听说过DelayQueue吗?它是一种特定类型的集合,允许我们根据延迟时间对数据进行排序。这是一个非常有趣的类,它实现了BlockingQueue接口,该接口只能在数据过期时从队列中取出。
作为使用它的第一步,您的类需要在延迟接口中实现getDelay方法。当然不一定要声明类,也可以用Record。
这是Java14的一个新特性。
公共记录延迟事件(长开始时间,字符串消息){
公共long getDelay(时间单位单位){
long diff=start time-system . current time millis();
return unit.convert(diff,TimeUnit。毫秒);
}
公共int compareTo(Delayed o){
return(int)(this . start time-((DelayedEvent)o)。start time);
}
}假设我们需要一个延迟10s取出的数据。我们只需要放入一个比当前时间长10秒的任务。
final delay queue delaydevent delay queue=new delay queue();
final long time first=system . current time millis()10000;
delay queue . offer(new DelayedEvent(time first, 1 ));
log . info( Done );
log.info(delayQueue.take()。msg());最终输出如下:
时间格式的日期特性可能对大多数人没什么用,但说实话,我个人非常喜欢;反正Java 8在时间API上改进了很多。也许你不需要这个版本的任何其他扩展库。
你能想到吗?从Java 16开始,你甚至可以使用标准库来表示一天的日期,比如“上午”“下午”,这是一种新的格式语句b。
字符串s=DateTimeFormatter。ofPattern(B )。format(local datetime . now());
system . out . println(s);以下是我的输出,具体和你现在的时间有关。
你可能想知道为什么叫“b”。真的好像不太直观。下表或许能解答你的疑惑:
Stamped Lock,在我看来是Java中最有趣的包之一,同时也很少被开发人员掌握,尤其是长期使用web开发框架的开发人员。
有多少人用过Lock?与synchronized相比,这是一种更加灵活的线程同步机制。
从Java8开始,您可以使用一个新的锁:StampedLock。StampedLock,可以代替读写锁。
现在假设有两个线程,一个更新金额,另一个读取余额;更新余额的线程首先需要读取金额,然后在多线程的情况下需要某种同步机制(否则更新数据时会出错)。第二个线程以乐观锁定的方式读取余额。
StampedLock lock=new StampedLock();
余额b=新余额(10000);
可运行w=() - {
long stamp=lock . write lock();
b . set amount(b . getamount()1000);
system . out . println( Write: b . getamount());
lock.unlockWrite(戳);
};
Runnable r=() - {
long stamp=lock . trypositicread();
如果(!lock.validate(stamp)) {
stamp=lock . read lock();
尝试{
system . out . println( Read: b . getamount());
}最后{
lock . unlock read(stamp);
}
}否则{
System.out.println(乐观读取失败);
}
};现在更新和读取都是用50个线程测试,最后的余额会等于60000。
ExecutorService executor=executors . newfixedthreadpool(10);
for(int I=0;i 50i ) {
执行者.提交(w);
executor . submit(r);
}并发累加器锁不是并行包中唯一有趣的特性,并发累加器同样有趣;它可以根据我们提供的功能更新数据;在多线程更新数据的场景下,LongAccumulator是比AtomicLong更好的选择。
现在让我们看看如何使用它。我们需要两个参数进行初始化;第一个是用于累积计算的函数,通常是sum函数,第二个参数是累积计算的初始值。
接下来,让我们创建一个LongAccumulator,初始值为10000。最后的结果是什么?其实结果和上面一样,都是6万,只是这次没有用锁。
LongAccumulator余额=新的LongAccumulator(Long:sum,10000 l);
runnable w=()-balance . accumulate(1000 l);
ExecutorService executor=executors . newfixedthreadpool(50);
for(int I=0;i 50i ) {
执行者.提交(w);
}
executor.shutdown()。
if(executor . await termination(1000 l,时间单位。毫秒))
system . out . println( Balance: Balance . get());
assert balance . get()==60000 l;数组的二分搜索法假设我们想要在一个排序列表中插入一个新元素。我们可以使用Arrays.binarySearch()函数。当这个键存在时,它将返回该键所在的索引。如果不存在,它将返回插入位置-(插入点)-1。
BinarySearch是Java中一种非常简单有效的查询方法。
在下面的示例中,您可以通过反转返回的结果来到达索引位置。
int[] t=new int[] {1,2,4,5 };
int x=Arrays.binarySearch(t,3);
assert ~ x==2;负数的二进制数用正数的补数表示,数的逆1等于补数,所以这里的直接求逆等于Arrays.binarySearch()不存在时的返回值。
如果你需要对一个二进制数组进行操作,你会怎么做?使用布尔[]布尔数组?
还有一种更高效更节省内存的方式,那就是BitSet。它允许我们存储和操作位数组,与boolean[]相比可以节省8倍的内存;您也可以使用逻辑运算,例如and/or/xor。
假设我们现在有两个位数组,我们需要对它们进行异或运算;我们需要创建两个位集实例,然后调用xor函数。
bit set bs1=new bit set();
bs1 . set(0);
bs1 . set(2);
bs1 . set(4);
system . out . println( bs1: bs1 );
bit set bs2=new bit set();
bs2 . set(1);
bs2 . set(2);
bs2 . set(3);
system . out . println( bs2: bs2 );
bs2 . xor(bs1);
system . out . println( xor: bs2 );最终输出结果如下:
版权归作者所有:原创作品来自博主crossoverJie,转载授权请联系作者,否则将追究法律责任。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。