jdk8新特性

1接口的默认方法-静态方法

  1.1 static方法 

           1.使用static修饰的接口,必须有主体

           2.使用static修饰的接口,只能被他本身调用  接口名.方法名

          3.使用static修饰的接口,不能被子接口继承

         4.使用static修饰的接口,不能被实现类覆写,及直接调用。

   1.2 代码  

public interface MyInterface {
    public abstract  void test();

    static  void staticMethod(){
        System.out.println("hello ....");
    };
}
public class Test {
    public static void main(String[] args) {
        MyInterface.staticMethod();
    }
}

   结论:通过上面的demo,可以测试出,1.1中的1和2点,都符合。

 

使用static修饰的接口,不能被子接口继承

public interface SubInfarce extends MyInterface{

}

这里显示为红色的波浪线,该子接口没有继承父接口的静态方法。 

使用static修饰的接口,不能被实现类覆写,及直接调用

public class MyIntergfaceImpl implements  MyInterface {
    @Override
    public void test() {

    }
}

 从上面的代码中可以看出,父接口的状态方法,没有重写

2.接口的默认方法-default方法

   2.1 demo

public interface MyInterface {
    default void defaultMethod(){
        System.out.println("hello default ...");
    };
}
public class MyInterfaceImpl implements MyInterface {

}
public class Test {
    public static void main(String[] args) {
        MyInterface myInterface = new MyInterfaceImpl();
        myInterface.defaultMethod();
    }
}

结论:default方法,不能通过接口的方式调用,一定要有一个接口实现该接口,才能调用。

2.2 demo2

public interface MyInterface {
    default void defaultMethod(){
        System.out.println("hello default ...");
    };
}
public class MyInterfaceImpl implements MyInterface {
    @Override
    public void defaultMethod() {
        MyInterface.super.defaultMethod();
        System.out.println("impl");
    }
}
public class Test {
    public static void main(String[] args) {
        MyInterface myInterface = new MyInterfaceImpl();
        myInterface.defaultMethod();
    }
}

 结论:可以在接口中编写逻辑,在实现类中调用。

2.3 demo3

public interface SubInterface extends  MyInterface {

}
public class SubInterfaceImpl implements  SubInterface {

}
public class Test {
    public static void main(String[] args) {
        SubInterface sub = new SubInterfaceImpl();
        sub.defaultMethod();
    }
}

结论:说明接口里面的default方法,能被子接口继承。 

3.函数式接口

        函数式接口就是有且只有一个抽象方法,但是可以有多个非抽象方法,函数式接口可以隐式的转为lambda表达式。

@FunctionalInterface
public interface MyInterface<functionInterface> {
    public abstract void test();
    default void defaultMethod(){
        System.out.println("hello default ...");
    };
}

在接口上增加@FunctionalInterface,注意增加注解以后,就会很严格的判断是不是函数式接口,像如下的demo,因为有两个抽象方法,所以不符合函数式接口。

4.Lambda 表达式

         4.1  什么是Lambda表达式

                    简单的可以看成匿名内部类的简写, 使用Lambda表达式时,接口必须是函数式接口。

           4.2 Lambda表达式语法

                  < 函数式接口>  <变量名>   = (参数1,参数2....)    ->{

                              //  方法体

                   }     

           4.3代码

                      4.3.1  使用匿名内部类方式

public interface MyInterface {
    int sum(int num1,int num2);
}
public class Test {
    public static void main(String[] args) {
        MyInterface my = new MyInterface() {
            @Override
            public int sum(int num1, int num2) {
                return num1+num2;
            }
        };
        System.out.println(my.sum(123,456));
    }
}

                           4.3.2 使用lambda表达式(接收两个参数)

public class Test {
    public static void main(String[] args) {
        MyInterface my = new MyInterface() {
            @Override
            public int sum(int num1, int num2) {
                return num1+num2;
            }
        };

        //使用Lambda表达式
        MyInterface my1 =(int num1,int num2) -> {
            return num1+num2;
        };
        System.out.println(my1.sum(123,456));
    }
}

两种方式,实现的效果一样

Lamda表达式简写

使用Lambda表达式简写:

          1.形参参数列表的类型可以不写,会自动推断

          2.如果方法中的代码只有一句,可以省略掉{},如果是ruturn返回数据的,可以省略return

  MyInterface my2=(num1,num2) -> num1+num2;

  4.3.3 使用lambda表达式(接收一个参数,且没有返回值)

public interface MyInterface {
    void print(String msg);
}
public class Test {
    public static void main(String[] args) {
        //使用匿名内部类的方式  打印一句话
        MyInterface my = new MyInterface() {
            @Override
            public void print(String msg) {
                System.out.println("Hello "+msg+"...");
            }
        };
        //使用Lambda常规写法
        MyInterface my1 = (String msg) -> {
            System.out.println("Hello "+msg+"...");
        };

        //Lambda简写方法
        MyInterface my2 = (msg) -> System.out.println("Hello "+msg+"...");

        my2.print("Lanbda");
    }
}

4.3.4 使用lambda表达式(接收无参数,且没有返回值)

public interface MyInterface {
    void test();
}
public class Test {
    public static void main(String[] args) {
        //匿名内部类
        MyInterface my = new MyInterface() {
            @Override
            public void test() {
                System.out.println("666");
            }
        };

        //Lambda表达式
        MyInterface my1 = () ->{
              System.out.println(666);
        };

        //简写Lambda
        MyInterface my2 =() -> System.out.println(6666);
        my2.test();
    }
}

4.4 Lambda作用域

         在Lambda表达式中访问外层作用域和老版本匿名对象中的方式很相似,可以直接访问标记的final的外层局部变量,或者实例的字段及镜头变量,单如果访问局部变量,要求局部变量必须是final修饰的。

这里的变量a实际上是final类型的,final类型很重要的一点就是不能赋值,实际上,他为了是final,这是因为新版本里面隐式的帮我们做了处理。

4.5 构造方法引用

public interface MyInterface {
    Student createStuent(String name,Integer age);
}
public class Student {
    private String name;
    private Integer age;

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class Test {
    public static void main(String[] args) {
        //Lambda常规写法
        MyInterface my1 = (name,age) ->  new Student(name,age);
        //Lambda简写
        MyInterface my2 = Student:: new;
        Student stuent = my2.createStuent("张三", 14);
        System.out.println(stuent.toString());
    }
}

4.6  静态方法引用 

public interface MyInterface {
    int parse(String msg);
}
public class Test {
    public static void main(String[] args) {
        //常规写法
        MyInterface my = msg -> Integer.parseInt(msg);
        //简写
        MyInterface my1 = Integer::parseInt;
    }
}

4.7 实例方法引用

public class Test {
    public static void main(String[] args) {
        String str = "Hello Lambda";
        //使用匿名内部类的方式
        Function<String,Boolean> fun = new Function<String, Boolean>() {
            @Override
            public Boolean apply(String s) {
                return str.endsWith(s);
            }
        };

        //使用常规写法
        Function<String,Boolean> fun1= s -> str.endsWith(s);

        //使用简写
        Function<String,Boolean> fun2 = str::endsWith;

        Boolean apply = fun2.apply("Lambda");
        System.out.println(apply);
    }
}

4.8 事例

       4.8.1  循环list数组

public class Test1 {
    public static void main(String[] args) {
        List<String> lists= Arrays.asList("a","b","c","d");
        //老版本代码
        for (String s:lists){
            System.out.println(s);
        }
        //使用jdk8
        lists.forEach(i -> System.out.println(i));
    }
}

                 4.8.2  对数据进行排序

public class Test1 {
    public static void main(String[] args) {
        // 如果用Lambda表达式,一定要写明泛型
        List<String> list = Arrays.asList("peter","anna","make");
        /**  老版本代码  */
       Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String a, String b) {
                return a.compareTo(b);
            }
        });

       //使用Lambda表达式
        Collections.sort(list,(a,b) -> a.compareTo(b));
        //简写
        Collections.sort(list, String::compareTo);
        list.forEach(i-> System.out.println(i));
    }
}

                       4.8.3 stream()

  查询学生List中,年龄大于20岁,并输出

     List<Student> students = new ArrayList<>();
     students.add(new Student("Ted", "Neward", 41));
     students.add(new Student("Charlotte", "Neward", 41));
     students.add(new Student("Michael", "Neward", 19));
     students.add(new Student("Matthew", "Neward", 13));

     students.stream().filter((e) -> e.age >20).forEach(System.out::println);

4.8.4 forEach() 使用该方法迭代流中的每个数据

public class Test2 {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Ted", "Neward", 41));
        students.add(new Student("Charlotte", "Neward", 41));
        students.add(new Student("Michael", "Neward", 19));
        students.add(new Student("Matthew", "Neward", 13));
        // java 8 前
        System.out.println("java 8 前");
        for(Student student: students){
            System.out.println(student);
        }
        System.out.println("-------------------------------");
        //java lambda
        System.out.println("java 8 lambda");
        students.forEach(student -> System.out.println(student));
        System.out.println("-------------------------------");
        //java stream
        System.out.println("java stream");
        students.stream().forEach( student -> System.out.println(student));
    }
}

4.8.5 sorted() 使用该方法排序数据

public class Test2 {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Ted", "Neward", 41));
        students.add(new Student("Charlotte", "Neward", 41));
        students.add(new Student("Michael", "Neward", 19));
        students.add(new Student("Matthew", "Neward", 13));

        System.out.println("排序前:");
        students.forEach(student -> System.out.println(student));
        System.out.println("-----排序后-----");
        students.stream().sorted(Comparator.comparing(Student::getAge)).forEach(student -> System.out.println(student));
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值