世界正在缓慢但肯定地发生变化。 经过更改后,Java有了JDK 7的全新外观,Java社区期待JDK 8(可能还有JDK 9)所带来的其余改进。
JDK 8的目标目的是填补JDK 7实施中的空白-该实施中剩下的部分难题,应该在2013年底之前为广大读者所用,目的是改善和增强JDK 7中的语言。三个特定方向:
- 生产率
- 性能
- 模块化
因此,从明年开始,java将在所有地方(移动,云,桌面,服务器等)运行,但是会以一种改进的方式运行。 在接下来的内容中,我将简短概述一下2013年的预期-紧接新年决议发布-之后,我将主要关注生产率方面,重点是项目lambda以及它的引入将如何影响我们的编码方式。
生产率
在生产力方面,JDK 8的目标是两个主要领域:–集合–通过引入语言的文字扩展与集合进行交互的一种更便捷的方式–注释–增强了对注释的支持,允许在当前非法的环境(例如基元)中编写注释
性能
向JDK 7添加Fork / Join框架是Java朝多核CPU迈出的第一步。 JDK 8通过为Java提供闭包支持(即lambda表达式),进一步走了这条路。 Java受影响最大的部分可能是Collections部分,其闭包与新添加的接口和功能将Java容器推向了新的高度。 除了要编写的更具可读性和更短的代码之外,通过向集合提供将在内部执行的lambda表达式,平台可以利用多核处理器。
模块化
社区中最令人感兴趣的作品之一是项目拼图:“该项目的目标是为Java SE平台设计和实现标准模块系统,并将该系统应用于平台本身和JDK。” 我使用过去式,是因为对于那些希望摆脱类路径和类加载器的人来说,我们不得不推迟对Java 9的使用,因为那时候项目Jigsaw也被推迟了 。
要更清晰地了解如何重新发布Java Roadmap 2013:
- 2013/01/31 M6功能完成
- 2013/02/21 M7开发人员预览
- 2013/07/05 M8最终版本候选
- 2013/09/09 GA全面上市
除了项目拼图之外,即将出现的另一个重大变化(在此版本中)是对闭包的支持。 通过lambda表达式的帮助,它们将改善JDK的关键点。
Lambdas
入门
首先,首先应该获得启用了lambda的SDK。 在这个方向上,有两种获取方法:
*面向勇敢者的一种:从源头构建
*方便的一种:下载已经编译的SDK版本
最初,我从源头开始构建它,但是由于时间紧缺以及与环境变量有关的警告过多,我选择了惰性方法并采用了现有的JDK。 另一个重要的工具是用于编写代码的文本编辑器。 直到现在为止,它是最早出现的JDK版本,并在一段时间后启用了IDE。 这次有所不同,这也许是由于openjdk提供的SDK的透明性和广泛可用性。 几天前,JetBrain实现了第一个启用Java 8的IDE。 因此IntelliJ IDEA 版本 12是第一个提供对JDK 8支持的IDE,此外还有改进之处吗? 因此,出于测试目的,我在Windows 7,x64计算机上将IntelliJ 12 Community Edition与JDK 8 b68一起使用。 对于那些喜欢Netbeans的人,可以下载具有lambda支持的每晚构建。
调整为适当的心态。
在开始使用新提供的功能来编写经过改进和简洁的代码之前,必须先掌握几个新概念,无论如何我还是需要的。
- 什么是lambda表达式? 查看lambda表达式的最简单方法就像一种方法:“它提供了形式参数的列表,以及根据这些参数表示的主体(表达式或块)。lambda表达式的参数可以声明或推断。 ,当形式参数具有推断的类型时,则这些类型是从lambda表达式所针对的功能接口类型派生的。 从返回值的角度来看,lambda表达式可以是void兼容的-它们不返回任何值或值兼容-如果任何给定的执行路径返回值。
lambda表达式的示例:(a) (int a, int b) -> a + b(b) (int a, int b) -> {if (a > b) {return a;} else if (a == b) {return a * b;} else {return b;}}
- 什么是功能接口? 功能接口是仅包含一个抽象方法的接口,因此表示单个方法协定。 在某些情况下,单个方法可能具有带有覆盖等效签名的多个方法,在这种情况下,所有方法都代表一个方法。 除了通过创建和实例化类来创建接口实例的典型方式之外,还可以通过使用lambda表达式,方法或构造函数引用来创建功能接口实例。
功能接口示例:// custom built functional interface public interface FuncInterface {public void invoke(String s1, String s2); }
JAVA API的功能接口示例:
java.lang.Comparablejava.lang.Runnablejava.util.concurrent.Callablejava.awt.event.ActionListener
因此,让我们看看线程的开始在将来可能会发生什么变化:
旧方法:new Thread(new Runnable() {@Overridepublic void run() {for (int i=0; i< 9; i++) {System.out.println(String.format('Message #%d from inside the thread!', i));}}}).start();
新方法:
new Thread(() -> {for (int i=0; i< 9; i++) {System.out.println(String.format('Message #%d from inside the thread!', i));}}).start();
即使我有一段时间没有编写任何与Java Swing,AWT相关的功能,我也不得不承认lambda将为Swing开发人员的Action侦听器添加新鲜空气:
JButton button = new JButton('Click');// NEW WAY:button.addActionListener( (e) -> {System.out.println('The button was clicked!');});// OLD WAY:button.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println('The button was clicked using old fashion code!');}});
- 谁/什么是SAM? SAM代表“单一抽象方法”,因此可以说一些捷径可以说是SAM ==功能接口。 即使在最初的规范中,也将仅具有一种抽象方法的抽象类也视为SAM类型,一些人还是发现/猜测了原因。
- 方法/构造函数引用
- 什么是lambda表达式? 查看lambda表达式的最简单方法就像一种方法:“它提供了形式参数的列表,以及根据这些参数表示的主体(表达式或块)。lambda表达式的参数可以声明或推断。 ,当形式参数具有推断的类型时,则这些类型是从lambda表达式所针对的功能接口类型派生的。 从返回值的角度来看,lambda表达式可以是void兼容的-它们不返回任何值或值兼容-如果任何给定的执行路径返回值。
Lambda听起来很好听吗? 但是以某种方式对功能接口的需求在某种程度上受到了限制–这是否意味着我只能使用包含单个抽象方法的接口? 并非完全如此-JDK 8提供了一种别名机制,该机制允许从类或对象中“提取”方法。 这可以通过使用新添加的::运算符来完成。 它可以应用于类–用于提取静态方法,也可以应用于对象以提取方法。 相同的运算符也可以用于构造函数。
引用:
interface ConstructorReference{T constructor();
}interface MethodReference {void anotherMethod(String input);
}public class ConstructorClass {String value;public ConstructorClass() {value = 'default';}public static void method(String input) {System.out.println(input);}public void nextMethod(String input) {// operations}public static void main(String... args) {// constructor referenceConstructorReferencereference = ConstructorClass::new;ConstructorClass cc = reference.constructor();// static method referenceMethodReference mr = cc::method;// object method referenceMethodReference mr2 = cc::nextMethod;System.out.println(cc.value);}
}
- 接口中的默认方法
这意味着从版本8开始,java接口可以包含方法主体,因此简单地说,java将支持多重继承,而不会带来通常的麻烦。 同样,通过提供接口方法的默认实现,可以确保添加新方法不会在实现类中造成混乱。 JDK 8向java.util.Collection或java.util.Iterator之类的接口添加了默认方法,并通过此方法提供了一种在实际需要的地方更好地使用lambda的机制。
值得注意的接口添加:
java.util.stream.Streamablejava.util.stream.Stream
改善馆藏的互动
在我看来,lambda项目所带来的所有更改都是对语言的重大补充,这将使其与当前的标准保持一致,并使之更简单,更精简,但可能会对生产力产生最大的影响,并且最大的好处是+效果肯定是集合框架的改进。 不,没有Collection 2框架,我们现在仍然需要处理类型擦除,但是Java将做出另一个重要的转变:从外部迭代到内部迭代。 这样,它为开发人员提供了一种以优雅的方式过滤和聚合集合的机制,此外还可以提高效率。 通过提供将在内部执行的lambda表达式,可以充分利用多核处理器的功能。 让我们考虑以下情形:
一个。 考虑一个字符串列表,选择所有大写的字符串。 怎么写?
旧方法:
//.....List inputList = new LinkedList<>();List upper = new LinkedList<>();// add elementsfor (String currentValue : inputList) {if (currentValue != null && currentValue.matches("[A-Z0-9]*")) {upper.add(currentValue);}}System.out.println(upper);
//….. 新方法:
//.....inputList.stream().filter(x -> (x != null && x.matches('[A-Z0-9]*'))).into(upper);
b。 考虑您想将所有提取的字符更改为小写。 使用JDK8的方式如下所示:
// .....inputList.stream().filter(x -> (x != null && x.matches("[A-Z0-9]*"))).map(String::toLowerCase).into(upper);
C。 以及如何从所选集合中找出字符数
// ..... int sumX = inputList.stream().filter(x -> (x != null && x.matches("[A-Z0-9]*"))).map(String::length).reduce(0, Integer::sum);
使用的方法:
default Streamstream() // java.util.CollectionStreamfilter(Predicate predicate) // java.util.stream.StreamIntStream map(IntFunction mapper) //java.util.stream.Stream
d。 如果我想从集合中获取每个元素并打印出来怎么办?
//OLD WAY:
for (String current : list) {System.out.println(current);
}//NEW WAY:list.forEach(x -> System.out.println(x));
除了提到的功能之外,JDK 8还有其他有趣的消息,但是出于简洁的原因,我将在这里停止。 有关它的更多信息,请参见JDK 8 Project lambda网站或JSR 337的网页。
总而言之,Java正在向前发展,我个人喜欢它的发展方向,另一个兴趣点是库开发人员也开始采用JDK 8的时间点。 那肯定会很有趣。 谢谢您的时间和耐心,祝您圣诞快乐。
资源资源
Brian Goetz资源文件夹:
http://cr.openjdk.java.net/~briangoetz/lambda
方法/构造方法参考:
http://doanduyhai.wordpress.com/2012/07/14/java-8-lambda-in-details-part-iii-method-and-constructor-referencing
参考: Java –我们的JCG合作伙伴 Olimpiu Pop在Java Advent Calendar博客上对JDK 8的远见。
翻译自: https://www.javacodegeeks.com/2012/12/java-far-sight-look-at-jdk-8.html