您现在的位置是:首页 > 文章详情

Java8新特性总结

日期:2018-05-07点击:422

Java8新特性总结

Lambda 表达式

Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中)
它允许我们将函数当成参数传递给某个方法,或者把代码本身当作数据处理:函数式开发者非常熟悉这些概念

用Lambda表达式实现Runnable

我们在这里做了什么呢?那就是用() -> {}代码块替代了整个匿名类。

// Java 8之前: new Thread(new Runnable() { @Override public void run() { System.out.println("Before Java8, too much code for too little to do"); } }).start(); //Java 8方式: new Thread( () -> System.out.println("In Java8, Lambda expression rocks !!") ).start(); 

使用Java 8 lambda表达式进行事件处理

// Java 8之前: JButton show = new JButton("Show"); show.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("Event handling without lambda expression is boring"); } }); // Java 8方式: show.addActionListener((e) -> { System.out.println("Light, Camera, Action !! Lambda expressions Rocks"); });

使用lambda表达式对列表进行迭代

// Java 8之前: List<String> features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API"); for (String feature : features) { System.out.println(feature); } // Java 8之后: List features1 = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API"); features1.forEach(n -> System.out.println(n));

使用lambda表达式和函数式接口Predicate

除了在语言层面支持函数式编程风格,Java 8也添加了一个包,叫做 java.util.function。它包含了很多类,用来支持Java的函数式编程。其中一个便是Predicate,使用 java.util.function.Predicate 函数式接口以及lambda表达式,可以向API方法添加逻辑,用更少的代码支持更多的动态行为。下面是Java 8 Predicate 的例子,展示了过滤集合数据的多种常用方法。Predicate接口非常适用于做过滤。

public static void main(String[] args){ List<String> languages = Arrays.asList("Java", "Scala", "C++", "Haskell", "Lisp"); System.out.println("Languages which starts with J :"); filter(languages, (str)->((String) str).startsWith("J")); System.out.println("Languages which ends with a "); filter(languages, (str)->((String) str).endsWith("a")); System.out.println("Print all languages :"); filter(languages, (str)->true); System.out.println("Print no language : "); filter(languages, (str)->false); System.out.println("Print language whose length greater than 4:"); filter(languages, (str)->((String) str).length() > 4); } public static void filter(List<String> names, Predicate condition) { for(String name: names) { if(condition.test(name)) { System.out.println(name + " "); } } }

使用lambda表达式的Map和Reduce示例

// 为每个订单加上12%的税 // 老方法: List<Integer> costBeforeTax = Arrays.asList(100, 200, 300, 400, 500); double total = 0; for (Integer cost : costBeforeTax) { double price = cost + 0.12*cost; total = total + price; } System.out.println("Total : " + total); // 新方法: List<Integer> costBeforeTax1 = Arrays.asList(100, 200, 300, 400, 500); double bill = costBeforeTax1.stream().map((cost) -> cost + 0.12*cost).reduce((sum, cost) -> sum + cost).get(); System.out.println("Total : " + bill);

接口的默认方法和静态方法

Java 8使用两个新概念扩展了接口的含义:默认方法和静态方法。
默认方法使得开发者可以在 不破坏二进制兼容性的前提下,往现存接口中添加新的方法,即不强制那些实现了该接口的类也同时实现这个新加的方法。

默认方法就是一个在接口里面有了一个实现的方法。

默认方法和抽象方法之间的区别在于抽象方法需要实现,而默认方法不需要。接口提供的默认方法会被接口的实现类继承或者覆写

private interface Defaulable { // Interfaces now allow default methods, the implementer may or  // may not implement (override) them. default String notRequired() { return "Default implementation"; } } private static class DefaultableImpl implements Defaulable { } private static class OverridableImpl implements Defaulable { @Override public String notRequired() { return "Overridden implementation"; } }

Defaulable接口使用关键字default定义了一个默认方法notRequired()。DefaultableImpl类实现了这个接口,同时默认继承了这个接口中的默认方法;OverridableImpl类也实现了这个接口,但覆写了该接口的默认方法,并提供了一个不同的实现。

Java 8带来的另一个有趣的特性是在接口中可以定义静态方法,例子代码如下:

private interface DefaulableFactory { // Interfaces now allow static methods static Defaulable create( Supplier< Defaulable > supplier ) { return supplier.get(); } }

下面的代码片段整合了默认方法和静态方法的使用场景:

public static void main( String[] args ) { Defaulable defaulable = DefaulableFactory.create( DefaultableImpl::new ); System.out.println( defaulable.notRequired() ); defaulable = DefaulableFactory.create( OverridableImpl::new ); System.out.println( defaulable.notRequired() ); }

这段代码的输出结果如下:

Default implementation Overridden implementation

由于JVM上的默认方法的实现在字节码层面提供了支持,因此效率非常高。默认方法允许在不打破现有继承体系的基础上改进接口。该特性在官方库中的应用是:给java.util.Collection接口添加新方法,如stream()、parallelStream()、forEach()和removeIf()等等。

尽管默认方法有这么多好处,但在实际开发中应该谨慎使用:在复杂的继承体系中,默认方法可能引起歧义和编译错误。如果你想了解更多细节,可以参考官方文档。

Date Time API

加强对日期与时间的处理。
jdk1.8新增了java.time包和java.time中的类

Java 8引入了新的Date-Time API(JSR 310)来改进时间、日期的处理。时间和日期的管理一直是最令Java开发者痛苦的问题。java.util.Date和后来的java.util.Calendar一直没有解决这个问题。

因为上面这些原因,诞生了第三方库Joda-Time,可以替代Java的时间管理API。Java 8中新的时间和日期管理API深受Joda-Time影响,并吸收了很多Joda-Time的精华。新的java.time包包含了所有关于日期、时间、时区、Instant(跟日期类似但是精确到纳秒)、duration(持续时间)和时钟操作的类。新设计的API认真考虑了这些类的不变性(从java.util.Calendar吸取的教训),如果某个实例需要修改,则返回一个新的对象。

我们接下来看看java.time包中的关键类和各自的使用例子。首先,Clock类使用时区来返回当前的纳秒时间和日期。Clock可以替代System.currentTimeMillis()和TimeZone.getDefault()。

// Get the system clock as UTC offset final Clock clock = Clock.systemUTC(); System.out.println( clock.instant() ); System.out.println( clock.millis() );

上述例子的输出结果如下:

2018-04-23T06:59:48.587Z 1524466788738 

第二,关注下LocalDate和LocalTime类。LocalDate仅仅包含ISO-8601日历系统中的日期部分;LocalTime则仅仅包含该日历系统中的时间部分。这两个类的对象都可以使用Clock对象构建得到。

// Get the system clock as UTC offset final Clock clock = Clock.systemUTC(); // Get the local date and local time final LocalDate date = LocalDate.now(); final LocalDate dateFromClock = LocalDate.now(clock); System.out.println(date); System.out.println(dateFromClock); // Get the local date and local time final LocalTime time = LocalTime.now(); final LocalTime timeFromClock = LocalTime.now(clock); System.out.println(time); System.out.println(timeFromClock);

上述例子的输出结果如下:

2018-04-23 2018-04-23 15:17:58.641 07:17:58.641

Stream API

原文地址 http://www.bieryun.com/3703.html
原文链接:https://yq.aliyun.com/articles/590830
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章