《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!
/**
* The maximum capacity, used if a higher value is implicitly specified
* by either of the constructors with arguments.
* MUST be a power of two <= 1<<30.
*/
static final int MAXIMUM_CAPACITY = 1 << 30;
这两个变量来自java.util.HashMap
源码,你可能也非常好奇为什么不直接写成数字,要弄一个移位骚操作?
这是在告诉开发者,HashMap 的容量大小必须是 2 的幂次,不然会造成空间浪费。另外,HashMap 容量为什么总是为 2 的次幂?这篇推荐看下。
4、复制变量
transient Collection values;
public Collection values() {
Collection vs = values;
if (vs == null) {
vs = new Values();
values = vs;
}
return vs;
}
以上同样来自java.util.HashMap
的源码,为什么不直接用values
:
transient Collection values;
public Collection values() {
if (values == null) {
values = new Values();
}
return values;
}
而要重新定义一个vs
来绕一个弯呢?
这样写不是更简单么?
JDK里面大量这样的写法,这是为什么呢?!
那是因为操作局部变量要比读取全局变量要更快,另外,我个人觉得还有一个好处,再申明一下局部变量,可以很明显的看到这个变量的类型,而不要翻到上面或者用鼠标移上去来看变量类型。
另外提一点,上面的复制变量再操作的方式让我想到了CopyOnWriteArrayList,这也是让当前变量不被其他线程改变保证当前线程变量一致性的一种方式。
写 JDK 源码的都是大神啊,透过源码,我们能学到太多东西!
5、泛型
来看一段泛型的灵活运用:
public Observable compose(Transformer<? super T, ? extends R> transformer) {
return ((Transformer<T, R>) transformer).call(this);
}
这个泛型方法写得牛 X 吧,泛型 T、R、通配符(?)、上边界(extends)和下边界(super)都用上了!
常用的泛型含义:
-
T - Type(类型)
-
R - Result(结果)
-
K - Key(键)
-
V - Value(值)
-
E - Element (元素)
-
N - Number(数字)
-
? - 不确定类型
上面的泛型我们应该有常见到吧,边界和通配符不懂的可以看下这篇文章吧:困扰我多年的Java泛型 和 ,终于搞清楚了。
泛型要学会用,学好能装B。
6、Lambda
Lambda 表达式这是 Java 8 里面添加的新特性,用来简化匿名内部类以及结合函数式接口编程用的。
如下面创建线程的示例:
// 1
Runnable runnable = () -> System.out.println(“javastack.cn”);
new Thread(runnable).start();
// 2
new Thread(() -> System.out.println(“javastack.cn”)).start();
// 3
new Thread(() -> clean()).start();
三个不同的写法,我们再也不用写new Runnable()
的一大堆 的匿名内部类了,是不是很清爽了!
如果你还不会用Lambda
表达式,那真的 OUT 了,可以关注微信公众号:Java技术栈,在后台回复:新特性,我已经写了一大堆教程了。
下面是一个Lambada
真实案例:
@Bean
public CommandLineRunner commandLineRunner(NettyServer nettyServer) {
return (args) -> {
Thread thread = new Thread(() -> nettyServer.start());
thread.setDaemon(true);
thread.start();
};
}
上述示例省去了 newCommandLineRunner
的匿名内部类的过程。
7、函数式编程
上面有提到函数式编程,这是 Java 8 里面添加的新特性,我之前在公众号里已经写过很多 Java 新特性的教程,这也不是新玩法了,已经被玩烂了。
来看一个真实的案例,来自 Spring Boot 的邮件发送自动配置:
private void applyProperties(JavaMailSenderImpl sender) {
PropertyMapper map = PropertyMapper.get();
map.from(this.properties::getHost).to(sender::setHost);
map.from(this.properties::getPort).whenNonNull().to(sender::setPort);
map.from(this.properties::getUsername).to(sender::setUsername);
map.from(this.properties::getPassword).to(sender::setPassword);
map.from(this.properties::getProtocol).to(sender::setProtocol);
map.from(this.properties::getDefaultEncoding).whenNonNull().as(Charset::name)
.to(sender::setDefaultEncoding);
map.from(this.properties::getProperties).whenNot(Map::isEmpty)
.as(this::asProperties).to(sender::setJavaMailProperties);
}
第一次看到这段代码的时候,我内心是拒绝的,很难理解。
上面的 from 和 to 方法分别用到了Supplier
和Consumer
函数式接口,还用到了双冒号::
结合使用,讳莫如深,还能结合Lambda
表达式使用。
函数式编程很厉害,虽然会用,但到现在我也觉得很高深,可读性和可理解性太差了,但是,装 X 必学、必用。
8、流关闭
MyInputStream mis = new MyInputStream();
MyOutputStream mos = new MyOutputStream();
try (mis; mos) {
mis.read(“1.9”);
mos.write(“1.9”);
} catch (Exception e) {
e.printStackTrace();
}
没错,你看到的这个关闭流骚操作是 Java 9 的新语法糖,较 Java 7 又简化了try-with-resources
用法,装 X 的姿势越来越多了。
关于try-with-resources
的详细介绍及演进过程,大家可以阅读这篇文章:JDK9新特性实战:简化流关闭新姿势,或者可以关注微信公众号:Java技术栈,在后台回复 “新特性” 获取这篇文章完整版。
不知道的可能上来就一顿骂了,你流关闭动作在哪,为什么不关闭流,多跟着栈长学点新知识吧,哈哈。
9、类型推断
关注Java技术栈公众号的老读者应该都看过,Java 10 刚出来的时候,我写过两篇新特性文章:
-
Java 10的10个新特性,将彻底改变你写代码的方式!
-
Java 10 实战第 1 篇:局部变量类型推断
来,我再挑两个示例来欣赏下:
示例1:
var javastack = “javastack”;
示例2:
private static void testLoop() {
for (var i = 0; i < 3; i++) {
for (var m = 10; m < 15; m++) {
System.out.println(i + m);
}
}
}
最后
文章中涉及到的知识点我都已经整理成了资料,录制了视频供大家下载学习,诚意满满,希望可以帮助在这个行业发展的朋友,在论坛博客等地方少花些时间找资料,把有限的时间,真正花在学习上,所以我把这些资料,分享出来。相信对于已经工作和遇到技术瓶颈的朋友们,在这份资料中一定都有你需要的内容。
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!