zoukankan      html  css  js  c++  java
  • 01.java8入门

    函数式编程的不变模式

    
    import java.util.Arrays;
    
    /**
     * 函数式编程的不变模式
     */
    public class ArrStream {
        public static void main(String[] args){
            int[] arr = {1,2,3,4,5};
            Arrays.stream(arr).map((x)->x+1).forEach(System.out::print);
            System.out.println();
            Arrays.stream(arr).forEach(System.out::print);
        }
        //23456
        //12345
    }
    

    FunctionalInterface注解

    /**
     * FunctionalInterface注解
     */
    @FunctionalInterface //用于表明是一个函数式接口
    public  interface IntHandler {
        void handle(int i);//只包含一个抽象方法
    }
    
    @FunctionalInterface //用于表明是一个函数式接口
    public  interface IntHandler {
        boolean equals(Object obj);//此时编译未通过,不是函数式接口,因为equals()方法在java.lang.Object中已经实现
    }
    
    /**
     * 符合函数式接口要求
     */
    @FunctionalInterface //用于表明是一个函数式接口
    public  interface IntHandler {
        boolean equals(Object obj);
        void handle(int i);
    }
    

    接口的默认方式--default关键字

    public interface IHorse {
        void eat();
        //使用default关键字,可以在接口内定义实例方法
        default void run(){
            System.out.println("Horse run");
        }
    }
    
    public interface IAnimal {
        default void breath(){
            System.out.println("breath");
        }
    }
    
    public interface IDonkey {
        void eat();
        default void run(){
            System.out.println("Donkey run");
        }
    }
    
    
    /**
     * 同时拥有不同接口的实现方法
     */
    public class Mule implements IAnimal,IHorse,IDonkey {
        @Override
        public void eat() {
            System.out.println("Mule eat");
        }
        @Override
        public void run(){
            IHorse.super.run();
        }
        public static void main(String[] args){
            Mule mule = new Mule();
            mule.run();
            mule.breath();
        }
        //Horse run
        //breath
    }
    
    
    import java.util.function.Function;
    
    /**
     * lambda表达式访问外部的局部变量
     */
    public class LambdaTest {
        public static void main(String[] args){
            final int num = 2;//外部的变量必须申明为final,即使省略final也可以编译通过,这是因为Java8会自动将lambda表达式中使用的变量视为final
            Function<Integer,Integer> st = (from)->from*num;
            System.out.println(st.apply(3));
            int num2 = 3;
            Function<Integer,Integer> st2 = (from)->from*num2;
            num2++;//编译保错 Error:(14, 54) java: 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量
        }
    }
    
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 方法引用:
     * 静态方法引用:ClassName::methodName
     * 实例上的实例方法引用:instanceReference::methodName
     * 超类上的实例方法引用:super:methodName
     * 类型上的实例方法引用:ClassName::methodName
     * 构造方法引用:Class::methodName
     * 数组构造方法引用:TypeName[]::methodName
     *
     * 方法引用使用::定义,::前半部分表示类名或实例名,后半部分表示方法名称,如果是构造函数,则使用new表示
     */
    public class InstanceMethodDemo {
        static class User{
            private int id;
            private String name;
    
            public User(int id, String name) {
                this.id = id;
                this.name = name;
            }
    
            public int getId() {
                return id;
            }
    
            public void setId(int id) {
                this.id = id;
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
        }
        public static void main(String[] args){
            List<User> users = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                users.add(new User(i,"name"+Integer.toString(i)));
            }
            //User::getName,在执行时,java会自动识别流中的元素(这里指User实例)是作为调用目标还是调用方法的参数,
            //显然应该作为调用目标,在这里调用每一个User对象实例的getName()方法,并将这些User的name作为一个新的流,
            //同时,对于这里得到的所有name,使用方法引用System.out::println进行处理。系统会自动判断,流内的元素此时
            //应该作为方法的参数传入,而️不是调用目标
    
            // 一般来说,如果使用的是静态方法,或者调用目标明确,那么流内的元素会自动作为参数使用。如果函数引用表示
            //实例方法,并且不存在调用目标,那么流内元素就会自动作为调用目标
            users.stream().map(User::getName).forEach(System.out::println);
        }
        //name0
        //name1
        //name2
        //name3
        //name4
        //name5
        //name6
        //name7
        //name8
        //name9
    }
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class ConstrMethodRef {
        public static void main(String[] args){
            List<User> users = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                users.add(uf.create(i,"name"+Integer.toString(i)));
            }
            users.stream().map(User::getName).forEach(System.out::println);
        }
        //User::new创建接口实例时,系统会根据UserFactory.create()的函数签名来选择合适的User构造函数
        //在这里,很显然就是 public User(int id, String name),在创建UserFactory.create()的调用
        //都会委托给User的实际构造函数进行,从而创建User对象实例。
        static UserFactory<User> uf = User::new;
        @FunctionalInterface
        interface UserFactory<U extends User>{
            U create(int id,String name);
        }
        static class User{
            private int id;
            private String name;
    
            public User(int id, String name) {
                this.id = id;
                this.name = name;
            }
    
            public int getId() {
                return id;
            }
    
            public void setId(int id) {
                this.id = id;
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
        }
    }
    
  • 相关阅读:
    Yslow-23条规则
    ASP.Net MVC多语言
    Java笔记--反射机制
    Java笔记--常用类
    Java笔记--多线程
    Java--IO流
    Java笔记--枚举&注解
    Java笔记--泛型
    Java笔记--异常
    Java笔记--集合
  • 原文地址:https://www.cnblogs.com/fly-book/p/11492471.html
Copyright © 2011-2022 走看看