zoukankan      html  css  js  c++  java
  • 菜鸡的Java笔记 第三十六

    StudyLambda
        Lambda 指的是函数式编程,现在最为流行的编程模式为面向对象,很多的开发者并不认可面向对象,所以很多的开发者宁愿继续使用 C 语言进行开发,也不愿意使用java,c++
        但是随着整个行业的技术发展,函数编程语言已经开始被很多的人所认可,于是java也是被迫环境因素追加了 Lambda
        如果要想去理解 Lambda 表达式设置的背景,就需要首先理解匿名内部类
        匿名内部类解决的问题:对于抽象类或接口的子类如果发现其只使用一次,那么就没有必要将其定义为一个类,这样可以节约类的定义空间,但是匿名内部类太麻烦了
        
        范例:观察匿名内部类

    package cn.mysterious;
    interface IMessage{
        public String getMsg();
        
    }
    
    public class Lang0 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            IMessage msg = new IMessage() {
                
                @Override
                public String getMsg() {
                    // TODO Auto-generated method stub
                    return "ssssssssssssssss";
                }
            };
            System.out.println(msg.getMsg());
        }
    
    }

               
                因为面向对象的最大特征:结构要完整,这个时候如果使用 Lambda 表达式呢?
                

    package cn.mysterious;
    interface IMessage{
        public String getMsg();
        
    }
    
    public class Lang0 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            IMessage msg = () ->"?????????";
            System.out.println(msg.getMsg());
        }
    }

               
                一个简单的一行语句就代替了完整的结构,那么自然会有许多的追捧者去使用它
                实际上 Lambda 表达式以上的做法只是其中的一种形式,它有三种语法:
                    () ->{多行语句,return 语句};
                    () ->单行语句;
                    () ->返回结果;
                    
                范例:多行语句定义

    package cn.mysterious;
    interface IMessage{
        public String getMsg();
        
    }
    
    public class Lang0 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            IMessage msg = () ->{
                String str = "???????";
                return str;
            };
            System.out.println(msg.getMsg());
        }
    
    }                

                   
                    如果现在设计的接口里面没有返回值的存在,那么方法体也可以使用一行语句,可以直接避免“{}”定义

    package cn.mysterious;
    interface IMessage{
        public void print();
        
    }
    
    public class Lang0 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            IMessage msg = () -> System.out.println("???????????");;
            msg.print();
        }
    
    }

                   
                如果要想使用 Lambda 表达式有一个重要的前提:一个接口之中只允许有一个抽象方法,如果你现在需要强制描述接口定义(某一个接口就是函数式编程接口)则可以追加一个注解

    package cn.mysterious;
    @FunctionalInterface // 是函数式接口,只允许有一个抽象方法
    interface IMessage{
        public void print();
        
    }
    public class Lang0 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            IMessage msg = () -> System.out.println("???????????");;
            msg.print();
        }
    
    }

                   
                    Lambda 是基于函数式接口定义的,如果要想使用 Lambda  重要的前提:一个接口之中只允许有一个抽象方法
                    
                如果有很多抽象方法呢?

    package cn.mysterious;
    @FunctionalInterface // 是函数式接口,只允许有一个抽象方法
    interface IMessage{
        public void print();
        public default void fun(){}
        
    }
    public class Lang0 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            IMessage msg = () -> System.out.println("???????????");;
            msg.print();
            msg.fun();
        }
    
    }


    */

    /*    
        在之前所学习的都属于对象的引用,对象引用的本质在于:同一块堆内存空间,可以被不同的栈内存所指向
        那么方法的引用指的是一个方法可以设置不同的别名,即:可以被不同的接口的对象所使用
        对于方法的引用在java里面提供有四种处理形式:
            引用类中的静态方法:类名称 :: static 方法名称
            引用某个对象的方法;实例化对象 :: 普通方法
            引用某个特定的方法:类名称 :: 普通方法
            引用构造方法:类名称 :: 普通方法
            
        范例:引用静态方法
            String 类有一个 valueOf() 方法,该方法可以将接收到的基本数据类型变为字符串
                方法定义: public static String valueOf(数据类型 变量);
                

    package cn.mysterious;
    /**
     * 进行以函数式接口定义
     * @author mldn
     * @param <P> 引用方法的参数类型
     * @param <R> 引用方法的返回值定义
     */
    @FunctionalInterface // 是函数式接口,只允许有一个抽象方法
    interface IUtile<P,R>{
        public R convert(P p); // 做新的方法
        
    }
    public class Lang0 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            IUtile<Integer,String> objA = String :: valueOf; // 方法引用
            System.out.println(objA.convert(100));
        }
    
    }

               
            也可以使用 Integer,parseInt() 转换
                

    package cn.mysterious;
    public class Lang0 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            IUtil<Integer,String> objA =  String :: valueOf; // 方法引用
            System.out.println(fun(objA,100).length());
        }
        public static <P,R> R fun(IUtil<P,R> temp,P p){
            return temp.convert(p);
        }
    
    }
    /**
     * 进行以函数式接口定义
     * @author mldn
     * @param <P> 引用方法的参数类型
     * @param <R> 引用方法的返回值定义
     */
    @FunctionalInterface // 是函数式接口,只允许有一个抽象方法
    interface IUtil<P,R>{
        public R convert(P p); // 做新的方法
        
    }

               
            以上只是引用了一个简单的 static 方法,也可以直接引用某一个类中的方法
            
            范例:引用 String 类中的字符串转大写方法
                [“字符串”.toUpperCase] public String toUpperCase();

    package cn.mysterious;
    
    @FunctionalInterface // 是函数式接口,只允许有一个抽象方法
    interface IUtil<R>{
        public R upper(); // 做新的方法
        
    }
    public class Lang0 {
    
        public static void main(String[] args) {
            IUtil<String> obj = "hello" :: toUpperCase;
            System.out.println(obj.upper());
        }
    }

               
            范例:引用类中的普通方法
                String 类有一个 compareTo() 方法,这个方法是一个普通方法,而且需要两个参数比较
                    方法: public int compareTo(String str);

    package cn.mysterious;
    
    @FunctionalInterface // 是函数式接口,只允许有一个抽象方法
    interface IUtil<R,P>{
        public R compare(P p1,P p2); // 做新的方法
        
    }
    public class Lang0 {
    
        public static void main(String[] args) {
            IUtil<Integer,String> obj = String :: compareTo;
            System.out.println(obj.compare("A","a"));
        }
    }

                   
                以上使用的都是类的结构,而整个设计里面最大的亮点在于构造方法也可以设置别名引用
                
            范例:引用构造方法

    package cn.mysterious;
    @FunctionalInterface // 是函数式接口,只允许有一个抽象方法
    interface IUtil<R,FP,SP>{
        public R create(FP p1,SP p2); // 做新的方法
    
        
    }
    public class Lang0 {
    
        public static void main(String[] args) {
            IUtil<Member,String,Integer> obj = Member :: new; // 引用构造
            System.out.println(obj.create("????",20));
        }
    
    }
    class Member{
        private String name;
        private int age;
        public Member(String name,int age) {
            this.name = name;
            this.age = age;
        }
        @Override
        public String toString() {
            return "Member [name=" + name + ", age=" + age + "]";
        }
    }

               
                Lambda 表达式的操作除了可以自定义方法体之外,用户也可以去引用已经实现好的类中的方法
                
        
        内建函数式接口
            函数式接口是 Lambda 实现关键所在,但是很多时候如果要想进行一个项目设计的时候,肯定需要许多标准的函数式接口
            所以在java设计过程之中考虑到用户使用标准型问题,所以也提供有四个内建的函数式接口
                功能性函数接口: public Interface Function<T,R>{R apply(T t)}
                消费型函数接口: public interface Consumer<T>{public void accept(T t)}
                供给性函数接口: public interface Supplier<T>{public T get()}
                断言型函数接口: public interface Predicate<T>{public boolean test(T t)}
                
            范例:使用功能型接口

        package cn.mysterious;
    
        import java.util.function.Function;
    
        public class Lang0 {
    
            public static void main(String[] args) {
                Function<Integer,String> obj = String :: valueOf;
                System.out.println(obj.apply(100));
            }
    
        }

               
            实际上在 java.util.function 开发包里面有许多扩展的函数式接口,可以帮助用户简化定义
            
            范例:使用 IntFunction

        package cn.mysterious;
    
        import java.util.function.IntFunction;
        public class Lang0 {
    
            public static void main(String[] args) {
                IntFunction<String> obj = String :: valueOf;
                System.out.println(obj.apply(100));
            }
    
        }

               
            范例:消费型接口,现在学习到的消费处理只有一个方法:打印输出

        package cn.mysterious;
    
        import java.util.function.Consumer;
        import java.util.function.IntFunction;
        public class Lang0 {
    
            public static void main(String[] args) {
                Consumer<String> obj = System.out :: println;
                obj.accept("?????");
            }
    
        }

               
            范例:供给型,字符串转大写或小写(“Hello” .toLowerCase())

        package cn.mysterious;
    
        import java.util.function.Supplier;
    
        public class Lang0 {
    
            public static void main(String[] args) {
                Supplier<String> obj = "Hello" :: toLowerCase;
                System.out.println(obj.get());
    
            }
    
        }

               
            范例:断言型接口( startsWith() 方法,返回boolean,接收一个字符串)

        package cn.mysterious;
    
        import java.util.function.Predicate;
    
        public class Lang0 {
    
            public static void main(String[] args) {
                Predicate<String> obj = "##hello" :: startsWith;
                System.out.println(obj.test("##"));
            }
    
        }

               
                如果不去考虑标准,这些接口完全可以自己来实现,而这四个接口是 java 中进行 Lambda 编程时所采用的标准接口

                
       

  • 相关阅读:
    项目经理手记
    自动填写版权信息
    在批处理中实现等待/延迟/暂停
    使用 PowerDesigner 设计数据库
    如何让PowerDesigner支持自动生成含SQL Server 2000的表和列注释的角本
    管理人员的招聘始末谈
    PowerDesign 6简易介绍
    PowerDesigner11.0使用总结
    用表单字段加亮的方式为用户提供友好的界面
    择才有道——企业招聘方式比较
  • 原文地址:https://www.cnblogs.com/mysterious-killer/p/10123623.html
Copyright © 2011-2022 走看看