`
君淋天下
  • 浏览: 31787 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Java 8 新特性综合概述

阅读更多

 根据Oracle 对java 8开发进度安排,java将于2014年的3月份发布。从java8 新引入的特性看,函数式编程语言对java8 影响很大,运行在JVM上的ScalaGroovy等编程语言部分特性被java 8吸收。平台、API等方面先不关注,仅就从编程语言特性来说java8绝对是一次革命性的的改进,有了java 8 java语言的表达能力、简洁性有了很大提高,跟Scala groovy等JVM上的新兴语言差距缩小了很多。语言特性改进概括起来有以下几点

  •  函数式接口  
  •  Lambda表达式
  • 方法引用
  • 接口的改进
  • Stream
这篇文章我将说说以上几个语言特性,以及对代码编写的影响

一  函数式接口

 所谓函数式接口(FunctionalInterface)是指只有一个抽象方法的接口,比如java 8 之前的Runnabe接口(只有run方法),Comparator接口(comare方法),Comparable(compareTo方法)都属于函数式接口,到了Java 8时代这些接口都被注解为@FunctionalInterface,另外@FunctionalInterface也是java 8 新进入的注解,Java 8新增了一个包java.util.function,在function包下提供了大量常见函数式接口,举例如一下几个

Predicate:谓词,boolean test(T t) 输入类型T,输出布尔值

Supplier 生产者,T  get(),无输入,输出类型T

Consumerer 消息者,void accept(T t),输入T,无输出

Function 函数,R apply(T t ) ,输入T 输出R

 

 二 Lambda

Lambda表达式就是匿名方法,方法可以通过名称被重用,而匿名方法不能在被其它代码所调用。lambda也具有输入参数,方法体,返回值,比如(Object o) ->{System.out.println(o.toString()); return o.toSting();}输入参数为Object o 返回值为String类型,方法体为{}之间的语言

比如方法sum方法

public int sum(int x ,int y){
        return x + y;
}

 改用lambda表达式为

(int x, int y) -> {return x + y;}

 在特点场景下通过java 8 类型推导功能,可以省略lambda输入参数的类型,比如上面的sum方法lambda表达式可以改写为

(x, y) -> {return x + y;}

 lambda表达式方法体内可以访问lamba外的变量,相比匿名内部类访问外部类变量需要final修饰方便多了

 Runnable的run方法没有输入参数,用lambda表达式写Runnable接口实现类可以这样写

   

Runable r = () -> {System.out.println("Hello");}

 

Comparator<String>接口实现类可以这样写

Comparator comparator = (String str1,String str2) ->{return s1.compareToIgnoreCase(s2);}
//由于lambda基于类型推导功能,可以省去str1和str2前面的类型String
Comparator comparator = (str1,str2) ->{return s1.compareToIgnoreCase(s2);}

 

 

三 方法引用

  通过方法引用轻轻松松的实现function as first-classs object(函数作为一类对象)功能,可以将方法作为变量看待,作为参数传递。方法引用符号是::

比如通过 方法引用实现字符串从小写到大写的转换

Function<String, String> upperfier = String::toUpperCase;
 System.out.println(upperfier.apply("Hello"));

 比如Set类里有boolean contains(T t)方法,显然方法属于谓词(Predicate)函数,我用可以这用的使用Set的contains方法

 

 Set<String> knowNames = new HashSet<>();
 knowNames.add("Zhang");
 knowNames.contains("Zhang");

 Predicate<String> isKnowName = knowNames::contains;
 isKnowName.test("Zhang");
 isKnowName.test("Li");

 

以上举的方法引用都是实例方法引用,方法引用包括(此处方法包括静态方法、实例方法、构造方法、数组构造方法) 

 

  四 接口的改进

  java 8 中对接口的功能做了改进,包括默认方法和静态方法。

 

 1 默认方法

在java8以前接口不能定义具体方法,只能定义抽象方法。作为一个通用的库或框架,接口一旦发布之后不能轻易的增加新的抽象方法,否则该接口的具体实现类都必须跟着实现新增的方法。java 8 中为了不破坏接口的实现,允许接口有具体的实现方法,实现方法用关键字default修饰 也叫默认方法。

比如JDK中Iterable接口中新增的默认方法 forEach实现遍历功能

 

 default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

 

 

接口增加了默认方法之后就会存在多继承问题。

  比如接口1和接口2都有相同的默认方法method1,接口3同时继承了接口1和接口2,在接口3以及接口3的实现类里 method1到底是继承接口1还是继承接口2的method1方法呢? java 8 通过引入新的语法来i解决问题,接口3必须重写method1方法,在method1方法里可以指定到底是继承接口1还是接口2,比如下面的代码DrawInteface3的draw必须显示指定继承哪个父接口的方法

 

public interface DrawInterface1 {

    default void draw(){
        System.out.println("DrawInterface1.draw");
    }
}

public interface DrawInterface2 {

    default void draw(){
        System.out.println("DrawInterface2.draw");
    }
}

public interface DrawInterface3 extends DrawInterface1,DrawInterface2 {
    default void draw(){
        //接口名.super.父接口方法名 来指定调用哪个接口方法
        DrawInterface1.super.draw();
    }
}
 

  2 静态方法

  在java 8 以前接口标准库里定义了Collection接口,然后增加一个Collections工具了辅助Collection接口,java 8 里允许定义接口的静态方法(static修饰)

   比如Comparator接口增加了大量的静态放,有了comparing这个静态方法后写比较器非常的轻松

 

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor)
    {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
    }

//根据名字做比较的比较器
Comparator nameComparator = Comparator.comparing(Employee::getName);

//根据薪水做比较比较器
Comparator salaryComparator = Comparator.comparing(Employee::getSalary);
 

 

 五  Stream 流

1 本质

java8 新增的Stream非之前IO相关的流,Stream的本质是对数据源进行抽象提供一套通用API,引入Stream、函数式接口、lambda等几大特性候java 8 有了一些函数式编程语言味道

Stream实现map filter reduce等操作,Stream的数据源包括数组、集合、IO通道、随机数生成器等,Stream相关接口在java.util.stream包下

 

2 使用例子

现在举个List<Integer>来说明Stream的filter map reduce等常见高阶函数的使用   

//对list求和 
int result = list.stream().reduce(0,(x,y) -> x + y);

//对list过滤(大于5的数字)再求和 
int result = list.stream().filter(x -> x > 5).reduce(0,(x,y) -> x + y);

//对list 过滤(大于5的数字) 映射(求平方) 再求和,先通过mapToInt生成IntStream,调用sum方法 
result = list.stream().filter(x -> x > 5).map(x -> x * x).mapToInt(x -> x).sum();
 filter参数为谓词Predicate<T>   predicate,map函数参数为Function<T,R> mapper ,reduce参数为(T identity,BinaryOperator<T> accumulator),identity为起始值,accumulator为二元操作函数。
   x -> x > 5为Predicate的lambda写法,(x , y ) -> x + y 为BinaryOperator<T> accumulator的lambda写法

 

3 Stream的实际应用

当年学习Oracle时入门的例子就用employee表,这里我举例还是用Employee,只是从数据库表换成里java类。现有一个List<Employee> employees (Employee包括name、salary、departId三个属性),通过Stream的相应方法实现一些常见的"统计功能"

 

//求所有员工薪资总和
        int totalSalary = employees.stream()
                .map(e -> e.getSalary())
                .reduce(0,(x,y) -> x + y);
        System.out.println("totalSalary = " + totalSalary);
 
 //所有雇员姓名
 List<String> nameList = employees.stream()
                .map(e -> e.getName())
                .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
 System.out.println("nameList = " + nameList);
 

 

 

//求平均工资
double averageSalary = employees.stream()
                .mapToInt(e -> e.getSalary())
                .average()
                .getAsDouble();

 

 //求平均工资,用Collectors工具类的帮助方法
averageSalary = employees.stream()
                .collect(Collectors.averagingInt(e -> e.getSalary()));
  System.out.println("averageSalary = " + averageSalary);

 

 //雇员按照部门分组
 Map<Integer,List<Employee>> deaprtEmployee = employees.stream()
                .collect(Collectors.groupingBy(e -> e.getDepartId()));

 

 //打印每个部门的平均工资
        deaprtEmployee.forEach((k,v) -> System.out.println(k+":" + v.stream().mapToInt(
                e -> e.getSalary()).average().getAsDouble()));

 

//查找每个部门工资最低的雇员
deaprtEmployee.forEach((k,v) -> System.out.println(k+":" + v.stream().
                sorted(Comparator.comparing(Employee::getSalary)).findFirst().get()));

 

 //对雇员根据名字排序
employees.sort(Comparator.comparing(Employee::getName));

 

通过以上的例子可以看出java 8 的表达能力有了很大提高,更少的代码能完成更多的事情。另外通过Stream的collect()方法和工具类Collectors可以轻轻松松实现很多运算方法。

 

 

 

 

 

分享到:
评论

相关推荐

    Java语言实用教程

    第6章 Java类的高级特性 6.1 访问权限 6.2 方法重载 6.3 构造方法 …… 第7章 继承、接口和包 第8章 系统常用类 第9章 异常处理 第10章 输入输出流与文件处理 第11章 简单GUI编程 第12章 Java Applet基础 附录 参考...

    java课件(ppt课件)

    第01章 Java概述.ppt 第02章 Java语言基础.ppt 第03章 面向对象的核心特性.ppt 第04章 接口、内部类和包.ppt 第05章 异常处理.ppt 第06章 图形用户界面.ppt 第07章 多线程.ppt 第08章 Applet应用程序.ppt 第09章 ...

    JAVA基础课程讲义

    JAVA的特性和优势 14 JAVA应用程序的运行机制 15 JVM(JAVA VIRTUAL MACHINE) 16 Java运行时环境JRE(Java Runtime Environment) 17 JAVA语言应用范围 18 第一个JAVA程序 18 JAVA开发环境搭建 18 一个典型的JAVA程序的...

    java基础案例与开发详解案例源码全

    1.2.1 Java语言特性3 1.2.2 JavaApplet4 1.2.3 丰富的类库4 1.2.4 Java的竞争对手5 1.2.5 Java在应用领域的优势7 1.3 Java平台的体系结构7 1.3.1 JavaSE标准版8 1.3.2 JavaEE企业版10 1.3.3 JavaME微型版11 1.4 ...

    javaswing程序源码-java-book:《Java编程:综合入门》一书的源代码

    进行概述,然后介绍数据类型、运算符和控制语句的基本概念,接着讲解该语言更复杂的特性,如类、方法、继承、接口、包、异常、多线程和泛型。 第二部分(第17~21章)介绍 Swing,首先对用 Swing 进行 GUI 编程进行...

    java课程设计报告贪吃蛇游戏设计.doc

    3.1.2程序概述 本程序是一个利用Java应用软件制作的贪食蛇小游戏。在游戏过程中,用户通过点击 小键盘区的方向键来控制蛇的运行方向;游戏运行过程中,如果想暂停,只需要按F3键 即可。重新开始游戏的按键为F2。当...

    基于Java和android的外卖APP设计.doc

    3 2.3.2 硬件接口 3 2.3.3 软件接口 4 2.4 系统功能需求 4 2.5 分析模型 4 2.5.1 数据流图 4 2.5.2 用例图 5 3 设计报告 8 3.1 设计概述 8 3.2 系统的概要设计与分析 8 3.2.1 系统功能设计 8 3.2.2 子系统与模块 9 ...

    java面试宝典

    coreJava部分 8 1、面向对象的特征有哪些方面? 8 2、作用域public,private,protected,以及不写时的区别? 8 3、String 是最基本的数据类型吗? 8 4、float 型float f=3.4是否正确? 8 5、语句float f=1.3;编译能否...

    基于Java的人事管理系统的设计与实现.doc

    基于Java的人事管理系统的设计与实现 摘要:本文根据企业人事管理的实际情况,采用了myeclipse/tomcat作为开发工具, 利用java/jsp建模语言设计开发出了人事管理信息系统。主要包括登录系统、系统构建 模块、指标...

    java安卓开发外卖订餐系统课程设计.doc

    JAVA课程设计报告 题目:外卖订餐系统 班 级: 姓 名: 学 号: 指导教师: 日 期: 年 月 日 目 录 一、概述 1 1.1课程设计的目的 1 1.2设计任务与要求 1 二、需求分析报告 2 1 引言 2 1.1 编写目的 2 1.2 产品范围 2 2 ...

    java程序设计与开发课件

    第1章 Java语言概述······························· (1) 1.1 Java语言及其产生···························· (1) 1.2 Java的特点··········...

    《UML建模实例教程》【PPT】

    3.5.10UML 2.0新特性 3.6UML建模基本流程 习题 第4章UML建模工具简介 4.1常用UML建模工具 4.1.1 Rational Rose 4.1.2Enterprise Architect 4.1.3Together 4.1.4PowerDesigner 4.1.5 Visi0 4.1.6Tnffun ...

    JDBC 3.0数据库开发与设计

    2.2.3 PL/SQL和Java的特性 2.2.4 PL/SQL和Java的实际开发应用实例 2.2.5 Java连接各类数据库的程序代码 2.3 Web应用服务器 2.3.1 Tomcat的安装及系统文件设置 2.3.2 WebSphere简介 2.3.3 WebLogic的安装和配置...

    动力节点MySQL数据库入门视频教程-029-综合案例

    动力节点的杜老师讲述的mysql教程,详细讲解了MySQL的相关知识,包括MySQL概述,MySQL应用环境,MySQL系统特性,MySQL初学基础,MySQL管理工具,如何安装MySQL及MySQL新特性,通过观看可掌握MySQL全套知识。

    深入探索Redis的实验性应用与实践源码

    本项目以Java为主要开发语言,综合运用Lua脚本,深入探索Redis数据库的实验性应用与实践。项目包含25个文件,涵盖了从图像资源到配置文件,再到核心代码和构建脚本。 文件类型详细说明: - 图像资源:共7个.png文件...

    javaSE代码实例

    9.1 概述及其特性 156 9.2 成员变量在接口中的使用 157 9.2.1 语法规则 157 9.2.2 接口中成员变量的作用 158 9.3 方法在接口中的使用 159 9.3.1 语法规则 159 9.3.2 如何实现接口 160 9.3.3 接口引用...

    Ext Js权威指南(.zip.001

    Ex4.0共2个压缩包特性,《ext js权威指南》 前 言 第1章 ext js 4开发入门 / 1 1.1 学习ext js必需的基础知识 / 1 1.2 json概述 / 3 1.2.1 认识json / 3 1.2.2 json的结构 / 3 1.2.3 json的例子 / 4 1.2.4 ...

    千方百计笔试题大全

    coreJava部分 8 1、面向对象的特征有哪些方面? 8 2、作用域public,private,protected,以及不写时的区别? 8 3、String 是最基本的数据类型吗? 8 4、float 型float f=3.4是否正确? 8 5、语句float f=1.3;编译能否...

    基于SSH2+Maven+EasyUI+MySQL技术实战开发易买网电子商务交易平台

    特点二、在每节开始之前先简单回顾上一节所讲的主要内容,并对本节所讲的内容先进行概述,讲解概念、技术要点,设计实现思路等内容,最后总结本次课程的要掌握的要点,讲师授课采用先理论,后实战的方式,由浅入深...

Global site tag (gtag.js) - Google Analytics