接口改善

接口中可以定义默认方法和静态方法

interface A{
    public default void Sf(){
        System.out.println("A.Sf()");
    }

    public static int name() {
        return 1;
    }

}

class B implements A{

}

不能用默认方法来重载equals,hashCode和toString

函数式接口

Java 8 引入的一个核心概念是函数式接口。如果一个接口定义个唯一一个抽象方法,那么这个接口就成为函数式接口。比如,java.lang.Runnable就是一个函数式接口,因为它只有一个抽象方法:

public abstract void run();

引入了一个新的Annotation:@FunctionalInterface。可以把他它放在一个接口前,表示这个接口是一个函数式接口。

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

Lambda 表达式

为什么使用Lambda

一、Java是面向对象的语言,不能象函数式语言那样嵌套定义方法。

二、Java的匿名内部类只能存在于创建它的线程中,不能运行在多线程中,无法充分利用多核的硬件优势。

三、匿名内部类的缺点还有:

  1. 语法相对复杂。

  2. 在调用内部类的上下文中,指引和this的指代容易混淆。

  3. 类加载和实例创建语法不可避免。

  4. 不能引用外部的非final对象。

  5. 不能抽象化控制流程。

Lambda语法

lambda的语法包括三部分

  1. 参数列表

  2. 箭头符号”->”

  3. 代码块。

(参数列表)->{
表达式
}

Stream

  1. Stream在Java8中被定义为泛型接口

  2. Stream接口代表数据流。

  3. Stream不是一个数据结构,不直接存储数据。

  4. Stream通过管道操作数据。

  5. 创建Stream接口实现类对象

stream():创建一个Stream接口实现类的对象。

例如:

Stream stream=people.stream();

一、管道:代表一个操作序列。

二、管道包含以下组件:

  1. 数据集:可能是集合、数组等。

  2. 零个或多个中间业务。如过滤器

  3. 一个终端操作,如的forEach

过滤器

  1. 过滤器:用给定的条件在源数据基础上过滤出新的数据,并返回一个Stream对象。

  2. 过滤器包含匹配的谓词。

例如:判断p对象是否为男性的lambda表达式:

Stream stream=people.stream(); 
stream=stream.filter(p->p.getGender()==‘男’);
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class Java8 {

    public static void main(String[] args) {
        List<Person> people = createPeople();
        Stream<Person> stream = people.stream();
        stream.forEach(p->System.out.println(p.toString()));
        stream.filter(person -> person.getGender()==(Person.Sex.FEMALE)).
                forEach(person -> System.out.println(person.toString()));
    }

    public static List<Person> createPeople() {
        List<Person> tempList = new ArrayList<Person>();
        for (int i = 0; i < 10; i++) {
            Person p = new Person("张飞" + i, Person.Sex.FEMALE, 10 + i, 180 + i);
            if (i % 2 == 0) {
                p.setGender(Person.Sex.MALE);
            }
            tempList.add(p);
        }
        return tempList;
    }
}

class Person{

    private Sex gender;

    private String name;

    private int age;

    private int height;

    public static enum Sex{
        MALE,FEMALE;
    }

    public Person(String name,Sex gender,int age, int height) {
        super();
        this.gender = gender;
        this.name = name;
        this.age = age;
        this.height = height;
    }

    public Sex getGender() {
        return gender;
    }

    public void setGender(Sex gender) {
        this.gender = gender;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public int getHeight() {
        return height;
    }
    public void setHeight(int height) {
        this.height = height;
    }

    @Override
    public String toString() {
        return "Person [gender=" + gender + ", name=" + name + ", age=" + age
                + ", height=" + height + "]";
    }

}

DoubleStream接口

一、DoubleStream接口表示元素类型是double的数据源。

二、DoubleStream接口的常用方法:

  1. max().getAsDouble():获取流中数据集的最大值。

  2. stream.min().getAsDouble() :获取流中数据集的最小值。

  3. stream.average() :获取流中数据集的平均值。

三、获取DoubleStream

集合变量.mapToDouble()

【案例】统计people集合中姓名中包含“飞”字的平均身高

public static void main(String[] args) {
        List<Person> people = createPeople();
        Stream<Person> stream = people.stream();
        double height = stream.filter(person -> person.getName().
        contains("飞")).mapToDouble(person -> person.getHeight()).average().getAsDouble();
        System.out.println("所有名字包含飞字的人的平均身高:" + height);
    }

LocalDate类

LocalDate类使用ISO日历表示年,月,日

  1. LocalDate.now():

获取系统当前日期 :2016-06-24

  1. LocalDate.of(int year,int month,int dayofMonth)

按指定日期创建LocalDate对象。

LocalDate date=LocalDate.of(2015,5,30); 2015-05-30

  1. date.getYear(); //返回当前日期年

  2. date.getMonthValue(); //返回当前日期月份

  3. date.getDayOfMonth(); //返回当前日期天

LocalTiem类用于表示一天中的时间

  1. LocalTime.now()

获得当前系统的时间:17:47:22.905

  1. LocalTime.of(int hour,int minute,int second)

按指定时间创建LocalTime对象

  1. getHour()

  2. getMinute()

  3. getSecond()

LocalDateTime类用于表示日期和时间

  1. LocalDateTime类的常用方法:

  2. LocalDateTime.now():获取系统当前时间。

LocalDateTime.of(int year,int month,int dayOfMonth

int hour,int minute,int second)

按指定日期和时间创建LocalDateTime对象。

  1. getYear():返回日期中的年份。

  2. getMonth():返回日期中的月份。

  3. getDayOfMonth():返回月份中的日。

  4. getHour():返回小时。

  5. getMinute():返回分钟。

  6. getSecond():返回秒。

DateTimeFormatter类用于将字符串解析为日期

常用方法:

  1. static ofPattern(String pattern);

作用:按pattern字符串指定的格式创建DateTimeFormatter对象。

DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”);

  1. LocalDateTime.parse(strDate, formatter);

作用:按指定日期模板和该模版字符串创建LocalDateTime对象。